Netdev List
 help / color / mirror / Atom feed
* [PATCH net-2.6.24] [NET] Cleanup: DIV_ROUND_UP
From: Ilpo Järvinen @ 2007-08-22 10:48 UTC (permalink / raw)
  To: David Miller; +Cc: Netdev

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2118 bytes --]


Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 net/ipv4/tcp_output.c |    6 +-----
 net/key/af_key.c      |   17 +++++------------
 2 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 10b2e39..bca4ee2 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -646,11 +646,7 @@ static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned
 		skb_shinfo(skb)->gso_size = 0;
 		skb_shinfo(skb)->gso_type = 0;
 	} else {
-		unsigned int factor;
-
-		factor = skb->len + (mss_now - 1);
-		factor /= mss_now;
-		skb_shinfo(skb)->gso_segs = factor;
+		skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss_now);
 		skb_shinfo(skb)->gso_size = mss_now;
 		skb_shinfo(skb)->gso_type = sk->sk_gso_type;
 	}
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 5502df1..17b2a69 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -352,16 +352,14 @@ static int verify_address_len(void *p)
 
 	switch (addr->sa_family) {
 	case AF_INET:
-		len  = sizeof(*sp) + sizeof(*sin) + (sizeof(uint64_t) - 1);
-		len /= sizeof(uint64_t);
+		len = DIV_ROUND_UP(sizeof(*sp) + sizeof(*sin), sizeof(uint64_t));
 		if (sp->sadb_address_len != len ||
 		    sp->sadb_address_prefixlen > 32)
 			return -EINVAL;
 		break;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case AF_INET6:
-		len  = sizeof(*sp) + sizeof(*sin6) + (sizeof(uint64_t) - 1);
-		len /= sizeof(uint64_t);
+		len = DIV_ROUND_UP(sizeof(*sp) + sizeof(*sin6), sizeof(uint64_t));
 		if (sp->sadb_address_len != len ||
 		    sp->sadb_address_prefixlen > 128)
 			return -EINVAL;
@@ -386,14 +384,9 @@ static int verify_address_len(void *p)
 
 static inline int pfkey_sec_ctx_len(struct sadb_x_sec_ctx *sec_ctx)
 {
-	int len = 0;
-
-	len += sizeof(struct sadb_x_sec_ctx);
-	len += sec_ctx->sadb_x_ctx_len;
-	len += sizeof(uint64_t) - 1;
-	len /= sizeof(uint64_t);
-
-	return len;
+	return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) +
+			    sec_ctx->sadb_x_ctx_len,
+			    sizeof(uint64_t));
 }
 
 static inline int verify_sec_ctx_len(void *p)
-- 
1.5.0.6

^ permalink raw reply related

* [PATCH -mm] drivers/net/e1000e/netdev.c warning fix
From: Michal Piotrowski @ 2007-08-22 12:51 UTC (permalink / raw)
  To: Andrew Morton, Netdev, Linux NICS, e1000-devel

Hi,

This patch fixes the following compilation warning

drivers/net/e1000e/netdev.c: In function ‘e1000_setup_rctl’:
drivers/net/e1000e/netdev.c:1963: warning: unused variable ‘pages’

Regards,
Michal

-- 
LOG
http://www.stardust.webpages.pl/log/

--- linux-mm-clean/drivers/net/e1000e/netdev.c	2007-08-22 12:20:31.000000000 +0200
+++ linux-work/drivers/net/e1000e/netdev.c	2007-08-22 14:44:58.000000000 +0200
@@ -1960,7 +1960,10 @@ static void e1000_setup_rctl(struct e100
 	struct e1000_hw *hw = &adapter->hw;
 	u32 rctl, rfctl;
 	u32 psrctl = 0;
+
+#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
 	u32 pages = 0;
+#endif
 
 	/* Program MC offset vector base */
 	rctl = er32(RCTL);

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel

^ permalink raw reply

* Re: [PATCH 1/1] net/core: Fix crash in dev_mc_sync()/dev_mc_unsync()
From: Benjamin Thery @ 2007-08-22 13:21 UTC (permalink / raw)
  To: netdev, Patrick McHardy; +Cc: David Miller
In-Reply-To: <20070821163129.377666902@frecb000701.frec.bull.fr>

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

Oops, don't use the previous version of the patch:
the change in dev_mc_unsync() was not correct.
Sorry.

This one is a lot better (it compiles and runs). :)

Benjamin
-- 
B e n j a m i n   T h e r y  - BULL/DT/Open Software R&D

    http://www.bull.com

[-- Attachment #2: Fix-crash-in-dev_mc_sync.patch --]
[-- Type: text/x-patch, Size: 2083 bytes --]

From: benjamin.thery@bull.net
Subject: net/core: Fix crash in dev_mc_sync()/dev_mc_unsync()

This patch fixes a crash that may occur when the routine dev_mc_sync()
deletes an address from the list it is currently going through. It 
saves the pointer to the next element before deleting the current one.
The problem may also exist in dev_mc_unsync().

Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
---
 net/core/dev_mcast.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

Index: linux-2.6.23-rc2/net/core/dev_mcast.c
===================================================================
--- linux-2.6.23-rc2.orig/net/core/dev_mcast.c
+++ linux-2.6.23-rc2/net/core/dev_mcast.c
@@ -116,11 +116,13 @@ int dev_mc_add(struct net_device *dev, v
  */
 int dev_mc_sync(struct net_device *to, struct net_device *from)
 {
-	struct dev_addr_list *da;
+	struct dev_addr_list *da, *next;
 	int err = 0;
 
 	netif_tx_lock_bh(to);
-	for (da = from->mc_list; da != NULL; da = da->next) {
+	da = from->mc_list;
+	while (da != NULL) {
+		next = da->next;
 		if (!da->da_synced) {
 			err = __dev_addr_add(&to->mc_list, &to->mc_count,
 					     da->da_addr, da->da_addrlen, 0);
@@ -134,6 +136,7 @@ int dev_mc_sync(struct net_device *to, s
 			__dev_addr_delete(&from->mc_list, &from->mc_count,
 					  da->da_addr, da->da_addrlen, 0);
 		}
+		da = next;
 	}
 	if (!err)
 		__dev_set_rx_mode(to);
@@ -156,12 +159,14 @@ EXPORT_SYMBOL(dev_mc_sync);
  */
 void dev_mc_unsync(struct net_device *to, struct net_device *from)
 {
-	struct dev_addr_list *da;
+	struct dev_addr_list *da, *next;
 
 	netif_tx_lock_bh(from);
 	netif_tx_lock_bh(to);
 
-	for (da = from->mc_list; da != NULL; da = da->next) {
+	da = from->mc_list;
+	while (da != NULL) {
+		next = da->next;
 		if (!da->da_synced)
 			continue;
 		__dev_addr_delete(&to->mc_list, &to->mc_count,
@@ -169,6 +174,7 @@ void dev_mc_unsync(struct net_device *to
 		da->da_synced = 0;
 		__dev_addr_delete(&from->mc_list, &from->mc_count,
 				  da->da_addr, da->da_addrlen, 0);
+		da = next;
 	}
 	__dev_set_rx_mode(to);
 

^ permalink raw reply

* [PATCH 2.6.23-rc3-mm1] request_irq fix DEBUG_SHIRQ handling Re: 2.6.23-rc2-mm1: rtl8139 inconsistent lock state
From: Jarek Poplawski @ 2007-08-22 13:35 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Mariusz Kozlowski, netdev, Jeff Garzik, David Woodhouse,
	Ingo Molnar, Thomas Gleixner, linux-kernel
In-Reply-To: <200708100149.14446.m.kozlowski@tuxland.pl>

On 10-08-2007 01:49, Mariusz Kozlowski wrote:
> Hello,
> 
> =================================
> [ INFO: inconsistent lock state ]
> 2.6.23-rc2-mm1 #7
> ---------------------------------
> inconsistent {in-hardirq-W} -> {hardirq-on-W} usage.
> ifconfig/5492 [HC0[0]:SC0[0]:HE1:SE1] takes:
>  (&tp->lock){+...}, at: [<de8706e0>] rtl8139_interrupt+0x27/0x46b [8139too]
> {in-hardirq-W} state was registered at:
>   [<c0138eeb>] __lock_acquire+0x949/0x11ac
>   [<c01397e7>] lock_acquire+0x99/0xb2
>   [<c0452ff3>] _spin_lock+0x35/0x42
>   [<de8706e0>] rtl8139_interrupt+0x27/0x46b [8139too]
>   [<c0147a5d>] handle_IRQ_event+0x28/0x59
>   [<c01493ca>] handle_level_irq+0xad/0x10b
>   [<c0105a13>] do_IRQ+0x93/0xd0
>   [<c010441e>] common_interrupt+0x2e/0x34
...
> other info that might help us debug this:
> 1 lock held by ifconfig/5492:
>  #0:  (rtnl_mutex){--..}, at: [<c0451778>] mutex_lock+0x1c/0x1f
> 
> stack backtrace:
...
>  [<c0452ff3>] _spin_lock+0x35/0x42
>  [<de8706e0>] rtl8139_interrupt+0x27/0x46b [8139too]
>  [<c01480fd>] free_irq+0x11b/0x146
>  [<de871d59>] rtl8139_close+0x8a/0x14a [8139too]
>  [<c03bde63>] dev_close+0x57/0x74
...

It looks like this was possible after David's fix, which really
enabled running of the handler in free_irq, but before Andrew's patch
disabling local irqs for this time.

So, this bug should be fixed, but IMHO similar problem is possible in
request_irq. And, I think, this is not only about lockdep complaining,
but real lockup possibility, because any locks in such a handler are
taken in another, not expected for them context, and could be
vulnerable (especially with softirqs, but probably hardirqs as well).

Reported-by: Mariusz Kozlowski <m.kozlowski@tuxland.pl>
Signed-off-by: Jarek Poplawski <jarkao2@o2.pl>

---

diff -Nurp 2.6.23-rc3-mm1-/kernel/irq/manage.c 2.6.23-rc3-mm1/kernel/irq/manage.c
--- 2.6.23-rc3-mm1-/kernel/irq/manage.c	2007-08-22 13:58:58.000000000 +0200
+++ 2.6.23-rc3-mm1/kernel/irq/manage.c	2007-08-22 14:12:21.000000000 +0200
@@ -546,14 +546,11 @@ int request_irq(unsigned int irq, irq_ha
 		 * We do this before actually registering it, to make sure that
 		 * a 'real' IRQ doesn't run in parallel with our fake
 		 */
-		if (irqflags & IRQF_DISABLED) {
-			unsigned long flags;
+		unsigned long flags;
 
-			local_irq_save(flags);
-			handler(irq, dev_id);
-			local_irq_restore(flags);
-		} else
-			handler(irq, dev_id);
+		local_irq_save(flags);
+		handler(irq, dev_id);
+		local_irq_restore(flags);
 	}
 #endif
 

^ permalink raw reply

* [PATCH] [00/10] pasemi_mac patches for 2.6.24
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev

Hi,

pasemi_mac patches for 2.6.24:

01/10: pasemi_mac: Abstract out register access
02/10: pasemi_mac: Stop using the pci config space accessors for register read/writes
03/10: pasemi_mac: Enable L2 caching of packet headers
04/10: pasemi_mac: Fix memcpy amount for short receives
05/10: pasemi_mac: RX performance tweaks
06/10: pasemi_mac: Batch up TX buffer frees
07/10: pasemi_mac: Enable LLTX
08/10: pasemi_mac: Fix TX ring wrap checking
09/10: pasemi_mac: Fix RX checksum flags
10/10: pasemi_mac: Clean TX ring in poll


Thanks,

Olof

--

^ permalink raw reply

* [PATCH] [01/10] pasemi_mac: Abstract out register access
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-regaccess --]
[-- Type: text/plain, Size: 13437 bytes --]

Abstract out the PCI config read/write accesses into reg read/write ones,
still calling the pci accessors on the back end.

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


Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -81,6 +81,48 @@ MODULE_PARM_DESC(debug, "PA Semi MAC bit
 
 static struct pasdma_status *dma_status;
 
+static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
+{
+	unsigned int val;
+
+	pci_read_config_dword(mac->iob_pdev, reg, &val);
+	return val;
+}
+
+static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
+			  unsigned int val)
+{
+	pci_write_config_dword(mac->iob_pdev, reg, val);
+}
+
+static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg)
+{
+	unsigned int val;
+
+	pci_read_config_dword(mac->pdev, reg, &val);
+	return val;
+}
+
+static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg,
+			  unsigned int val)
+{
+	pci_write_config_dword(mac->pdev, reg, val);
+}
+
+static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg)
+{
+	unsigned int val;
+
+	pci_read_config_dword(mac->dma_pdev, reg, &val);
+	return val;
+}
+
+static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg,
+			  unsigned int val)
+{
+	pci_write_config_dword(mac->dma_pdev, reg, val);
+}
+
 static int pasemi_get_mac_addr(struct pasemi_mac *mac)
 {
 	struct pci_dev *pdev = mac->pdev;
@@ -166,22 +208,21 @@ static int pasemi_mac_setup_rx_resources
 
 	memset(ring->buffers, 0, RX_RING_SIZE * sizeof(u64));
 
-	pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_BASEL(chan_id),
-			       PAS_DMA_RXCHAN_BASEL_BRBL(ring->dma));
+	write_dma_reg(mac, PAS_DMA_RXCHAN_BASEL(chan_id), PAS_DMA_RXCHAN_BASEL_BRBL(ring->dma));
+
+	write_dma_reg(mac, PAS_DMA_RXCHAN_BASEU(chan_id),
+			   PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) |
+			   PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2));
+
+	write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id),
+			   PAS_DMA_RXCHAN_CFG_HBU(1));
 
-	pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_BASEU(chan_id),
-			       PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) |
-			       PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2));
-
-	pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_CFG(chan_id),
-			       PAS_DMA_RXCHAN_CFG_HBU(1));
-
-	pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_BASEL(mac->dma_if),
-			       PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers)));
-
-	pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_BASEU(mac->dma_if),
-			       PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) |
-			       PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
+	write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if),
+			   PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers)));
+
+	write_dma_reg(mac, PAS_DMA_RXINT_BASEU(mac->dma_if),
+			   PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) |
+			   PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
 
 	ring->next_to_fill = 0;
 	ring->next_to_clean = 0;
@@ -233,18 +274,18 @@ static int pasemi_mac_setup_tx_resources
 
 	memset(ring->desc, 0, TX_RING_SIZE * sizeof(struct pas_dma_xct_descr));
 
-	pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_BASEL(chan_id),
-			       PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
+	write_dma_reg(mac, PAS_DMA_TXCHAN_BASEL(chan_id),
+			   PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
 	val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
 	val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
 
-	pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_BASEU(chan_id), val);
+	write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val);
 
-	pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_CFG(chan_id),
-			       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));
+	write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id),
+			   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));
 
 	ring->next_to_use = 0;
 	ring->next_to_clean = 0;
@@ -383,12 +424,8 @@ static void pasemi_mac_replenish_rx_ring
 
 	wmb();
 
-	pci_write_config_dword(mac->dma_pdev,
-			       PAS_DMA_RXCHAN_INCR(mac->dma_rxch),
-			       limit - count);
-	pci_write_config_dword(mac->dma_pdev,
-			       PAS_DMA_RXINT_INCR(mac->dma_if),
-			       limit - count);
+	write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), limit - count);
+	write_dma_reg(mac, PAS_DMA_RXINT_INCR(mac->dma_if), limit - count);
 
 	mac->rx->next_to_fill += limit - count;
 }
@@ -404,9 +441,7 @@ static void pasemi_mac_restart_rx_intr(s
 
 	reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC;
 
-	pci_write_config_dword(mac->iob_pdev,
-			       PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch),
-			       reg);
+	write_iob_reg(mac, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
 }
 
 static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
@@ -418,8 +453,7 @@ static void pasemi_mac_restart_tx_intr(s
 
 	reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC;
 
-	pci_write_config_dword(mac->iob_pdev,
-			       PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
+	write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
 }
 
 
@@ -574,8 +608,6 @@ static irqreturn_t pasemi_mac_rx_intr(in
 	 * all others.
 	 */
 
-	pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), &reg);
-
 	reg = 0;
 	if (*mac->rx_status & PAS_STATUS_SOFT)
 		reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
@@ -586,9 +618,7 @@ static irqreturn_t pasemi_mac_rx_intr(in
 
 	netif_rx_schedule(dev);
 
-	pci_write_config_dword(mac->iob_pdev,
-			       PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
-
+	write_iob_reg(mac, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
 
 	return IRQ_HANDLED;
 }
@@ -613,9 +643,7 @@ static irqreturn_t pasemi_mac_tx_intr(in
 	if (*mac->tx_status & PAS_STATUS_ERROR)
 		reg |= PAS_IOB_DMA_TXCH_RESET_DINTC;
 
-	pci_write_config_dword(mac->iob_pdev,
-			       PAS_IOB_DMA_TXCH_RESET(mac->dma_txch),
-			       reg);
+	write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
 
 	return IRQ_HANDLED;
 }
@@ -641,7 +669,7 @@ static void pasemi_adjust_link(struct ne
 	} else
 		netif_carrier_on(dev);
 
-	pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags);
+	flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
 	new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M |
 			      PAS_MAC_CFG_PCFG_TSR_M);
 
@@ -673,7 +701,7 @@ static void pasemi_adjust_link(struct ne
 	mac->link = mac->phydev->link;
 
 	if (new_flags != flags)
-		pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, new_flags);
+		write_mac_reg(mac, PAS_MAC_CFG_PCFG, new_flags);
 
 	if (msg && netif_msg_link(mac))
 		printk(KERN_INFO "%s: Link is up at %d Mbps, %s duplex.\n",
@@ -736,39 +764,37 @@ static int pasemi_mac_open(struct net_de
 	int ret;
 
 	/* enable rx section */
-	pci_write_config_dword(mac->dma_pdev, PAS_DMA_COM_RXCMD,
-			       PAS_DMA_COM_RXCMD_EN);
+	write_dma_reg(mac, PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);
 
 	/* enable tx section */
-	pci_write_config_dword(mac->dma_pdev, PAS_DMA_COM_TXCMD,
-			       PAS_DMA_COM_TXCMD_EN);
+	write_dma_reg(mac, 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);
 
-	pci_write_config_dword(mac->pdev, PAS_MAC_CFG_TXP, flags);
+	write_mac_reg(mac, PAS_MAC_CFG_TXP, flags);
 
 	flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE |
 		PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE;
 
 	flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
 
-	pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
-			       PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
+	write_iob_reg(mac, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
+			   PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
 
-	pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
-			       PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
+	write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
+			   PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
 
 	/* Clear out any residual packet count state from firmware */
 	pasemi_mac_restart_rx_intr(mac);
 	pasemi_mac_restart_tx_intr(mac);
 
 	/* 0xffffff is max value, about 16ms */
-	pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
-			       PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff));
+	write_iob_reg(mac, PAS_IOB_DMA_COM_TIMEOUTCFG,
+			   PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff));
 
-	pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags);
+	write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
 
 	ret = pasemi_mac_setup_rx_resources(dev);
 	if (ret)
@@ -778,25 +804,22 @@ static int pasemi_mac_open(struct net_de
 	if (ret)
 		goto out_tx_resources;
 
-	pci_write_config_dword(mac->pdev, PAS_MAC_IPC_CHNL,
-			       PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) |
-			       PAS_MAC_IPC_CHNL_BCH(mac->dma_rxch));
+	write_mac_reg(mac, PAS_MAC_IPC_CHNL,
+			   PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) |
+			   PAS_MAC_IPC_CHNL_BCH(mac->dma_rxch));
 
 	/* enable rx if */
-	pci_write_config_dword(mac->dma_pdev,
-			       PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
-			       PAS_DMA_RXINT_RCMDSTA_EN);
+	write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
+			   PAS_DMA_RXINT_RCMDSTA_EN);
 
 	/* enable rx channel */
-	pci_write_config_dword(mac->dma_pdev,
-			       PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
-			       PAS_DMA_RXCHAN_CCMDSTA_EN |
-			       PAS_DMA_RXCHAN_CCMDSTA_DU);
+	write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
+			   PAS_DMA_RXCHAN_CCMDSTA_EN |
+			   PAS_DMA_RXCHAN_CCMDSTA_DU);
 
 	/* enable tx channel */
-	pci_write_config_dword(mac->dma_pdev,
-			       PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
-			       PAS_DMA_TXCHAN_TCMDSTA_EN);
+	write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
+			   PAS_DMA_TXCHAN_TCMDSTA_EN);
 
 	pasemi_mac_replenish_rx_ring(dev);
 
@@ -875,20 +898,12 @@ static int pasemi_mac_close(struct net_d
 	pasemi_mac_clean_rx(mac, RX_RING_SIZE);
 
 	/* Disable interface */
-	pci_write_config_dword(mac->dma_pdev,
-			       PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
-			       PAS_DMA_TXCHAN_TCMDSTA_ST);
-	pci_write_config_dword(mac->dma_pdev,
-		      PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
-		      PAS_DMA_RXINT_RCMDSTA_ST);
-	pci_write_config_dword(mac->dma_pdev,
-		      PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
-		      PAS_DMA_RXCHAN_CCMDSTA_ST);
+	write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), PAS_DMA_TXCHAN_TCMDSTA_ST);
+	write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), PAS_DMA_RXINT_RCMDSTA_ST);
+	write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), PAS_DMA_RXCHAN_CCMDSTA_ST);
 
 	for (retries = 0; retries < MAX_RETRIES; retries++) {
-		pci_read_config_dword(mac->dma_pdev,
-				      PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
-				      &stat);
+		stat = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch));
 		if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
 			break;
 		cond_resched();
@@ -898,9 +913,7 @@ static int pasemi_mac_close(struct net_d
 		dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n");
 
 	for (retries = 0; retries < MAX_RETRIES; retries++) {
-		pci_read_config_dword(mac->dma_pdev,
-				      PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
-				      &stat);
+		stat = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch));
 		if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT))
 			break;
 		cond_resched();
@@ -910,9 +923,7 @@ static int pasemi_mac_close(struct net_d
 		dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n");
 
 	for (retries = 0; retries < MAX_RETRIES; retries++) {
-		pci_read_config_dword(mac->dma_pdev,
-				      PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
-				      &stat);
+		stat = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
 		if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT))
 			break;
 		cond_resched();
@@ -925,12 +936,9 @@ static int pasemi_mac_close(struct net_d
 	 * stopping, since you can't disable when active.
 	 */
 
-	pci_write_config_dword(mac->dma_pdev,
-			       PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), 0);
-	pci_write_config_dword(mac->dma_pdev,
-			       PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0);
-	pci_write_config_dword(mac->dma_pdev,
-			       PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
+	write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), 0);
+	write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0);
+	write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
 
 	free_irq(mac->tx_irq, dev);
 	free_irq(mac->rx_irq, dev);
@@ -1011,8 +1019,7 @@ static int pasemi_mac_start_tx(struct sk
 
 	spin_unlock_irqrestore(&txring->lock, flags);
 
-	pci_write_config_dword(mac->dma_pdev,
-			       PAS_DMA_TXCHAN_INCR(mac->dma_txch), 1);
+	write_dma_reg(mac, PAS_DMA_TXCHAN_INCR(mac->dma_txch), 1);
 
 	return NETDEV_TX_OK;
 
@@ -1035,7 +1042,7 @@ static void pasemi_mac_set_rx_mode(struc
 	struct pasemi_mac *mac = netdev_priv(dev);
 	unsigned int flags;
 
-	pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags);
+	flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
 
 	/* Set promiscuous */
 	if (dev->flags & IFF_PROMISC)
@@ -1043,7 +1050,7 @@ static void pasemi_mac_set_rx_mode(struc
 	else
 		flags &= ~PAS_MAC_CFG_PCFG_PR;
 
-	pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags);
+	write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
 }
 
 

--

^ permalink raw reply

* [PATCH] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-kill-pci-config-access --]
[-- Type: text/plain, Size: 6906 bytes --]

Move away from using the pci config access functions for simple register
access.  Our device has all of the registers in the config space (hey,
from the hardware point of view it looks reasonable :-), so we need to
somehow get to it. Newer firmwares have it in the device tree such that
we can just get it and ioremap it there (in case it ever moves in future
products). For now, provide a hardcoded fallback for older firmwares.


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


Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -81,46 +81,47 @@ MODULE_PARM_DESC(debug, "PA Semi MAC bit
 
 static struct pasdma_status *dma_status;
 
-static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
+static inline unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
 {
 	unsigned int val;
 
-	pci_read_config_dword(mac->iob_pdev, reg, &val);
+	val = in_le32(mac->iob_regs+reg);
+
 	return val;
 }
 
-static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
+static inline void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
 			  unsigned int val)
 {
-	pci_write_config_dword(mac->iob_pdev, reg, val);
+	out_le32(mac->iob_regs+reg, val);
 }
 
-static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg)
+static inline unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg)
 {
 	unsigned int val;
 
-	pci_read_config_dword(mac->pdev, reg, &val);
+	val = in_le32(mac->regs+reg);
 	return val;
 }
 
-static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg,
+static inline void write_mac_reg(struct pasemi_mac *mac, unsigned int reg,
 			  unsigned int val)
 {
-	pci_write_config_dword(mac->pdev, reg, val);
+	out_le32(mac->regs+reg, val);
 }
 
-static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg)
+static inline unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg)
 {
 	unsigned int val;
 
-	pci_read_config_dword(mac->dma_pdev, reg, &val);
+	val = in_le32(mac->dma_regs+reg);
 	return val;
 }
 
-static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg,
+static inline void write_dma_reg(struct pasemi_mac *mac, unsigned int reg,
 			  unsigned int val)
 {
-	pci_write_config_dword(mac->dma_pdev, reg, val);
+	out_le32(mac->dma_regs+reg, val);
 }
 
 static int pasemi_get_mac_addr(struct pasemi_mac *mac)
@@ -585,7 +586,6 @@ static int pasemi_mac_clean_tx(struct pa
 	}
 	mac->tx->next_to_clean += count;
 	spin_unlock_irqrestore(&mac->tx->lock, flags);
-
 	netif_wake_queue(mac->netdev);
 
 	return count;
@@ -1076,6 +1076,73 @@ static int pasemi_mac_poll(struct net_de
 	}
 }
 
+static inline void __iomem * __devinit map_onedev(struct pci_dev *p, int index)
+{
+	struct device_node *dn;
+	void __iomem *ret;
+
+	dn = pci_device_to_OF_node(p);
+	if (!dn)
+		goto fallback;
+
+	ret = of_iomap(dn, index);
+	if (!ret)
+		goto fallback;
+
+	return ret;
+fallback:
+	/* This is hardcoded and ugly, but we have some firmware versions
+	 * who don't provide the register space in the device tree. Luckily
+	 * they are at well-known locations so we can just do the math here.
+	 */
+	return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
+}
+
+static int __devinit pasemi_mac_map_regs(struct pasemi_mac *mac)
+{
+	struct resource res;
+	struct device_node *dn;
+	int err;
+
+	mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
+	if (!mac->dma_pdev) {
+		dev_err(&mac->pdev->dev, "Can't find DMA Controller\n");
+		return -ENODEV;
+	}
+
+	mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
+	if (!mac->iob_pdev) {
+		dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n");
+		return -ENODEV;
+	}
+
+	mac->regs = map_onedev(mac->pdev, 0);
+	mac->dma_regs = map_onedev(mac->dma_pdev, 0);
+	mac->iob_regs = map_onedev(mac->iob_pdev, 0);
+
+	if (!mac->regs || !mac->dma_regs || !mac->iob_regs) {
+		dev_err(&mac->pdev->dev, "Can't map registers\n");
+		return -ENODEV;
+	}
+
+	/* The dma status structure is located in the I/O bridge, and
+	 * is cache coherent.
+	 */
+	if (!dma_status) {
+		dn = pci_device_to_OF_node(mac->iob_pdev);
+		if (dn)
+			err = of_address_to_resource(dn, 1, &res);
+		if (!dn || err) {
+			/* Fallback for old firmware */
+			res.start = 0xfd800000;
+			res.end = res.start + 0x1000;
+		}
+		dma_status = __ioremap(res.start, res.end-res.start, 0);
+	}
+
+	return 0;
+}
+
 static int __devinit
 pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -1104,21 +1171,6 @@ pasemi_mac_probe(struct pci_dev *pdev, c
 
 	mac->pdev = pdev;
 	mac->netdev = dev;
-	mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
-
-	if (!mac->dma_pdev) {
-		dev_err(&pdev->dev, "Can't find DMA Controller\n");
-		err = -ENODEV;
-		goto out_free_netdev;
-	}
-
-	mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
-
-	if (!mac->iob_pdev) {
-		dev_err(&pdev->dev, "Can't find I/O Bridge\n");
-		err = -ENODEV;
-		goto out_put_dma_pdev;
-	}
 
 	/* These should come out of the device tree eventually */
 	mac->dma_txch = index;
@@ -1161,12 +1213,9 @@ pasemi_mac_probe(struct pci_dev *pdev, c
 	dev->poll = pasemi_mac_poll;
 	dev->features = NETIF_F_HW_CSUM;
 
-	/* The dma status structure is located in the I/O bridge, and
-	 * is cache coherent.
-	 */
-	if (!dma_status)
-		/* XXXOJN This should come from the device tree */
-		dma_status = __ioremap(0xfd800000, 0x1000, 0);
+	err = pasemi_mac_map_regs(mac);
+	if (err)
+		goto out;
 
 	mac->rx_status = &dma_status->rx_sta[mac->dma_rxch];
 	mac->tx_status = &dma_status->tx_sta[mac->dma_txch];
@@ -1193,10 +1242,17 @@ pasemi_mac_probe(struct pci_dev *pdev, c
 	return err;
 
 out:
-	pci_dev_put(mac->iob_pdev);
-out_put_dma_pdev:
-	pci_dev_put(mac->dma_pdev);
-out_free_netdev:
+	if (mac->iob_pdev)
+		pci_dev_put(mac->iob_pdev);
+	if (mac->dma_pdev)
+		pci_dev_put(mac->dma_pdev);
+	if (mac->dma_regs)
+		iounmap(mac->dma_regs);
+	if (mac->iob_regs)
+		iounmap(mac->iob_regs);
+	if (mac->regs)
+		iounmap(mac->regs);
+
 	free_netdev(dev);
 out_disable_device:
 	pci_disable_device(pdev);
@@ -1220,6 +1276,10 @@ static void __devexit pasemi_mac_remove(
 	pci_dev_put(mac->dma_pdev);
 	pci_dev_put(mac->iob_pdev);
 
+	iounmap(mac->regs);
+	iounmap(mac->dma_regs);
+	iounmap(mac->iob_regs);
+
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(netdev);
 }
Index: mainline/drivers/net/pasemi_mac.h
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.h
+++ mainline/drivers/net/pasemi_mac.h
@@ -52,6 +52,9 @@ struct pasemi_mac_rxring {
 
 struct pasemi_mac {
 	struct net_device *netdev;
+	void __iomem *regs;
+	void __iomem *dma_regs;
+	void __iomem *iob_regs;
 	struct pci_dev *pdev;
 	struct pci_dev *dma_pdev;
 	struct pci_dev *iob_pdev;

--

^ permalink raw reply

* [PATCH] [03/10] pasemi_mac: Enable L2 caching of packet headers
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-cache-headers --]
[-- Type: text/plain, Size: 1911 bytes --]

Enable settings to target l2 for the first few cachelines of the packet, since
we'll access them to get to the various headers.


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


Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -216,7 +216,7 @@ static int pasemi_mac_setup_rx_resources
 			   PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2));
 
 	write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id),
-			   PAS_DMA_RXCHAN_CFG_HBU(1));
+			   PAS_DMA_RXCHAN_CFG_HBU(2));
 
 	write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if),
 			   PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers)));
@@ -225,6 +225,9 @@ static int pasemi_mac_setup_rx_resources
 			   PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) |
 			   PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
 
+	write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if),
+			   PAS_DMA_RXINT_CFG_DHL(2));
+
 	ring->next_to_fill = 0;
 	ring->next_to_clean = 0;
 
Index: mainline/drivers/net/pasemi_mac.h
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.h
+++ mainline/drivers/net/pasemi_mac.h
@@ -218,6 +218,14 @@ enum {
 #define    PAS_DMA_RXINT_RCMDSTA_ACT	0x00010000
 #define    PAS_DMA_RXINT_RCMDSTA_DROPS_M	0xfffe0000
 #define    PAS_DMA_RXINT_RCMDSTA_DROPS_S	17
+#define PAS_DMA_RXINT_CFG(i)		(0x204+(i)*_PAS_DMA_RXINT_STRIDE)
+#define    PAS_DMA_RXINT_CFG_DHL_M	0x07000000
+#define    PAS_DMA_RXINT_CFG_DHL_S	24
+#define    PAS_DMA_RXINT_CFG_DHL(x)	(((x) << PAS_DMA_RXINT_CFG_DHL_S) & \
+					 PAS_DMA_RXINT_CFG_DHL_M)
+#define    PAS_DMA_RXINT_CFG_WIF	0x00000002
+#define    PAS_DMA_RXINT_CFG_WIL	0x00000001
+
 #define PAS_DMA_RXINT_INCR(i)		(0x210+(i)*_PAS_DMA_RXINT_STRIDE)
 #define    PAS_DMA_RXINT_INCR_INCR_M	0x0000ffff
 #define    PAS_DMA_RXINT_INCR_INCR_S	0

--

^ permalink raw reply

* [PATCH] [04/10] pasemi_mac: Fix memcpy amount for short receives
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-bugfix --]
[-- Type: text/plain, Size: 676 bytes --]

Fix up memcpy for short receives.

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


Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -516,9 +516,7 @@ static int pasemi_mac_clean_rx(struct pa
 			    netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN);
 			if (new_skb) {
 				skb_reserve(new_skb, NET_IP_ALIGN);
-				memcpy(new_skb->data - NET_IP_ALIGN,
-					skb->data - NET_IP_ALIGN,
-					len + NET_IP_ALIGN);
+				memcpy(new_skb->data, skb->data, len);
 				/* save the skb in buffer_info as good */
 				skb = new_skb;
 			}

--

^ permalink raw reply

* [PATCH] [07/10] pasemi_mac: Enable LLTX
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-enable-lltx --]
[-- Type: text/plain, Size: 636 bytes --]

Enable LLTX on pasemi_mac: we're already doing sufficient locking
in the driver to enable it.


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

Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -1235,7 +1235,7 @@ pasemi_mac_probe(struct pci_dev *pdev, c
 	dev->set_multicast_list = pasemi_mac_set_rx_mode;
 	dev->weight = 64;
 	dev->poll = pasemi_mac_poll;
-	dev->features = NETIF_F_HW_CSUM;
+	dev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX;
 
 	err = pasemi_mac_map_regs(mac);
 	if (err)

--

^ permalink raw reply

* [PATCH] AH4: Update IPv4 options handling to conform to RFC 4302.
From: Nick Bowler @ 2007-08-22 14:22 UTC (permalink / raw)
  To: davem; +Cc: netdev

I was asked to resend my message here, so here it is.
Please CC me on replies.
---
In testing our ESP/AH offload hardware, I discovered an issue with how AH
handles mutable fields in IPv4.  RFC 4302 (AH) states the following on the
subject:

        For IPv4, the entire option is viewed as a unit; so even
        though the type and length fields within most options are immutable
        in transit, if an option is classified as mutable, the entire option
        is zeroed for ICV computation purposes.

The current implementation does not zero the type and length fields, resulting
in authentication failures when communicating with hosts that do (i.e. FreeBSD).

I have tested record route and timestamp options (ping -R and ping -T) on a
small network involving Windows XP, FreeBSD 6.2, and Linux hosts, with one
router.  In the presence of these options, the FreeBSD and Linux hosts (with
the patch or with the hardware) can communicate.  The Windows XP host simply
fails to accept these packets with or without the patch.

I have also been trying to test source routing options (using traceroute -g),
but haven't had much luck getting this option to work *without* AH, let alone
with.

Signed-off-by: Nick Bowler <nbowler@ellipticsemi.com>
---
 net/ipv4/ah4.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 7a23e59..39f6211 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -46,7 +46,7 @@ static int ip_clear_mutable_options(struct iphdr *iph, __be32 *daddr)
 			memcpy(daddr, optptr+optlen-4, 4);
 			/* Fall through */
 		default:
-			memset(optptr+2, 0, optlen-2);
+			memset(optptr, 0, optlen);
 		}
 		l -= optlen;
 		optptr += optlen;
-- 
1.5.2.2

-- 
Nick Bowler, Elliptic Semiconductor (http://www.ellipticsemi.com/)


^ permalink raw reply related

* [ofa-general] Re: [PATCH 10/10 Rev4] [E1000] Implement batching
From: Kok, Auke @ 2007-08-22 14:39 UTC (permalink / raw)
  To: Krishna Kumar
  Cc: johnpol, jagana, peter.p.waskiewicz.jr, herbert, gaagaan,
	Robert.Olsson, kumarkr, rdreier, hadi, netdev, kaber, jeff,
	general, mchan, tgraf, mcarlson, sri, shemminger, davem
In-Reply-To: <20070822083148.11964.50427.sendpatchset@localhost.localdomain>

Krishna Kumar wrote:
> E1000: Implement batching capability (ported thanks to changes taken from
> 	Jamal). Not all changes are made in this as in IPoIB, eg, handling
> 	out of order skbs (see XXX in the first mail).
> 
> Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
> ---
>  e1000_main.c |  150 +++++++++++++++++++++++++++++++++++++++++++++++------------
>  1 files changed, 121 insertions(+), 29 deletions(-)


Krishna,

while I appreciate the patch I would have preferred a patch to e1000e. Not only 
does the e1000e driver remove a lot of the workarounds for old silicon, it is 
also a good way for us to move the current e1000 driver into a bit more stable 
maintenance mode.

Do you think you can write this patch for e1000e instead? code-wise a lot of 
things are still the same, so your patch should be relatively easy to generate.

e1000e currently lives in a branch from jeff garzik's netdev-2.6 tree

Thanks,

Auke

> 
> diff -ruNp org/drivers/net/e1000/e1000_main.c new/drivers/net/e1000/e1000_main.c
> --- org/drivers/net/e1000/e1000_main.c	2007-08-20 14:26:29.000000000 +0530
> +++ new/drivers/net/e1000/e1000_main.c	2007-08-22 08:33:51.000000000 +0530
> @@ -157,6 +157,7 @@ static void e1000_update_phy_info(unsign
>  static void e1000_watchdog(unsigned long data);
>  static void e1000_82547_tx_fifo_stall(unsigned long data);
>  static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
> +static int e1000_xmit_frames(struct net_device *dev);
>  static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
>  static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
>  static int e1000_set_mac(struct net_device *netdev, void *p);
> @@ -990,7 +991,7 @@ e1000_probe(struct pci_dev *pdev,
>  	if (pci_using_dac)
>  		netdev->features |= NETIF_F_HIGHDMA;
>  
> -	netdev->features |= NETIF_F_LLTX;
> +	netdev->features |= NETIF_F_LLTX | NETIF_F_BATCH_SKBS;
>  
>  	adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
>  
> @@ -3098,6 +3099,18 @@ e1000_tx_map(struct e1000_adapter *adapt
>  	return count;
>  }
>  
> +static void e1000_kick_DMA(struct e1000_adapter *adapter,
> +			   struct e1000_tx_ring *tx_ring, int i)
> +{
> +	wmb();
> +
> +	writel(i, adapter->hw.hw_addr + tx_ring->tdt);
> +	/* we need this if more than one processor can write to our tail
> +	 * at a time, it syncronizes IO on IA64/Altix systems */
> +	mmiowb();
> +}
> +
> +
>  static void
>  e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
>                 int tx_flags, int count)
> @@ -3144,13 +3157,7 @@ e1000_tx_queue(struct e1000_adapter *ada
>  	 * know there are new descriptors to fetch.  (Only
>  	 * applicable for weak-ordered memory model archs,
>  	 * such as IA-64). */
> -	wmb();
> -
>  	tx_ring->next_to_use = i;
> -	writel(i, adapter->hw.hw_addr + tx_ring->tdt);
> -	/* we need this if more than one processor can write to our tail
> -	 * at a time, it syncronizes IO on IA64/Altix systems */
> -	mmiowb();
>  }
>  
>  /**
> @@ -3257,21 +3264,31 @@ static int e1000_maybe_stop_tx(struct ne
>  }
>  
>  #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
> +
> +struct e1000_tx_cbdata {
> +	int count;
> +	unsigned int max_per_txd;
> +	unsigned int nr_frags;
> +	unsigned int mss;
> +};
> +
> +#define E1000_SKB_CB(__skb)	((struct e1000_tx_cbdata *)&((__skb)->cb[0]))
> +#define NETDEV_TX_DROPPED	-5
> +
>  static int
> -e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
> +e1000_prep_queue_frame(struct sk_buff *skb, struct net_device *netdev)
>  {
>  	struct e1000_adapter *adapter = netdev_priv(netdev);
>  	struct e1000_tx_ring *tx_ring;
> -	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
> +	unsigned int max_per_txd = E1000_MAX_DATA_PER_TXD;
>  	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
> -	unsigned int tx_flags = 0;
>  	unsigned int len = skb->len;
> -	unsigned long flags;
> -	unsigned int nr_frags = 0;
> -	unsigned int mss = 0;
> +	unsigned int nr_frags;
> +	unsigned int mss;
>  	int count = 0;
> -	int tso;
>  	unsigned int f;
> +	struct e1000_tx_cbdata *cb = E1000_SKB_CB(skb);
> +
>  	len -= skb->data_len;
>  
>  	/* This goes back to the question of how to logically map a tx queue
> @@ -3282,7 +3299,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
>  
>  	if (unlikely(skb->len <= 0)) {
>  		dev_kfree_skb_any(skb);
> -		return NETDEV_TX_OK;
> +		return NETDEV_TX_DROPPED;
>  	}
>  
>  	/* 82571 and newer doesn't need the workaround that limited descriptor
> @@ -3328,7 +3345,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
>  					DPRINTK(DRV, ERR,
>  						"__pskb_pull_tail failed.\n");
>  					dev_kfree_skb_any(skb);
> -					return NETDEV_TX_OK;
> +					return NETDEV_TX_DROPPED;
>  				}
>  				len = skb->len - skb->data_len;
>  				break;
> @@ -3372,22 +3389,32 @@ e1000_xmit_frame(struct sk_buff *skb, st
>  	    (adapter->hw.mac_type == e1000_82573))
>  		e1000_transfer_dhcp_info(adapter, skb);
>  
> -	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
> -		/* Collision - tell upper layer to requeue */
> -		return NETDEV_TX_LOCKED;
> +	cb->count = count;
> +	cb->max_per_txd = max_per_txd;
> +	cb->nr_frags = nr_frags;
> +	cb->mss = mss;
> +
> +	return NETDEV_TX_OK;
> +}
> +
> +static int e1000_queue_frame(struct sk_buff *skb, struct net_device *netdev)
> +{
> +	struct e1000_adapter *adapter = netdev_priv(netdev);
> +	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
> +	int tso;
> +	unsigned int first;
> +	unsigned int tx_flags = 0;
> +	struct e1000_tx_cbdata *cb = E1000_SKB_CB(skb);
>  
>  	/* need: count + 2 desc gap to keep tail from touching
>  	 * head, otherwise try next time */
> -	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
> -		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
> +	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, cb->count + 2)))
>  		return NETDEV_TX_BUSY;
> -	}
>  
>  	if (unlikely(adapter->hw.mac_type == e1000_82547)) {
>  		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
>  			netif_stop_queue(netdev);
>  			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
> -			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
>  			return NETDEV_TX_BUSY;
>  		}
>  	}
> @@ -3402,8 +3429,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
>  	tso = e1000_tso(adapter, tx_ring, skb);
>  	if (tso < 0) {
>  		dev_kfree_skb_any(skb);
> -		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
> -		return NETDEV_TX_OK;
> +		return NETDEV_TX_DROPPED;
>  	}
>  
>  	if (likely(tso)) {
> @@ -3420,12 +3446,78 @@ e1000_xmit_frame(struct sk_buff *skb, st
>  
>  	e1000_tx_queue(adapter, tx_ring, tx_flags,
>  	               e1000_tx_map(adapter, tx_ring, skb, first,
> -	                            max_per_txd, nr_frags, mss));
> +	                            cb->max_per_txd, cb->nr_frags, cb->mss));
> +
> +	return NETDEV_TX_OK;
> +}
>  
> -	netdev->trans_start = jiffies;
> +static inline int e1000_xmit_frames(struct net_device *netdev)
> +{
> +	struct e1000_adapter *adapter = netdev->priv;
> +	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
> +	int ret = NETDEV_TX_OK;
> +	int skbs_done = 0;
> +	struct sk_buff *skb;
> +	unsigned long flags;
> +
> +	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) {
> +		/* Collision - tell upper layer to requeue */
> +		return NETDEV_TX_LOCKED;
> +	}
>  
> -	/* Make sure there is space in the ring for the next send. */
> -	e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
> +	while ((skb = __skb_dequeue(netdev->skb_blist)) != NULL) {
> +		if ((ret = e1000_prep_queue_frame(skb, netdev)) != NETDEV_TX_OK)
> +			continue;
> +
> +		ret = e1000_queue_frame(skb, netdev);
> +		if (ret == NETDEV_TX_OK) {
> +			skbs_done++;
> +		} else {
> +			if (ret == NETDEV_TX_BUSY)
> +				__skb_queue_head(netdev->skb_blist, skb);
> +			break;
> +		}
> +	}
> +
> +	if (skbs_done) {
> +		e1000_kick_DMA(adapter, tx_ring, adapter->tx_ring->next_to_use);
> +		netdev->trans_start = jiffies;
> +		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
> +	}
> +
> +	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
> +
> +	if (ret == NETDEV_TX_DROPPED)
> +		ret = NETDEV_TX_OK;
> +
> +	return ret;
> +}
> +
> +static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
> +{
> +	struct e1000_adapter *adapter = netdev_priv(netdev);
> +	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
> +	unsigned long flags;
> +
> +	if (!skb)
> +		return e1000_xmit_frames(netdev);
> +
> +	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) {
> +		/* Collision - tell upper layer to requeue */
> +		return NETDEV_TX_LOCKED;
> +	}
> +
> +	if (unlikely(e1000_prep_queue_frame(skb, netdev) != NETDEV_TX_OK)) {
> +		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
> +		return NETDEV_TX_OK;
> +	}
> +
> +	if (e1000_queue_frame(skb, netdev) == NETDEV_TX_OK) {
> +		e1000_kick_DMA(adapter, tx_ring, adapter->tx_ring->next_to_use);
> +		netdev->trans_start = jiffies;
> +		/* Make sure there is space in the ring for the next send. */
> +		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
> +	}
>  
>  	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
>  	return NETDEV_TX_OK;
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH -mm] drivers/net/e1000e/netdev.c warning fix
From: Kok, Auke @ 2007-08-22 14:40 UTC (permalink / raw)
  To: Michal Piotrowski; +Cc: e1000-devel, Netdev, Andrew Morton, Linux NICS
In-Reply-To: <46CC316D.2020906@googlemail.com>

Michal Piotrowski wrote:
> Hi,
> 
> This patch fixes the following compilation warning
> 
> drivers/net/e1000e/netdev.c: In function ‘e1000_setup_rctl’:
> drivers/net/e1000e/netdev.c:1963: warning: unused variable ‘pages’
> 
> Regards,
> Michal
> 

also exposes a symbol issue. I think I want to remove this #ifdef 
CONFIG_E1000_DISABLE_PACKET_SPLIT from this driver alltogether...

Auke

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

^ permalink raw reply

* [PATCH 1/4] ehea: fix interface to DLPAR tools
From: Jan-Bernd Themann @ 2007-08-22 14:20 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: netdev, Christoph Raisch, Jan-Bernd Themann, linux-kernel,
	linux-ppc, Marcus Eder, Thomas Klein, Stefan Roscher

Userspace DLPAR tool expects decimal numbers to be written to
and read from sysfs entries.

Signed-off-by: Jan-Bernd Themann <themann@de.ibm.com>


---
 drivers/net/ehea/ehea_main.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 9756211..22d000f 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2490,7 +2490,7 @@ static ssize_t ehea_show_port_id(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
 	struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev);
-	return sprintf(buf, "0x%X", port->logical_port_id);
+	return sprintf(buf, "%d", port->logical_port_id);
 }
 
 static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id,
@@ -2781,7 +2781,7 @@ static ssize_t ehea_probe_port(struct device *dev,
 
 	u32 logical_port_id;
 
-	sscanf(buf, "%X", &logical_port_id);
+	sscanf(buf, "%d", &logical_port_id);
 
 	port = ehea_get_port(adapter, logical_port_id);
 
@@ -2834,7 +2834,7 @@ static ssize_t ehea_remove_port(struct device *dev,
 	int i;
 	u32 logical_port_id;
 
-	sscanf(buf, "%X", &logical_port_id);
+	sscanf(buf, "%d", &logical_port_id);
 
 	port = ehea_get_port(adapter, logical_port_id);
 
-- 
1.5.2


^ permalink raw reply related

* [PATCH 2/4] ehea: fix module parameter description
From: Jan-Bernd Themann @ 2007-08-22 14:21 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: netdev, Christoph Raisch, Jan-Bernd Themann, linux-kernel,
	linux-ppc, Marcus Eder, Thomas Klein, Stefan Roscher

Update the module parameter description of "use_mcs" to
show correct default value

Signed-off-by: Jan-Bernd Themann <themann@de.ibm.com>

---
 drivers/net/ehea/ehea_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 22d000f..db57474 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -76,7 +76,7 @@ MODULE_PARM_DESC(rq1_entries, "Number of entries for Receive Queue 1 "
 MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue  "
 		 "[2^x - 1], x = [6..14]. Default = "
 		 __MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")");
-MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 ");
+MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 0 ");
 
 static int port_name_cnt = 0;
 static LIST_HEAD(adapter_list);
-- 
1.5.2


^ permalink raw reply related

* [PATCH 3/4] ehea: fix queue destructor
From: Jan-Bernd Themann @ 2007-08-22 14:21 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: netdev, Christoph Raisch, Jan-Bernd Themann, linux-kernel,
	linux-ppc, Marcus Eder, Thomas Klein, Stefan Roscher

Includes hcp_epas_dtor in eq/cq/qp destructors to unmap
HW register.

Signed-off-by: Jan-Bernd Themann <themann@de.ibm.com>

---
 drivers/net/ehea/ehea_qmr.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index a36fa6c..c82e245 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -235,6 +235,8 @@ int ehea_destroy_cq(struct ehea_cq *cq)
 	if (!cq)
 		return 0;
 
+	hcp_epas_dtor(&cq->epas);
+
 	if ((hret = ehea_destroy_cq_res(cq, NORMAL_FREE)) == H_R_STATE) {
 		ehea_error_data(cq->adapter, cq->fw_handle);
 		hret = ehea_destroy_cq_res(cq, FORCE_FREE);
@@ -361,6 +363,8 @@ int ehea_destroy_eq(struct ehea_eq *eq)
 	if (!eq)
 		return 0;
 
+	hcp_epas_dtor(&eq->epas);
+
 	if ((hret = ehea_destroy_eq_res(eq, NORMAL_FREE)) == H_R_STATE) {
 		ehea_error_data(eq->adapter, eq->fw_handle);
 		hret = ehea_destroy_eq_res(eq, FORCE_FREE);
@@ -541,6 +545,8 @@ int ehea_destroy_qp(struct ehea_qp *qp)
 	if (!qp)
 		return 0;
 
+	hcp_epas_dtor(&qp->epas);
+
 	if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) {
 		ehea_error_data(qp->adapter, qp->fw_handle);
 		hret = ehea_destroy_qp_res(qp, FORCE_FREE);
-- 
1.5.2


^ permalink raw reply related

* [PATCH 4/4] ehea: show physical port state
From: Jan-Bernd Themann @ 2007-08-22 14:21 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: netdev, Christoph Raisch, Jan-Bernd Themann, linux-kernel,
	linux-ppc, Marcus Eder, Thomas Klein, Stefan Roscher

Introduces a module parameter to decide whether the physical
port link state is propagated to the network stack or not.
It makes sense not to take the physical port state into account
on machines with more logical partitions that communicate
with each other. This is always possible no matter what the physical
port state is. Thus eHEA can be considered as a switch there.

Signed-off-by: Jan-Bernd Themann <themann@de.ibm.com>

---
 drivers/net/ehea/ehea.h      |    5 ++++-
 drivers/net/ehea/ehea_main.c |   14 +++++++++++++-
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index d67f97b..8d58be5 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0073"
+#define DRV_VERSION	"EHEA_0074"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
@@ -402,6 +402,8 @@ struct ehea_mc_list {
 
 #define EHEA_PORT_UP 1
 #define EHEA_PORT_DOWN 0
+#define EHEA_PHY_LINK_UP 1
+#define EHEA_PHY_LINK_DOWN 0
 #define EHEA_MAX_PORT_RES 16
 struct ehea_port {
 	struct ehea_adapter *adapter;	 /* adapter that owns this port */
@@ -427,6 +429,7 @@ struct ehea_port {
 	u32 msg_enable;
 	u32 sig_comp_iv;
 	u32 state;
+	u8 phy_link;
 	u8 full_duplex;
 	u8 autoneg;
 	u8 num_def_qps;
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index db57474..1804c99 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -53,17 +53,21 @@ static int rq3_entries = EHEA_DEF_ENTRIES_RQ3;
 static int sq_entries = EHEA_DEF_ENTRIES_SQ;
 static int use_mcs = 0;
 static int num_tx_qps = EHEA_NUM_TX_QP;
+static int show_phys_link = 0;
 
 module_param(msg_level, int, 0);
 module_param(rq1_entries, int, 0);
 module_param(rq2_entries, int, 0);
 module_param(rq3_entries, int, 0);
 module_param(sq_entries, int, 0);
+module_param(show_phys_link, int, 0);
 module_param(use_mcs, int, 0);
 module_param(num_tx_qps, int, 0);
 
 MODULE_PARM_DESC(num_tx_qps, "Number of TX-QPS");
 MODULE_PARM_DESC(msg_level, "msg_level");
+MODULE_PARM_DESC(show_phys_link, "Show link state of external port"
+		 "1:yes, 0: no.  Default = 0 ");
 MODULE_PARM_DESC(rq3_entries, "Number of entries for Receive Queue 3 "
 		 "[2^x - 1], x = [6..14]. Default = "
 		 __MODULE_STRING(EHEA_DEF_ENTRIES_RQ3) ")");
@@ -814,7 +818,9 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed)
 			ehea_error("Failed setting port speed");
 		}
 	}
-	netif_carrier_on(port->netdev);
+	if (!show_phys_link || (port->phy_link == EHEA_PHY_LINK_UP))
+		netif_carrier_on(port->netdev);
+
 	kfree(cb4);
 out:
 	return ret;
@@ -869,13 +875,19 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe)
 			}
 
 		if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PORT_UP, eqe)) {
+			port->phy_link = EHEA_PHY_LINK_UP;
 			if (netif_msg_link(port))
 				ehea_info("%s: Physical port up",
 					  port->netdev->name);
+			if (show_phys_link)
+				netif_carrier_on(port->netdev);
 		} else {
+			port->phy_link = EHEA_PHY_LINK_DOWN;
 			if (netif_msg_link(port))
 				ehea_info("%s: Physical port down",
 					  port->netdev->name);
+			if (show_phys_link)
+				netif_carrier_off(port->netdev);
 		}
 
 		if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PRIMARY, eqe))
-- 
1.5.2


^ permalink raw reply related

* [NET] sgiseeq: Fix return type of sgiseeq_remove
From: Ralf Baechle @ 2007-08-22 15:03 UTC (permalink / raw)
  To: Andrew Morton, Jeff Garzik, netdev

The driver remove method needs to return an int not void.  This was just
never noticed because usually this driver is not being built as a module.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 384b468..0fb74cb 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -726,7 +726,7 @@ err_out:
 	return err;
 }
 
-static void __exit sgiseeq_remove(struct platform_device *pdev)
+static int __exit sgiseeq_remove(struct platform_device *pdev)
 {
 	struct net_device *dev = platform_get_drvdata(pdev);
 	struct sgiseeq_private *sp = netdev_priv(dev);
@@ -735,6 +735,8 @@ static void __exit sgiseeq_remove(struct platform_device *pdev)
 	free_page((unsigned long) sp->srings);
 	free_netdev(dev);
 	platform_set_drvdata(pdev, NULL);
+
+	return 0;
 }
 
 static struct platform_driver sgiseeq_driver = {

^ permalink raw reply related

* [PATCH 1/3] e1000e: retire last_tx_tso workaround
From: Auke Kok @ 2007-08-22 15:08 UTC (permalink / raw)
  To: jeff; +Cc: netdev, john.ronciak, akpm

This TSO-related workaround is no longer needed since it's only
applicable for 8254x silicon.

Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 drivers/net/e1000e/e1000.h  |   15 +++------------
 drivers/net/e1000e/netdev.c |   20 ++------------------
 2 files changed, 5 insertions(+), 30 deletions(-)

diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index e3cd877..bbe5faf 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -142,18 +142,9 @@ struct e1000_ring {
 	/* array of buffer information structs */
 	struct e1000_buffer *buffer_info;
 
-	union {
-		/* for TX */
-		struct {
-			bool last_tx_tso; /* used to mark tso desc.  */
-		};
-		/* for RX */
-		struct {
-			/* arrays of page information for packet split */
-			struct e1000_ps_page *ps_pages;
-			struct sk_buff *rx_skb_top;
-		};
-	};
+	/* arrays of page information for packet split */
+	struct e1000_ps_page *ps_pages;
+	struct sk_buff *rx_skb_top;
 
 	struct e1000_queue_stats stats;
 };
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 8ebe238..4916f7c 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -1483,7 +1483,6 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter)
 
 	tx_ring->next_to_use = 0;
 	tx_ring->next_to_clean = 0;
-	tx_ring->last_tx_tso = 0;
 
 	writel(0, adapter->hw.hw_addr + tx_ring->head);
 	writel(0, adapter->hw.hw_addr + tx_ring->tail);
@@ -3216,15 +3215,6 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 	while (len) {
 		buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, max_per_txd);
-		/* Workaround for Controller erratum --
-		 * descriptor for non-tso packet in a linear SKB that follows a
-		 * tso gets written back prematurely before the data is fully
-		 * DMA'd to the controller */
-		if (tx_ring->last_tx_tso && !skb_is_gso(skb)) {
-			tx_ring->last_tx_tso = 0;
-			if (!skb->data_len)
-				size -= 4;
-		}
 
 		/* Workaround for premature desc write-backs
 		 * in TSO mode.  Append 4-byte sentinel desc */
@@ -3497,10 +3487,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		count++;
 	count++;
 
-	/* Controller Erratum workaround */
-	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
-		count++;
-
 	count += TXD_USE_COUNT(len, max_txd_pwr);
 
 	nr_frags = skb_shinfo(skb)->nr_frags;
@@ -3536,12 +3522,10 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		return NETDEV_TX_OK;
 	}
 
-	if (tso) {
-		tx_ring->last_tx_tso = 1;
+	if (tso)
 		tx_flags |= E1000_TX_FLAGS_TSO;
-	} else if (e1000_tx_csum(adapter, skb)) {
+	else if (e1000_tx_csum(adapter, skb))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
-	}
 
 	/* Old method was to assume IPv4 packet by default if TSO was enabled.
 	 * 82571 hardware supports TSO capabilities for IPv6 as well...

^ permalink raw reply related

* [PATCH 2/3] e1000e: Add read code and printout of PBA number (board identifier)
From: Auke Kok @ 2007-08-22 15:08 UTC (permalink / raw)
  To: jeff; +Cc: netdev, john.ronciak, akpm
In-Reply-To: <20070822150839.19918.86665.stgit@localhost.localdomain>

The PBA number allows customers and support to directly identify
the type of board and characteristics such as different skews.

Slightly enhance loading messages by adding module name to printout.

Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 drivers/net/e1000e/defines.h |    6 ++++--
 drivers/net/e1000e/e1000.h   |    2 ++
 drivers/net/e1000e/lib.c     |   21 +++++++++++++++++++++
 drivers/net/e1000e/netdev.c  |   12 +++++++++---
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index ca80fde..b32ed45 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -573,9 +573,11 @@
 /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
 #define NVM_SUM                    0xBABA
 
-#define NVM_WORD_SIZE_BASE_SHIFT   6
+/* PBA (printed board assembly) number words */
+#define NVM_PBA_OFFSET_0           8
+#define NVM_PBA_OFFSET_1           9
 
-/* NVM Commands - Microwire */
+#define NVM_WORD_SIZE_BASE_SHIFT   6
 
 /* NVM Commands - SPI */
 #define NVM_MAX_RETRY_SPI          5000 /* Max wait of 5ms, for RDY signal */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index bbe5faf..c57e35a 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -358,6 +358,8 @@ extern struct e1000_info e1000_ich8_info;
 extern struct e1000_info e1000_ich9_info;
 extern struct e1000_info e1000_es2_info;
 
+extern s32 e1000e_read_part_num(struct e1000_hw *hw, u32 *part_num);
+
 extern s32  e1000e_commit_phy(struct e1000_hw *hw);
 
 extern bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw);
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 6645c21..3bbfe60 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -2464,3 +2464,24 @@ bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
 	return ret_val;
 }
 
+s32 e1000e_read_part_num(struct e1000_hw *hw, u32 *part_num)
+{
+	s32 ret_val;
+	u16 nvm_data;
+
+	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
+	if (ret_val) {
+		hw_dbg(hw, "NVM Read Error\n");
+		return ret_val;
+	}
+	*part_num = (u32)(nvm_data << 16);
+
+	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
+	if (ret_val) {
+		hw_dbg(hw, "NVM Read Error\n");
+		return ret_val;
+	}
+	*part_num |= nvm_data;
+
+	return 0;
+}
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 4916f7c..420e111 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -3966,6 +3966,7 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
+	u32 part_num;
 
 	/* print bus type/speed/width info */
 	ndev_info(netdev, "(PCI Express:2.5GB/s:%s) "
@@ -3980,6 +3981,10 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
 	ndev_info(netdev, "Intel(R) PRO/%s Network Connection\n",
 		  (hw->phy.type == e1000_phy_ife)
 		   ? "10/100" : "1000");
+	e1000e_read_part_num(hw, &part_num);
+	ndev_info(netdev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
+		  hw->mac.type, hw->phy.type,
+		  (part_num >> 8), (part_num & 0xff));
 }
 
 /**
@@ -4414,9 +4419,10 @@ static struct pci_driver e1000_driver = {
 static int __init e1000_init_module(void)
 {
 	int ret;
-	printk(KERN_INFO "Intel(R) PRO/1000 Network Driver - %s\n",
-	       e1000e_driver_version);
-	printk(KERN_INFO "Copyright (c) 1999-2007 Intel Corporation.\n");
+	printk(KERN_INFO "%s: Intel(R) PRO/1000 Network Driver - %s\n",
+	       e1000e_driver_name, e1000e_driver_version);
+	printk(KERN_INFO "%s: Copyright (c) 1999-2007 Intel Corporation.\n",
+	       e1000e_driver_name);
 	ret = pci_register_driver(&e1000_driver);
 
 	return ret;

^ permalink raw reply related

* [PATCH 3/3] e1000e: Remove conditional packet split disable flag
From: Auke Kok @ 2007-08-22 15:08 UTC (permalink / raw)
  To: jeff; +Cc: netdev, john.ronciak, akpm
In-Reply-To: <20070822150839.19918.86665.stgit@localhost.localdomain>

This flag conflicts with e1000's Kconfig symbol and we'll leave
the feature enabled by default for now.

Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---

 drivers/net/e1000e/netdev.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 420e111..372da46 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2009,7 +2009,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 		break;
 	}
 
-#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
 	/*
 	 * 82571 and greater support packet-split where the protocol
 	 * header is placed in skb->data and the packet data is
@@ -2029,7 +2028,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
 	if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
 		adapter->rx_ps_pages = pages;
-#endif
+
 	if (adapter->rx_ps_pages) {
 		/* Configure extra packet-split registers */
 		rfctl = er32(RFCTL);

^ permalink raw reply related

* [PATCH] [05/10] pasemi_mac: RX performance tweaks
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-rxperf --]
[-- Type: text/plain, Size: 2464 bytes --]

Various RX performance tweaks, do some explicit prefetching of packet
data, etc.

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

Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -481,6 +481,7 @@ static int pasemi_mac_clean_rx(struct pa
 		rmb();
 
 		dp = &RX_DESC(mac, n);
+		prefetchw(dp);
 		macrx = dp->macrx;
 
 		if (!(macrx & XCT_MACRX_O))
@@ -502,8 +503,10 @@ static int pasemi_mac_clean_rx(struct pa
 			if (info->dma == dma)
 				break;
 		}
+		prefetchw(info);
 
 		skb = info->skb;
+		prefetchw(skb);
 		info->dma = 0;
 
 		pci_unmap_single(mac->dma_pdev, dma, skb->len,
@@ -526,9 +529,7 @@ static int pasemi_mac_clean_rx(struct pa
 
 		skb_put(skb, len);
 
-		skb->protocol = eth_type_trans(skb, mac->netdev);
-
-		if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
+		if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
 			skb->ip_summed = CHECKSUM_COMPLETE;
 			skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
 					   XCT_MACRX_CSUM_S;
@@ -538,6 +539,7 @@ static int pasemi_mac_clean_rx(struct pa
 		mac->stats.rx_bytes += len;
 		mac->stats.rx_packets++;
 
+		skb->protocol = eth_type_trans(skb, mac->netdev);
 		netif_receive_skb(skb);
 
 		dp->ptr = 0;
@@ -569,7 +571,7 @@ static int pasemi_mac_clean_tx(struct pa
 
 	for (i = start; i < mac->tx->next_to_use; i++) {
 		dp = &TX_DESC(mac, i);
-		if (!dp || (dp->mactx & XCT_MACTX_O))
+		if (unlikely(dp->mactx & XCT_MACTX_O))
 			break;
 
 		count++;
@@ -957,7 +959,7 @@ static int pasemi_mac_start_tx(struct sk
 	struct pasemi_mac_txring *txring;
 	struct pasemi_mac_buffer *info;
 	struct pas_dma_xct_descr *dp;
-	u64 dflags;
+	u64 dflags, mactx, ptr;
 	dma_addr_t map;
 	int flags;
 
@@ -985,6 +987,9 @@ static int pasemi_mac_start_tx(struct sk
 	if (dma_mapping_error(map))
 		return NETDEV_TX_BUSY;
 
+	mactx = dflags | XCT_MACTX_LLEN(skb->len);
+	ptr   = XCT_PTR_LEN(skb->len) | XCT_PTR_ADDR(map);
+
 	txring = mac->tx;
 
 	spin_lock_irqsave(&txring->lock, flags);
@@ -1005,12 +1010,11 @@ static int pasemi_mac_start_tx(struct sk
 		}
 	}
 
-
 	dp = &TX_DESC(mac, txring->next_to_use);
 	info = &TX_DESC_INFO(mac, txring->next_to_use);
 
-	dp->mactx = dflags | XCT_MACTX_LLEN(skb->len);
-	dp->ptr   = XCT_PTR_LEN(skb->len) | XCT_PTR_ADDR(map);
+	dp->mactx = mactx;
+	dp->ptr   = ptr;
 	info->dma = map;
 	info->skb = skb;
 

--

^ permalink raw reply

* [PATCH] [08/10] pasemi_mac: Fix TX ring wrap checking
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-ringwrap-bugfix --]
[-- Type: text/plain, Size: 3771 bytes --]

The old logic didn't detect full (tx) ring cases properly, causing
overruns and general badness. Clean it up a bit and abstract out the
ring size checks, always making sure to leave 1 slot open.


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

Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -69,6 +69,10 @@
 #define RX_DESC_INFO(mac, num)	((mac)->rx->desc_info[(num) & (RX_RING_SIZE-1)])
 #define RX_BUFF(mac, num)	((mac)->rx->buffers[(num) & (RX_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))
+
 #define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
 
 MODULE_LICENSE("GPL");
@@ -184,6 +188,7 @@ static int pasemi_mac_setup_rx_resources
 
 	spin_lock_init(&ring->lock);
 
+	ring->size = RX_RING_SIZE;
 	ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
 				  RX_RING_SIZE, GFP_KERNEL);
 
@@ -263,6 +268,7 @@ static int pasemi_mac_setup_tx_resources
 
 	spin_lock_init(&ring->lock);
 
+	ring->size = TX_RING_SIZE;
 	ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
 				  TX_RING_SIZE, GFP_KERNEL);
 	if (!ring->desc_info)
@@ -291,7 +297,7 @@ static int pasemi_mac_setup_tx_resources
 			   PAS_DMA_TXCHAN_CFG_UP |
 			   PAS_DMA_TXCHAN_CFG_WT(2));
 
-	ring->next_to_use = 0;
+	ring->next_to_fill = 0;
 	ring->next_to_clean = 0;
 
 	snprintf(ring->irq_name, sizeof(ring->irq_name),
@@ -386,9 +392,7 @@ static void pasemi_mac_replenish_rx_ring
 	int start = mac->rx->next_to_fill;
 	unsigned int limit, count;
 
-	limit = (mac->rx->next_to_clean + RX_RING_SIZE -
-		 mac->rx->next_to_fill) & (RX_RING_SIZE - 1);
-
+	limit = RING_AVAIL(mac->rx);
 	/* Check to see if we're doing first-time setup */
 	if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
 		limit = RX_RING_SIZE;
@@ -572,7 +576,7 @@ restart:
 	spin_lock_irqsave(&mac->tx->lock, flags);
 
 	start = mac->tx->next_to_clean;
-	limit = min(mac->tx->next_to_use, start+32);
+	limit = min(mac->tx->next_to_fill, start+32);
 
 	count = 0;
 
@@ -1013,14 +1017,13 @@ static int pasemi_mac_start_tx(struct sk
 
 	spin_lock_irqsave(&txring->lock, flags);
 
-	if (txring->next_to_clean - txring->next_to_use == TX_RING_SIZE) {
+	if (RING_AVAIL(txring) <= 1) {
 		spin_unlock_irqrestore(&txring->lock, flags);
 		pasemi_mac_clean_tx(mac);
 		pasemi_mac_restart_tx_intr(mac);
 		spin_lock_irqsave(&txring->lock, flags);
 
-		if (txring->next_to_clean - txring->next_to_use ==
-		    TX_RING_SIZE) {
+		if (RING_AVAIL(txring) <= 1) {
 			/* Still no room -- stop the queue and wait for tx
 			 * intr when there's room.
 			 */
@@ -1029,15 +1032,15 @@ static int pasemi_mac_start_tx(struct sk
 		}
 	}
 
-	dp = &TX_DESC(mac, txring->next_to_use);
-	info = &TX_DESC_INFO(mac, txring->next_to_use);
+	dp = &TX_DESC(mac, txring->next_to_fill);
+	info = &TX_DESC_INFO(mac, txring->next_to_fill);
 
 	dp->mactx = mactx;
 	dp->ptr   = ptr;
 	info->dma = map;
 	info->skb = skb;
 
-	txring->next_to_use++;
+	txring->next_to_fill++;
 	mac->stats.tx_packets++;
 	mac->stats.tx_bytes += skb->len;
 
Index: mainline/drivers/net/pasemi_mac.h
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.h
+++ mainline/drivers/net/pasemi_mac.h
@@ -31,7 +31,7 @@ struct pasemi_mac_txring {
 	struct pas_dma_xct_descr	*desc;
 	dma_addr_t	 dma;
 	unsigned int	 size;
-	unsigned int	 next_to_use;
+	unsigned int	 next_to_fill;
 	unsigned int	 next_to_clean;
 	struct pasemi_mac_buffer *desc_info;
 	char		 irq_name[10];  /* "eth%d tx" */

--

^ permalink raw reply

* [PATCH] [10/10] pasemi_mac: Clean TX ring in poll
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-clean-tx-in-poll --]
[-- Type: text/plain, Size: 1130 bytes --]

Unfortunately there's no timeout for how long a packet can sit on
the TX ring after completion before an interrupt is generated, and
we want to have a threshold that's larger than one packet per interrupt.

So we have to have a timer that occasionally cleans the TX ring even
though there hasn't been an interrupt. Instead of setting up a dedicated
timer for this, just clean it in the NAPI poll routine instead.


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

---

I know I got this rejected last time it was submitted, but no answers with
suggestions on how to handle it better. I'm all ears if there's a better
way.  (I noticed that Intel's new ixgbe driver does the same thing).

Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -1086,6 +1086,7 @@ static int pasemi_mac_poll(struct net_de
 	int pkts, limit = min(*budget, dev->quota);
 	struct pasemi_mac *mac = netdev_priv(dev);
 
+	pasemi_mac_clean_tx(mac);
 	pkts = pasemi_mac_clean_rx(mac, limit);
 
 	dev->quota -= pkts;

--

^ permalink raw reply

* [PATCH] [09/10] pasemi_mac: Fix RX checksum flags
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-rx-checksum-fix --]
[-- Type: text/plain, Size: 631 bytes --]

RX side flag to use is CHECKSUM_UNNECESSARY, not CHECKSUM_COMPLETE.

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

Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -534,7 +534,7 @@ static int pasemi_mac_clean_rx(struct pa
 		skb_put(skb, len);
 
 		if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
-			skb->ip_summed = CHECKSUM_COMPLETE;
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
 					   XCT_MACRX_CSUM_S;
 		} else

--

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox