Netdev List
 help / color / mirror / Atom feed
* [PATCH] staging: octeon-ethernet: remove .get_sg, etc. ethtool_ops
From: Michał Mirosław @ 2011-04-20 14:25 UTC (permalink / raw)
  To: netdev; +Cc: Greg Kroah-Hartman, devel

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/staging/octeon/ethernet-mdio.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 10a82ef..8a11ffc 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -91,8 +91,6 @@ const struct ethtool_ops cvm_oct_ethtool_ops = {
 	.set_settings = cvm_oct_set_settings,
 	.nway_reset = cvm_oct_nway_reset,
 	.get_link = ethtool_op_get_link,
-	.get_sg = ethtool_op_get_sg,
-	.get_tx_csum = ethtool_op_get_tx_csum,
 };
 
 /**
-- 
1.7.2.5


^ permalink raw reply related

* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Eric Dumazet @ 2011-04-20 14:26 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Pekka Enberg, casteyde.christian, Andrew Morton, netdev,
	bugzilla-daemon, bugme-daemon, Vegard Nossum
In-Reply-To: <alpine.DEB.2.00.1104200904440.8634@router.home>

Le mercredi 20 avril 2011 à 09:05 -0500, Christoph Lameter a écrit :
> On Wed, 20 Apr 2011, Eric Dumazet wrote:
> 
> > > Then, just disable SLUB_CMPXCHG_DOUBLE if KMEMCHECK is defined, as I did in my first patch.
> 
> Ok your first patch seems to be the sanest approach.
> 
> >  {
> > @@ -1889,16 +1895,18 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
> >  	struct kmem_cache_cpu *c;
> >  #ifdef CONFIG_CMPXCHG_LOCAL
> >  	unsigned long tid;
> > -#else
> > +#endif
> > +#ifdef MASK_IRQ_IN_SLAB_ALLOC
> >  	unsigned long flags;
> >  #endif
> >
> 
> Yea well that does not bring us much.

Well, we keep the fast free path ?

only slab_alloc() would have to disable irqs for ~20 instructions.




^ permalink raw reply

* Re: [PATCH] staging: octeon-ethernet: remove .get_sg, etc. ethtool_ops
From: Greg KH @ 2011-04-20 14:36 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: netdev, devel
In-Reply-To: <20110420142553.D497813909@rere.qmqm.pl>

On Wed, Apr 20, 2011 at 04:25:53PM +0200, Michał Mirosław wrote:
> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> ---
>  drivers/staging/octeon/ethernet-mdio.c |    2 --
>  1 files changed, 0 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
> index 10a82ef..8a11ffc 100644
> --- a/drivers/staging/octeon/ethernet-mdio.c
> +++ b/drivers/staging/octeon/ethernet-mdio.c
> @@ -91,8 +91,6 @@ const struct ethtool_ops cvm_oct_ethtool_ops = {
>  	.set_settings = cvm_oct_set_settings,
>  	.nway_reset = cvm_oct_nway_reset,
>  	.get_link = ethtool_op_get_link,
> -	.get_sg = ethtool_op_get_sg,
> -	.get_tx_csum = ethtool_op_get_tx_csum,
>  };

Why are you doing this?  Please explain it better in the changelog and
resend this.

thanks,

greg k-h

^ permalink raw reply

* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Christoph Lameter @ 2011-04-20 14:42 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Pekka Enberg, casteyde.christian, Andrew Morton, netdev,
	bugzilla-daemon, bugme-daemon, Vegard Nossum
In-Reply-To: <1303309591.3186.84.camel@edumazet-laptop>

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

On Wed, 20 Apr 2011, Eric Dumazet wrote:

> Le mercredi 20 avril 2011 à 09:05 -0500, Christoph Lameter a écrit :
> > On Wed, 20 Apr 2011, Eric Dumazet wrote:
> >
> > > > Then, just disable SLUB_CMPXCHG_DOUBLE if KMEMCHECK is defined, as I did in my first patch.
> >
> > Ok your first patch seems to be the sanest approach.
> >
> > >  {
> > > @@ -1889,16 +1895,18 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
> > >  	struct kmem_cache_cpu *c;
> > >  #ifdef CONFIG_CMPXCHG_LOCAL
> > >  	unsigned long tid;
> > > -#else
> > > +#endif
> > > +#ifdef MASK_IRQ_IN_SLAB_ALLOC
> > >  	unsigned long flags;
> > >  #endif
> > >
> >
> > Yea well that does not bring us much.
>
> Well, we keep the fast free path ?
>
> only slab_alloc() would have to disable irqs for ~20 instructions.

Avoiding the irq handling yields the savings that improve the fastpath. if
you do both then there is only a regression left. So lets go with
disabling the CMPXCHG_LOCAL.

^ permalink raw reply

* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Eric Dumazet @ 2011-04-20 15:01 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Pekka Enberg, casteyde.christian, Andrew Morton, netdev,
	bugzilla-daemon, bugme-daemon, Vegard Nossum
In-Reply-To: <alpine.DEB.2.00.1104200942020.9266@router.home>

Le mercredi 20 avril 2011 à 09:42 -0500, Christoph Lameter a écrit :

> Avoiding the irq handling yields the savings that improve the fastpath. if
> you do both then there is only a regression left. So lets go with
> disabling the CMPXCHG_LOCAL.

OK, let's do that then.

Thanks

[PATCH v4] slub: dont use cmpxchg_double if KMEMCHECK or DEBUG_PAGEALLOC

Christian Casteyde reported a KMEMCHECK splat in slub code.

Problem is now we are lockless and allow IRQ in slab_alloc(), the object
we manipulate from freelist can be allocated and freed right before we
try to read object->next.

Same problem can happen with DEBUG_PAGEALLOC

Just dont use cmpxchg_double() if either CONFIG_KMEMCHECK or
CONFIG_DEBUG_PAGEALLOC is defined.

Reported-by: Christian Casteyde <casteyde.christian@free.fr>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Vegard Nossum <vegardno@ifi.uio.no>
Cc: Christoph Lameter <cl@linux.com>
---
 mm/slub.c |   45 +++++++++++++++++++++++++--------------------
 1 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index 94d2a33..f31ab2c 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1540,7 +1540,12 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
 	}
 }
 
-#ifdef CONFIG_CMPXCHG_LOCAL
+#if defined(CONFIG_CMPXCHG_LOCAL) && !defined(CONFIG_KMEMCHECK) && \
+				     !defined(CONFIG_DEBUG_PAGEALLOC)
+#define SLUB_USE_CMPXCHG_DOUBLE
+#endif
+
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 #ifdef CONFIG_PREEMPT
 /*
  * Calculate the next globally unique transaction for disambiguiation
@@ -1604,7 +1609,7 @@ static inline void note_cmpxchg_failure(const char *n,
 
 void init_kmem_cache_cpus(struct kmem_cache *s)
 {
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	int cpu;
 
 	for_each_possible_cpu(cpu)
@@ -1643,7 +1648,7 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
 		page->inuse--;
 	}
 	c->page = NULL;
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	c->tid = next_tid(c->tid);
 #endif
 	unfreeze_slab(s, page, tail);
@@ -1780,7 +1785,7 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
 {
 	void **object;
 	struct page *new;
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	unsigned long flags;
 
 	local_irq_save(flags);
@@ -1819,7 +1824,7 @@ load_freelist:
 	c->node = page_to_nid(c->page);
 unlock_out:
 	slab_unlock(c->page);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	c->tid = next_tid(c->tid);
 	local_irq_restore(flags);
 #endif
@@ -1858,7 +1863,7 @@ new_slab:
 	}
 	if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
 		slab_out_of_memory(s, gfpflags, node);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	local_irq_restore(flags);
 #endif
 	return NULL;
@@ -1887,7 +1892,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
 {
 	void **object;
 	struct kmem_cache_cpu *c;
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	unsigned long tid;
 #else
 	unsigned long flags;
@@ -1896,7 +1901,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
 	if (slab_pre_alloc_hook(s, gfpflags))
 		return NULL;
 
-#ifndef CONFIG_CMPXCHG_LOCAL
+#ifndef SLUB_USE_CMPXCHG_DOUBLE
 	local_irq_save(flags);
 #else
 redo:
@@ -1910,7 +1915,7 @@ redo:
 	 */
 	c = __this_cpu_ptr(s->cpu_slab);
 
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	/*
 	 * The transaction ids are globally unique per cpu and per operation on
 	 * a per cpu queue. Thus they can be guarantee that the cmpxchg_double
@@ -1927,7 +1932,7 @@ redo:
 		object = __slab_alloc(s, gfpflags, node, addr, c);
 
 	else {
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 		/*
 		 * The cmpxchg will only match if there was no additional
 		 * operation and if we are on the right processor.
@@ -1954,7 +1959,7 @@ redo:
 		stat(s, ALLOC_FASTPATH);
 	}
 
-#ifndef CONFIG_CMPXCHG_LOCAL
+#ifndef SLUB_USE_CMPXCHG_DOUBLE
 	local_irq_restore(flags);
 #endif
 
@@ -2034,7 +2039,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
 {
 	void *prior;
 	void **object = (void *)x;
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	unsigned long flags;
 
 	local_irq_save(flags);
@@ -2070,7 +2075,7 @@ checks_ok:
 
 out_unlock:
 	slab_unlock(page);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	local_irq_restore(flags);
 #endif
 	return;
@@ -2084,7 +2089,7 @@ slab_empty:
 		stat(s, FREE_REMOVE_PARTIAL);
 	}
 	slab_unlock(page);
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	local_irq_restore(flags);
 #endif
 	stat(s, FREE_SLAB);
@@ -2113,7 +2118,7 @@ static __always_inline void slab_free(struct kmem_cache *s,
 {
 	void **object = (void *)x;
 	struct kmem_cache_cpu *c;
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	unsigned long tid;
 #else
 	unsigned long flags;
@@ -2121,7 +2126,7 @@ static __always_inline void slab_free(struct kmem_cache *s,
 
 	slab_free_hook(s, x);
 
-#ifndef CONFIG_CMPXCHG_LOCAL
+#ifndef SLUB_USE_CMPXCHG_DOUBLE
 	local_irq_save(flags);
 
 #else
@@ -2136,7 +2141,7 @@ redo:
 	 */
 	c = __this_cpu_ptr(s->cpu_slab);
 
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	tid = c->tid;
 	barrier();
 #endif
@@ -2144,7 +2149,7 @@ redo:
 	if (likely(page == c->page && c->node != NUMA_NO_NODE)) {
 		set_freepointer(s, object, c->freelist);
 
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 		if (unlikely(!this_cpu_cmpxchg_double(
 				s->cpu_slab->freelist, s->cpu_slab->tid,
 				c->freelist, tid,
@@ -2160,7 +2165,7 @@ redo:
 	} else
 		__slab_free(s, page, x, addr);
 
-#ifndef CONFIG_CMPXCHG_LOCAL
+#ifndef SLUB_USE_CMPXCHG_DOUBLE
 	local_irq_restore(flags);
 #endif
 }
@@ -2354,7 +2359,7 @@ static inline int alloc_kmem_cache_cpus(struct kmem_cache *s)
 	BUILD_BUG_ON(PERCPU_DYNAMIC_EARLY_SIZE <
 			SLUB_PAGE_SHIFT * sizeof(struct kmem_cache_cpu));
 
-#ifdef CONFIG_CMPXCHG_LOCAL
+#ifdef SLUB_USE_CMPXCHG_DOUBLE
 	/*
 	 * Must align to double word boundary for the double cmpxchg instructions
 	 * to work.



^ permalink raw reply related

* Re: [PATCH] bnx2x: dont dereference tcp header on non tcp frames
From: Dmitry Kravkov @ 2011-04-20 15:08 UTC (permalink / raw)
  To: David Miller
  Cc: eric.dumazet@gmail.com, Eilon Greenstein, netdev@vger.kernel.org
In-Reply-To: <1303292410.1813.23.camel@lb-tlvb-dmitry>

On Wed, 2011-04-20 at 02:40 -0700, Dmitry Kravkov wrote:

> Following patch fixes udp checksum offload flow and also addresses
> issues raised by Eric. We are testing it now.

It passed local regression, i was also unable to reproduce kmemcheck
warning.

I hit this one (on net-2.6 from today) not sure if it's related:


INFO: rcu_sched_state detected stall on CPU 0 (t=60000 jiffies)
sending NMI to all CPUs:
NMI backtrace for cpu 0
CPU 0 
Modules linked in: bnx2x nfs fscache nfsd nfs_acl auth_rpcgss autofs4
bluetooth rfkill lockd sunrpc ipv6 loop dm_mirror dm_multipath scsi_dh
video sbs sbshc power_meter battery acpi_memhotplug ac parport_pc lp
parport ide_cd_mod cdrom serio_raw option usb_wwan usbserial button b
nx2 tpm_tis tpm tpm_bios ipmi_si ipmi_msghandler hpilo mdio rtc_cmos
pcspkr rtc_core i5k_amb hwmon i5000_edac edac_core rtc_lib
dm_region_hash dm_log dm_mod ata_piix libata shpchp cciss sd_mod
scsi_mod ext3 jbd uhci_hcd ohci_hcd ehci_hcd [last unloaded: bnx2x]

Pid: 3441, comm: kworker/0:3 Not tainted 2.6.39-rc2test+ #2 HP ProLiant
DL380 G5
RIP: 0010:[<ffffffff811cbf65>]  [<ffffffff811cbf65>] delay_tsc+0x15/0x60
RSP: 0018:ffff88023fc03e78  EFLAGS: 00000803
RAX: 00000000ddf79987 RBX: 0000000000000001 RCX: ffffffff817894e0
RDX: 00000000000001aa RSI: 00000000000000ff RDI: 00000000002dc788
RBP: ffff88023fc03e78 R08: 0000000000000003 R09: 0000000000000000
R10: 0000000000000000 R11: 000000000000000a R12: ffff88023fc0e5e0
R13: ffff88023497cf60 R14: ffffffff81729900 R15: ffffffff81729a00
FS:  0000000000000000(0000) GS:ffff88023fc00000(0000)
knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00007f24456760a0 CR3: 0000000001713000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff4ff0 DR7: 0000000000000400
Process kworker/0:3 (pid: 3441, threadinfo ffff88021fe74000, task
ffff88023497cf60)
Stack:
 ffff88023fc03e88 ffffffff811cbf1a ffff88023fc03e98 ffffffff811cbf47
 ffff88023fc03eb8 ffffffff8101d155 0000000000000000 ffffffff81729900
 ffff88023fc03ef8 ffffffff81092b9c 000000004daf0bb9 0000000000000000
Call Trace:
 <IRQ> 
 [<ffffffff811cbf1a>] __delay+0xa/0x10
 [<ffffffff811cbf47>] __const_udelay+0x27/0x30
 [<ffffffff8101d155>] arch_trigger_all_cpu_backtrace+0x75/0xb0
 [<ffffffff81092b9c>] __rcu_pending+0x9c/0x370
 [<ffffffff81092efd>] rcu_check_callbacks+0x8d/0xd0
 [<ffffffff810530c1>] update_process_times+0x41/0x80
 [<ffffffff81070c07>] tick_periodic+0x27/0x70
 [<ffffffff81070c71>] tick_handle_periodic+0x21/0x80
 [<ffffffff8101cbd6>] smp_apic_timer_interrupt+0x66/0xa0
 [<ffffffff813c1993>] apic_timer_interrupt+0x13/0x20
 <EOI> 
 [<ffffffff811b1964>] ? blk_delay_work+0x34/0x40
 [<ffffffff8105d449>] process_one_work+0xf9/0x390
 [<ffffffff811b1930>] ? submit_bio+0xd0/0xd0
 [<ffffffff8105fa45>] worker_thread+0xe5/0x270
 [<ffffffff8105f960>] ? gcwq_mayday_timeout+0x80/0x80
 [<ffffffff810638e6>] kthread+0x96/0xa0
 [<ffffffff813c20d4>] kernel_thread_helper+0x4/0x10
 [<ffffffff81063850>] ? kthread_stop+0xd0/0xd0
 [<ffffffff813c20d0>] ? gs_change+0xb/0xb
Code: 89 e5 f7 e2 48 8d 7a 01 e8 c9 ff ff ff c9 c3 0f 1f 80 00 00 00 00
55 65 44 8b 0c 25 68 c5 00 00 48 89 e5 66 66 90 0f ae e8 0f 31 
 89 c0 44 89 ce eb 11 0f 1f 00 f3 90 65 8b 0c 25 68 c5 00 00 
Call Trace:
 <IRQ>  [<ffffffff811cbf1a>] __delay+0xa/0x10
 [<ffffffff811cbf47>] __const_udelay+0x27/0x30
 [<ffffffff8101d155>] arch_trigger_all_cpu_backtrace+0x75/0xb0
 [<ffffffff81092b9c>] __rcu_pending+0x9c/0x370
 [<ffffffff81092efd>] rcu_check_callbacks+0x8d/0xd0
 [<ffffffff810530c1>] update_process_times+0x41/0x80
 [<ffffffff81070c07>] tick_periodic+0x27/0x70
 [<ffffffff81070c71>] tick_handle_periodic+0x21/0x80
 [<ffffffff8101cbd6>] smp_apic_timer_interrupt+0x66/0xa0
 [<ffffffff813c1993>] apic_timer_interrupt+0x13/0x20
 <EOI>  [<ffffffff811b1964>] ? blk_delay_work+0x34/0x40
 [<ffffffff8105d449>] process_one_work+0xf9/0x390
 [<ffffffff811b1930>] ? submit_bio+0xd0/0xd0
 [<ffffffff8105fa45>] worker_thread+0xe5/0x270
 [<ffffffff8105f960>] ? gcwq_mayday_timeout+0x80/0x80
 [<ffffffff810638e6>] kthread+0x96/0xa0
 [<ffffffff813c20d4>] kernel_thread_helper+0x4/0x10
 [<ffffffff81063850>] ? kthread_stop+0xd0/0xd0
 [<ffffffff813c20d0>] ? gs_change+0xb/0xb




^ permalink raw reply

* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Christoph Lameter @ 2011-04-20 15:17 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Pekka Enberg, casteyde.christian, Andrew Morton, netdev,
	bugzilla-daemon, bugme-daemon, Vegard Nossum
In-Reply-To: <1303311687.3186.100.camel@edumazet-laptop>

On Wed, 20 Apr 2011, Eric Dumazet wrote:

> [PATCH v4] slub: dont use cmpxchg_double if KMEMCHECK or DEBUG_PAGEALLOC

Acked-by: Christoph Lameter <cl@linux.com>

>
> -#ifdef CONFIG_CMPXCHG_LOCAL
> +#if defined(CONFIG_CMPXCHG_LOCAL) && !defined(CONFIG_KMEMCHECK) && \
> +				     !defined(CONFIG_DEBUG_PAGEALLOC)
> +#define SLUB_USE_CMPXCHG_DOUBLE

#undef CONFIG_CMPXCHG_LOCAL instead? Would reduce patch size but its kind
of hacky.


^ permalink raw reply

* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Eric Dumazet @ 2011-04-20 15:30 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Pekka Enberg, casteyde.christian, Andrew Morton, netdev,
	bugzilla-daemon, bugme-daemon, Vegard Nossum
In-Reply-To: <alpine.DEB.2.00.1104201015520.9266@router.home>

Le mercredi 20 avril 2011 à 10:17 -0500, Christoph Lameter a écrit :
> On Wed, 20 Apr 2011, Eric Dumazet wrote:
> 
> > [PATCH v4] slub: dont use cmpxchg_double if KMEMCHECK or DEBUG_PAGEALLOC
> 
> Acked-by: Christoph Lameter <cl@linux.com>
> 
> >
> > -#ifdef CONFIG_CMPXCHG_LOCAL
> > +#if defined(CONFIG_CMPXCHG_LOCAL) && !defined(CONFIG_KMEMCHECK) && \
> > +				     !defined(CONFIG_DEBUG_PAGEALLOC)
> > +#define SLUB_USE_CMPXCHG_DOUBLE
> 
> #undef CONFIG_CMPXCHG_LOCAL instead? Would reduce patch size but its kind
> of hacky.
> 

Well, its definitely hacky :)

I chose a local definition (instead of Kconfig game), referring to
cmpxchg_double()




^ permalink raw reply

* [RFC net-next-2.6] can: replace spinlocks with mutexes
From: Oliver Hartkopp @ 2011-04-20 15:31 UTC (permalink / raw)
  To: David Miller, Eric Dumazet
  Cc: Linux Netdev List, Kurt Van Dijck, Urs Thuermann

This patch removes spinlocks for the CAN netdevice specific receive lists.
The RCU-based receive lists can be modified from process context or from the
netdevice notifier call. As both might sleep we can safely replace the
spinlocks with mutexes.

Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>

---

diff --git a/net/can/af_can.c b/net/can/af_can.c
index a8dcaa4..e52ed358 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -47,7 +47,7 @@
 #include <linux/kmod.h>
 #include <linux/slab.h>
 #include <linux/list.h>
-#include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <linux/rcupdate.h>
 #include <linux/uaccess.h>
 #include <linux/net.h>
@@ -79,7 +79,7 @@ MODULE_PARM_DESC(stats_timer, "enable timer for statistics (default:on)");
 
 /* receive filters subscribed for 'all' CAN devices */
 struct dev_rcv_lists can_rx_alldev_list;
-static DEFINE_SPINLOCK(can_rcvlists_lock);
+static DEFINE_MUTEX(can_rcvlists_lock);
 
 static struct kmem_cache *rcv_cache __read_mostly;
 
@@ -435,7 +435,7 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
 	if (!r)
 		return -ENOMEM;
 
-	spin_lock(&can_rcvlists_lock);
+	mutex_lock(&can_rcvlists_lock);
 
 	d = find_dev_rcv_lists(dev);
 	if (d) {
@@ -459,7 +459,7 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
 		err = -ENODEV;
 	}
 
-	spin_unlock(&can_rcvlists_lock);
+	mutex_unlock(&can_rcvlists_lock);
 
 	return err;
 }
@@ -497,7 +497,7 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
 	if (dev && dev->type != ARPHRD_CAN)
 		return;
 
-	spin_lock(&can_rcvlists_lock);
+	mutex_lock(&can_rcvlists_lock);
 
 	d = find_dev_rcv_lists(dev);
 	if (!d) {
@@ -548,7 +548,7 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
 	}
 
  out:
-	spin_unlock(&can_rcvlists_lock);
+	mutex_unlock(&can_rcvlists_lock);
 
 	/* schedule the receiver item for deletion */
 	if (r)
@@ -775,7 +775,7 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg,
 		break;
 
 	case NETDEV_UNREGISTER:
-		spin_lock(&can_rcvlists_lock);
+		mutex_lock(&can_rcvlists_lock);
 
 		d = dev->ml_priv;
 		if (d) {
@@ -789,7 +789,7 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg,
 			printk(KERN_ERR "can: notifier: receive list not "
 			       "found for dev %s\n", dev->name);
 
-		spin_unlock(&can_rcvlists_lock);
+		mutex_unlock(&can_rcvlists_lock);
 
 		break;
 	}


^ permalink raw reply related

* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Eric Dumazet @ 2011-04-20 15:34 UTC (permalink / raw)
  To: vegardno
  Cc: Christoph Lameter, Pekka Enberg, casteyde.christian,
	Andrew Morton, netdev, bugzilla-daemon, bugme-daemon
In-Reply-To: <66e0b8f575075d009bdb3633837951a3@ulrik.uio.no>

Le mercredi 20 avril 2011 à 17:15 +0200, Vegard Nossum a écrit :

>  Thanks, guys. I wonder: Is it possible to make a reproducible test-case 
>  (e.g. loadable module) for this?
> 

Not easy to code a specific test-case, but just use regular workload,
(and network trafic to get interrupts). Use CONFIG_PREEMPT to trigger
preemptions.

>  Also, pardon my ignorance, but can you explain why this is a bug with 
>  kmemcheck/page-alloc debug and not without them?

Without them, we can read object->next without trigerring a fault.
We can read garbage data (if object is in use, it was overwritten with
user data), but this doesnt matter because cmpxchg_double() wont perform
its work (since tid will have change)




^ permalink raw reply

* Re: [RFC net-next-2.6] can: replace spinlocks with mutexes
From: Eric Dumazet @ 2011-04-20 15:39 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: David Miller, Linux Netdev List, Kurt Van Dijck, Urs Thuermann
In-Reply-To: <4DAEFC55.2010500@hartkopp.net>

Le mercredi 20 avril 2011 à 17:31 +0200, Oliver Hartkopp a écrit :
> This patch removes spinlocks for the CAN netdevice specific receive lists.
> The RCU-based receive lists can be modified from process context or from the
> netdevice notifier call. As both might sleep we can safely replace the
> spinlocks with mutexes.
> 
> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
> 
> ---

But... why ?

A spinlock is faster/smaller than a mutex.

Maybe you wanted to _remove_ spinlock, since/if writer hold RTNL and
doesnt need to exclude another writer(s) ?

Note : I did not check the RTNL assertion, you might add appropriate
ASSERT_RTNL() calls just to be 100% safe.




^ permalink raw reply

* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Vegard Nossum @ 2011-04-20 15:15 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Christoph Lameter, Pekka Enberg, casteyde.christian,
	Andrew Morton, netdev, bugzilla-daemon, bugme-daemon
In-Reply-To: <1303311687.3186.100.camel@edumazet-laptop>

 On Wed, 20 Apr 2011 17:01:27 +0200, Eric Dumazet 
 <eric.dumazet@gmail.com> wrote:
> Le mercredi 20 avril 2011 à 09:42 -0500, Christoph Lameter a écrit :
>
>> Avoiding the irq handling yields the savings that improve the 
>> fastpath. if
>> you do both then there is only a regression left. So lets go with
>> disabling the CMPXCHG_LOCAL.
>
> OK, let's do that then.
>
> Thanks
>
> [PATCH v4] slub: dont use cmpxchg_double if KMEMCHECK or 
> DEBUG_PAGEALLOC
>
> Christian Casteyde reported a KMEMCHECK splat in slub code.
>
> Problem is now we are lockless and allow IRQ in slab_alloc(), the 
> object
> we manipulate from freelist can be allocated and freed right before 
> we
> try to read object->next.
>
> Same problem can happen with DEBUG_PAGEALLOC
>
> Just dont use cmpxchg_double() if either CONFIG_KMEMCHECK or
> CONFIG_DEBUG_PAGEALLOC is defined.
>
> Reported-by: Christian Casteyde <casteyde.christian@free.fr>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Pekka Enberg <penberg@cs.helsinki.fi>
> Cc: Vegard Nossum <vegardno@ifi.uio.no>
> Cc: Christoph Lameter <cl@linux.com>

 Thanks, guys. I wonder: Is it possible to make a reproducible test-case 
 (e.g. loadable module) for this?

 Also, pardon my ignorance, but can you explain why this is a bug with 
 kmemcheck/page-alloc debug and not without them?

 Thanks,


 Vegard

^ permalink raw reply

* Re: Add missing socket check in can/bcm release.
From: Dave Jones @ 2011-04-20 16:03 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20110419.203720.02289813.davem@davemloft.net>

On Tue, Apr 19, 2011 at 08:37:20PM -0700, David Miller wrote:
 > From: Dave Jones <davej@redhat.com>
 > Date: Tue, 19 Apr 2011 23:30:01 -0400
 > 
 > > We can get here with a NULL socket argument passed from userspace,
 > > so we need to handle it accordingly.
 > > 
 > > Signed-off-by: Dave Jones <davej@redhat.com>
 > 
 > Applied and queued up for -stable, thanks Dave.

Out of curiousity, while I was asleep it occured to me.. is it ever valid
for a ->release to get passed a NULL socket->sk ?  I'm wondering if we
can't do this check a layer up in sock_release, in case future protocols
reintroduce the same bug.

>From a quick look, almost every protocol has this check in its ->release.
Though it seems some do something different instead of using socket->sk,
so it would be a pointless check for some of the lesser used ones.

thoughts?

	Dave


^ permalink raw reply

* Re: [RFC net-next-2.6] can: replace spinlocks with mutexes
From: Oliver Hartkopp @ 2011-04-20 16:18 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Miller, Linux Netdev List, Kurt Van Dijck, Urs Thuermann
In-Reply-To: <1303313954.3186.117.camel@edumazet-laptop>

On 20.04.2011 17:39, Eric Dumazet wrote:
> Le mercredi 20 avril 2011 à 17:31 +0200, Oliver Hartkopp a écrit :
>> This patch removes spinlocks for the CAN netdevice specific receive lists.
>> The RCU-based receive lists can be modified from process context or from the
>> netdevice notifier call. As both might sleep we can safely replace the
>> spinlocks with mutexes.
>>
>> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
>>
>> ---
> 
> But... why ?
> 
> A spinlock is faster/smaller than a mutex.

Hm, i expected the mutex to have some advantages especially in multicore
systems ...

But if it doesn't has any vital advantage, we can leave it as-is.

> Maybe you wanted to _remove_ spinlock, since/if writer hold RTNL and
> doesnt need to exclude another writer(s) ?

That's an interesting idea. The filters are modified at socket
creation/removal time and can also be modified in between using sockopts by
_ordinary_ users. Could that be a problem?

> Note : I did not check the RTNL assertion, you might add appropriate
> ASSERT_RTNL() calls just to be 100% safe.

I'll investigate some similar places in the networking code and then replace
the spinlocks with rtnl_locks for some testing.

Thanks for the feedback,
Oliver


^ permalink raw reply

* Re: [PATCH 1/1] powerpc: Fix multicast problem in fs_enet driver
From: Scott Wood @ 2011-04-20 16:23 UTC (permalink / raw)
  To: Andrea Galbusera
  Cc: Pantelis Antoniou, Vitaly Bordug, netdev, linuxppc-dev,
	linux-kernel
In-Reply-To: <1303289719-16913-1-git-send-email-gizero@gmail.com>

On Wed, 20 Apr 2011 10:55:19 +0200
Andrea Galbusera <gizero@gmail.com> wrote:

> mac-fec.c was setting individual UDP address registers instead of multicast
> group address registers when joining a multicast group.
> This prevented from correctly receiving UDP multicast packets.
> According to datasheet, replaced hash_table_high and hash_table_low
> with grp_hash_table_high and grp_hash_table_low respectively.
> 
> Tested on a MPC5121 based board.
> 
> Signed-off-by: Andrea Galbusera <gizero@gmail.com>
> ---
>  drivers/net/fs_enet/mac-fec.c |    8 ++++----
>  1 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
> index 61035fc..b9fbc83 100644
> --- a/drivers/net/fs_enet/mac-fec.c
> +++ b/drivers/net/fs_enet/mac-fec.c
> @@ -226,8 +226,8 @@ static void set_multicast_finish(struct net_device *dev)
>  	}
>  
>  	FC(fecp, r_cntrl, FEC_RCNTRL_PROM);
> -	FW(fecp, hash_table_high, fep->fec.hthi);
> -	FW(fecp, hash_table_low, fep->fec.htlo);
> +	FW(fecp, grp_hash_table_high, fep->fec.hthi);
> +	FW(fecp, grp_hash_table_low, fep->fec.htlo);
>  }
>  
>  static void set_multicast_list(struct net_device *dev)
> @@ -273,8 +273,8 @@ static void restart(struct net_device *dev)
>  	/*
>  	 * Reset all multicast.
>  	 */
> -	FW(fecp, hash_table_high, fep->fec.hthi);
> -	FW(fecp, hash_table_low, fep->fec.htlo);
> +	FW(fecp, grp_hash_table_high, fep->fec.hthi);
> +	FW(fecp, grp_hash_table_low, fep->fec.htlo);
>  
>  	/*
>  	 * Set maximum receive buffer size.

This will break on 8xx which does not have grp_hash_table_*.  It has only
one set of hash table registers which are used only for multicast -- so
8xx should have fec_hash_table_* renamed to fec_grp_hash_table_* in struct
fec.

-Scott

^ permalink raw reply

* [PATCH] staging: octeon-ethernet: remove .get_sg, etc. ethtool_ops
From: Michał Mirosław @ 2011-04-20 16:27 UTC (permalink / raw)
  To: netdev; +Cc: Greg Kroah-Hartman, devel
In-Reply-To: <20110420143612.GA22661@suse.de>

Driver sets .get_sg and .get_tx_csum ethtool_ops to their default
values anyway. Those fields are deprecated, starting in 2.6.39.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/staging/octeon/ethernet-mdio.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 10a82ef..8a11ffc 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -91,8 +91,6 @@ const struct ethtool_ops cvm_oct_ethtool_ops = {
 	.set_settings = cvm_oct_set_settings,
 	.nway_reset = cvm_oct_nway_reset,
 	.get_link = ethtool_op_get_link,
-	.get_sg = ethtool_op_get_sg,
-	.get_tx_csum = ethtool_op_get_tx_csum,
 };
 
 /**
-- 
1.7.2.5


^ permalink raw reply related

* Re: [PATCH v2] can: add missing socket check in can/raw release
From: Dave Jones @ 2011-04-20 17:03 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: David Miller, netdev
In-Reply-To: <4DAECA1B.5050300@hartkopp.net>

On Wed, Apr 20, 2011 at 01:57:15PM +0200, Oliver Hartkopp wrote:
 > v2: added space after 'if' according code style.
 > 
 > We can get here with a NULL socket argument passed from userspace,
 > so we need to handle it accordingly.
 > 
 > Thanks to Dave Jones pointing at this issue in net/can/bcm.c
 > 
 > Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>

ACK. That was the first thing I hit this morning ;-)

	Dave


^ permalink raw reply

* [PATCH net-next 2/9] tg3: Adjust rx prod ring bd replenish thresholds
From: Matt Carlson @ 2011-04-20 17:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

The oldest tg3 devices had large rx producer ring BD caches.  Back then,
it made sense to make the BD cache replenish threshold only a function
of the number of rx buffers posted by the driver.  Since then, the BD
cache sizes have shrunk to 25% of their original size and, in some
cases, the ring sizes have quadrupled in size.  Under such conditions,
static BD cache replenish thresholds no longer match the hardware
constraints.

This patch attempts to factor in the BD cache size into the bd cache
replenish strategy, taking the existing hardware bugs into account.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/tg3.c |   67 ++++++++++++++++++++++++++++++++++++----------------
 drivers/net/tg3.h |    9 +++++-
 2 files changed, 53 insertions(+), 23 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 58787ea..4aecb0a 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7952,6 +7952,48 @@ static void tg3_rings_reset(struct tg3 *tp)
 	}
 }
 
+static void tg3_setup_rxbd_thresholds(struct tg3 *tp)
+{
+	u32 val, bdcache_maxcnt, host_rep_thresh, nic_rep_thresh;
+
+	if (!(tp->tg3_flags2 & TG3_FLG2_5750_PLUS) ||
+	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
+		bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5700;
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+		 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+		bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5755;
+	else
+		bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5906;
+
+	nic_rep_thresh = min(bdcache_maxcnt / 2, tp->rx_std_max_post);
+	host_rep_thresh = max_t(u32, tp->rx_pending / 8, 1);
+
+	val = min(nic_rep_thresh, host_rep_thresh);
+	tw32(RCVBDI_STD_THRESH, val);
+
+	if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS)
+		tw32(STD_REPLENISH_LWM, bdcache_maxcnt);
+
+	if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) ||
+		(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+		return;
+
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+		bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5700;
+	else
+		bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5717;
+
+	host_rep_thresh = max_t(u32, tp->rx_jumbo_pending / 8, 1);
+
+	val = min(bdcache_maxcnt / 2, host_rep_thresh);
+	tw32(RCVBDI_JUMBO_THRESH, val);
+
+	if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS)
+		tw32(JMB_REPLENISH_LWM, bdcache_maxcnt);
+}
+
 /* tp->lock is held. */
 static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 {
@@ -8223,21 +8265,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 		return -ENODEV;
 	}
 
-	/* Setup replenish threshold. */
-	val = tp->rx_pending / 8;
-	if (val == 0)
-		val = 1;
-	else if (val > tp->rx_std_max_post)
-		val = tp->rx_std_max_post;
-	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-		if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1)
-			tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2);
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1)
+		tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2);
 
-		if (val > (TG3_RX_INTERNAL_RING_SZ_5906 / 2))
-			val = TG3_RX_INTERNAL_RING_SZ_5906 / 2;
-	}
-
-	tw32(RCVBDI_STD_THRESH, val);
+	tg3_setup_rxbd_thresholds(tp);
 
 	/* Initialize TG3_BDINFO's at:
 	 *  RCVDBDI_STD_BD:	standard eth size rx ring
@@ -8275,8 +8306,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
 	    ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
 	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))) {
-		/* Setup replenish threshold. */
-		tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
 
 		if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
@@ -8317,11 +8346,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 			  tp->rx_jumbo_pending : 0;
 	tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx);
 
-	if (tp->tg3_flags3 & TG3_FLG3_57765_PLUS) {
-		tw32(STD_REPLENISH_LWM, 32);
-		tw32(JMB_REPLENISH_LWM, 16);
-	}
-
 	tg3_rings_reset(tp);
 
 	/* Initialize MAC address and backoff seed. */
@@ -13599,6 +13623,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
 		tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
 
+
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) ||
 	    (tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
 		tp->tg3_flags2 |= TG3_FLG2_5705_PLUS;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index db50bfe..dd331f8 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -23,8 +23,6 @@
 #define TG3_BDINFO_NIC_ADDR		0xcUL /* 32-bit */
 #define TG3_BDINFO_SIZE			0x10UL
 
-#define TG3_RX_INTERNAL_RING_SZ_5906	32
-
 #define TG3_RX_STD_MAX_SIZE_5700	512
 #define TG3_RX_STD_MAX_SIZE_5717	2048
 #define TG3_RX_JMB_MAX_SIZE_5700	256
@@ -2136,6 +2134,13 @@
 #define  NIC_SRAM_MBUF_POOL_BASE5705	0x00010000
 #define  NIC_SRAM_MBUF_POOL_SIZE5705	0x0000e000
 
+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5700	128
+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5755	64
+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5906	32
+
+#define TG3_SRAM_RX_JMB_BDCACHE_SIZE_5700	64
+#define TG3_SRAM_RX_JMB_BDCACHE_SIZE_5717	16
+
 
 /* Currently this is fixed. */
 #define TG3_PHY_MII_ADDR		0x01
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 1/9] tg3: Workaround rx_discards stat bug
From: Matt Carlson @ 2011-04-20 17:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson, Michael Chan

The 5717, 5718, 5719 A0, and 5720 A0 has a bug where the rx_discards
statistic counter will increment when dropping unwanted multicast
frames.  This patch works around the problem by attempting to
recreate the data using other means.  The resulting value will not be
accurate, but it can still serve as a problem indicator.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/tg3.c |   27 ++++++++++++++++++++++++++-
 drivers/net/tg3.h |    2 ++
 2 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 9915734..58787ea 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -339,6 +339,7 @@ static const struct {
 	{ "dma_write_prioq_full" },
 	{ "rxbds_empty" },
 	{ "rx_discards" },
+	{ "mbuf_lwm_thresh_hit" },
 	{ "rx_errors" },
 	{ "rx_threshold_hit" },
 
@@ -8207,6 +8208,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	val = BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE;
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
 		val |= BUFMGR_MODE_NO_TX_UNDERRUN;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5720_A0)
+		val |= BUFMGR_MODE_MBLOW_ATTN_ENAB;
 	tw32(BUFMGR_MODE, val);
 	for (i = 0; i < 2000; i++) {
 		if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE)
@@ -8870,7 +8875,19 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp)
 	TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE);
 
 	TG3_STAT_ADD32(&sp->rxbds_empty, RCVLPC_NO_RCV_BD_CNT);
-	TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) {
+		TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT);
+	} else {
+		u32 val = tr32(HOSTCC_FLOW_ATTN);
+		val = (val & HOSTCC_FLOW_ATTN_MBUF_LWM) ? 1 : 0;
+		if (val) {
+			tw32(HOSTCC_FLOW_ATTN, HOSTCC_FLOW_ATTN_MBUF_LWM);
+			sp->rx_discards.low += val;
+			if (sp->rx_discards.low < val)
+				sp->rx_discards.high += 1;
+		}
+		sp->mbuf_lwm_thresh_hit = sp->rx_discards;
+	}
 	TG3_STAT_ADD32(&sp->rx_errors, RCVLPC_IN_ERRORS_CNT);
 }
 
@@ -13973,6 +13990,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	    GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
 		tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
 
+	/* Set these bits to enable statistics workaround. */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5720_A0) {
+		tp->coalesce_mode |= HOSTCC_MODE_ATTN;
+		tp->grc_mode |= GRC_MODE_IRQ_ON_FLOW_ATTN;
+	}
+
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
 		tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 224c3e0..db50bfe 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -147,6 +147,7 @@
 #define  CHIPREV_ID_5717_A0		 0x05717000
 #define  CHIPREV_ID_57765_A0		 0x57785000
 #define  CHIPREV_ID_5719_A0		 0x05719000
+#define  CHIPREV_ID_5720_A0		 0x05720000
 #define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700			 0x07
 #define   ASIC_REV_5701			 0x00
@@ -2602,6 +2603,7 @@ struct tg3_hw_stats {
 	tg3_stat64_t			dma_write_prioq_full;
 	tg3_stat64_t			rxbds_empty;
 	tg3_stat64_t			rx_discards;
+	tg3_stat64_t			mbuf_lwm_thresh_hit;
 	tg3_stat64_t			rx_errors;
 	tg3_stat64_t			rx_threshold_hit;
 
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 5/9] tg3: Move phy accessor functions higher
From: Matt Carlson @ 2011-04-20 17:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

Phy accessor functions should live closer to where the base phy read /
write routines are.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/tg3.c |  136 ++++++++++++++++++++++++++--------------------------
 1 files changed, 68 insertions(+), 68 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e134e48..ea41d76 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -881,6 +881,74 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
 	return ret;
 }
 
+static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val)
+{
+	int err;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
+	if (err)
+		goto done;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
+	if (err)
+		goto done;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
+			   MII_TG3_MMD_CTRL_DATA_NOINC | devad);
+	if (err)
+		goto done;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val);
+
+done:
+	return err;
+}
+
+static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val)
+{
+	int err;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
+	if (err)
+		goto done;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
+	if (err)
+		goto done;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
+			   MII_TG3_MMD_CTRL_DATA_NOINC | devad);
+	if (err)
+		goto done;
+
+	err = tg3_readphy(tp, MII_TG3_MMD_ADDRESS, val);
+
+done:
+	return err;
+}
+
+static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val)
+{
+	int err;
+
+	err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
+	if (!err)
+		err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val);
+
+	return err;
+}
+
+static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
+{
+	int err;
+
+	err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
+	if (!err)
+		err = tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
+
+	return err;
+}
+
 static int tg3_bmcr_reset(struct tg3 *tp)
 {
 	u32 phy_control;
@@ -1154,52 +1222,6 @@ static void tg3_mdio_fini(struct tg3 *tp)
 	}
 }
 
-static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val)
-{
-	int err;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
-	if (err)
-		goto done;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
-	if (err)
-		goto done;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
-			   MII_TG3_MMD_CTRL_DATA_NOINC | devad);
-	if (err)
-		goto done;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val);
-
-done:
-	return err;
-}
-
-static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val)
-{
-	int err;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
-	if (err)
-		goto done;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
-	if (err)
-		goto done;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
-			   MII_TG3_MMD_CTRL_DATA_NOINC | devad);
-	if (err)
-		goto done;
-
-	err = tg3_readphy(tp, MII_TG3_MMD_ADDRESS, val);
-
-done:
-	return err;
-}
-
 /* tp->lock is held. */
 static inline void tg3_generate_fw_event(struct tg3 *tp)
 {
@@ -1576,28 +1598,6 @@ static void tg3_phy_fini(struct tg3 *tp)
 	}
 }
 
-static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val)
-{
-	int err;
-
-	err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
-	if (!err)
-		err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val);
-
-	return err;
-}
-
-static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
-{
-	int err;
-
-	err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
-	if (!err)
-		err = tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
-
-	return err;
-}
-
 static void tg3_phy_fet_toggle_apd(struct tg3 *tp, bool enable)
 {
 	u32 phytest;
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 3/9] tg3: Nullify RSS for loopback test
From: Matt Carlson @ 2011-04-20 17:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

The loopback test assumes all traffic goes to the first rx queue.  There
is a 1 in 4 chance this won't be true if RSS is enabled though.  This
patch reprograms the RSS indirection table to route all rx packets to
the first queue.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/tg3.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 4aecb0a..1f233c4 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -11269,6 +11269,15 @@ static int tg3_test_loopback(struct tg3 *tp)
 		goto done;
 	}
 
+	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) {
+		int i;
+
+		/* Reroute all rx packets to the 1st queue */
+		for (i = MAC_RSS_INDIR_TBL_0;
+		     i < MAC_RSS_INDIR_TBL_0 + TG3_RSS_INDIR_TBL_SIZE; i += 4)
+			tw32(i, 0x0);
+	}
+
 	/* Turn off gphy autopowerdown. */
 	if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD)
 		tg3_phy_toggle_apd(tp, false);
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 9/9] tg3: Add additional EEE messaging
From: Matt Carlson @ 2011-04-20 17:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

This patch adds link messages and an item to the sign-on banner to make
EEE status more visible.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/tg3.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 9ed6bfb..693f36e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1360,6 +1360,11 @@ static void tg3_link_report(struct tg3 *tp)
 			    "on" : "off",
 			    (tp->link_config.active_flowctrl & FLOW_CTRL_RX) ?
 			    "on" : "off");
+
+		if (tp->phy_flags & TG3_PHYFLG_EEE_CAP)
+			netdev_info(tp->dev, "EEE is %s\n",
+				    tp->setlpicnt ? "enabled" : "disabled");
+
 		tg3_ump_link_report(tp);
 	}
 }
@@ -15278,8 +15283,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 			ethtype = "10/100/1000Base-T";
 
 		netdev_info(dev, "attached PHY is %s (%s Ethernet) "
-			    "(WireSpeed[%d])\n", tg3_phy_string(tp), ethtype,
-			  (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) == 0);
+			    "(WireSpeed[%d], EEE[%d])\n",
+			    tg3_phy_string(tp), ethtype,
+			    (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) == 0,
+			    (tp->phy_flags & TG3_PHYFLG_EEE_CAP) != 0);
 	}
 
 	netdev_info(dev, "RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n",
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 0/9] tg3: Bugfixes and cleanups
From: Matt Carlson @ 2011-04-20 17:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

This patchset adds a few low-priority bugfixes and adds accessors
for the phy aux ctrl registers.



^ permalink raw reply

* [PATCH net-next 6/9] tg3: Add read accessor for AUX CTRL phy reg
From: Matt Carlson @ 2011-04-20 17:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

This patch adds a read accessor for the aux ctrl register.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/tg3.c |   39 ++++++++++++++++++++++++++++-----------
 drivers/net/tg3.h |   17 ++++++++++-------
 2 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ea41d76..7be10cf 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -949,6 +949,19 @@ static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
 	return err;
 }
 
+static int tg3_phy_auxctl_read(struct tg3 *tp, int reg, u32 *val)
+{
+	int err;
+
+	err = tg3_writephy(tp, MII_TG3_AUX_CTRL,
+			   (reg << MII_TG3_AUXCTL_MISC_RDSEL_SHIFT) |
+			   MII_TG3_AUXCTL_SHDWSEL_MISC);
+	if (!err)
+		err = tg3_readphy(tp, MII_TG3_AUX_CTRL, val);
+
+	return err;
+}
+
 static int tg3_bmcr_reset(struct tg3 *tp)
 {
 	u32 phy_control;
@@ -1679,10 +1692,11 @@ static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
 			tg3_writephy(tp, MII_TG3_FET_TEST, ephy);
 		}
 	} else {
-		phy = MII_TG3_AUXCTL_MISC_RDSEL_MISC |
-		      MII_TG3_AUXCTL_SHDWSEL_MISC;
-		if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, phy) &&
-		    !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy)) {
+		int ret;
+
+		ret = tg3_phy_auxctl_read(tp,
+					  MII_TG3_AUXCTL_SHDWSEL_MISC, &phy);
+		if (!ret) {
 			if (enable)
 				phy |= MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
 			else
@@ -1695,13 +1709,14 @@ static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
 
 static void tg3_phy_set_wirespeed(struct tg3 *tp)
 {
+	int ret;
 	u32 val;
 
 	if (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED)
 		return;
 
-	if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007) &&
-	    !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val))
+	ret = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_MISC, &val);
+	if (!ret)
 		tg3_writephy(tp, MII_TG3_AUX_CTRL,
 			     (val | (1 << 15) | (1 << 4)));
 }
@@ -2092,8 +2107,9 @@ out:
 		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
 	} else if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
 		/* Set bit 14 with read-modify-write to preserve other bits */
-		if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007) &&
-		    !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val))
+		err = tg3_phy_auxctl_read(tp,
+					  MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val);
+		if (!err)
 			tg3_writephy(tp, MII_TG3_AUX_CTRL, val | 0x4000);
 	}
 
@@ -3263,9 +3279,10 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
 	current_duplex = DUPLEX_INVALID;
 
 	if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) {
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007);
-		tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
-		if (!(val & (1 << 10))) {
+		err = tg3_phy_auxctl_read(tp,
+					  MII_TG3_AUXCTL_SHDWSEL_MISCTEST,
+					  &val);
+		if (!err && !(val & (1 << 10))) {
 			val |= (1 << 10);
 			tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
 			goto relink;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index dd331f8..b9382f1 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2194,19 +2194,22 @@
 
 #define MII_TG3_AUX_CTRL		0x18 /* auxiliary control register */
 
+#define MII_TG3_AUXCTL_SHDWSEL_AUXCTL	0x0000
+#define MII_TG3_AUXCTL_ACTL_TX_6DB	0x0400
+#define MII_TG3_AUXCTL_ACTL_SMDSP_ENA	0x0800
+
+#define MII_TG3_AUXCTL_SHDWSEL_PWRCTL	0x0002
 #define MII_TG3_AUXCTL_PCTL_100TX_LPWR	0x0010
 #define MII_TG3_AUXCTL_PCTL_SPR_ISOLATE	0x0020
 #define MII_TG3_AUXCTL_PCTL_VREG_11V	0x0180
-#define MII_TG3_AUXCTL_SHDWSEL_PWRCTL	0x0002
 
-#define MII_TG3_AUXCTL_MISC_WREN	0x8000
-#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX	0x0200
-#define MII_TG3_AUXCTL_MISC_RDSEL_MISC	0x7000
+#define MII_TG3_AUXCTL_SHDWSEL_MISCTEST	0x0004
+
 #define MII_TG3_AUXCTL_SHDWSEL_MISC	0x0007
+#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX	0x0200
+#define MII_TG3_AUXCTL_MISC_RDSEL_SHIFT	12
+#define MII_TG3_AUXCTL_MISC_WREN	0x8000
 
-#define MII_TG3_AUXCTL_ACTL_SMDSP_ENA	0x0800
-#define MII_TG3_AUXCTL_ACTL_TX_6DB	0x0400
-#define MII_TG3_AUXCTL_SHDWSEL_AUXCTL	0x0000
 
 #define MII_TG3_AUX_STAT		0x19 /* auxiliary status register */
 #define MII_TG3_AUX_STAT_LPASS		0x0004
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 8/9] tg3: Add macro for SMDSP toggling
From: Matt Carlson @ 2011-04-20 17:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

A common AUX CTRL operation in the driver is to enable and disable the
SMDSP.  This patch consolidates the code so that the details of the
operation are in one place.  This patch also adds code to make sure the
SMDSP is enabled before executing code that relies on it.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/tg3.c |  102 ++++++++++++++++++++++++-----------------------------
 1 files changed, 46 insertions(+), 56 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 69cd7cf..9ed6bfb 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -970,6 +970,15 @@ static int tg3_phy_auxctl_write(struct tg3 *tp, int reg, u32 set)
 	return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg);
 }
 
+#define TG3_PHY_AUXCTL_SMDSP_ENABLE(tp) \
+	tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \
+			     MII_TG3_AUXCTL_ACTL_SMDSP_ENA | \
+			     MII_TG3_AUXCTL_ACTL_TX_6DB)
+
+#define TG3_PHY_AUXCTL_SMDSP_DISABLE(tp) \
+	tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \
+			     MII_TG3_AUXCTL_ACTL_TX_6DB);
+
 static int tg3_bmcr_reset(struct tg3 *tp)
 {
 	u32 phy_control;
@@ -1738,11 +1747,8 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
 
 	otp = tp->phy_otp;
 
-	/* Enable SM_DSP clock and tx 6dB coding. */
-	phy = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-	      MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
-	      MII_TG3_AUXCTL_ACTL_TX_6DB;
-	tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+	if (TG3_PHY_AUXCTL_SMDSP_ENABLE(tp))
+		return;
 
 	phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT);
 	phy |= MII_TG3_DSP_TAP1_AGCTGT_DFLT;
@@ -1766,10 +1772,7 @@ static void tg3_phy_apply_otp(struct tg3 *tp)
 	      ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT);
 	tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy);
 
-	/* Turn off SM_DSP clock. */
-	phy = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-	      MII_TG3_AUXCTL_ACTL_TX_6DB;
-	tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+	TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
 }
 
 static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
@@ -1804,18 +1807,11 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
 			case ASIC_REV_5717:
 			case ASIC_REV_5719:
 			case ASIC_REV_57765:
-				/* Enable SM_DSP clock and tx 6dB coding. */
-				val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-				      MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
-				      MII_TG3_AUXCTL_ACTL_TX_6DB;
-				tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
-
-				tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000);
-
-				/* Turn off SM_DSP clock. */
-				val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-				      MII_TG3_AUXCTL_ACTL_TX_6DB;
-				tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+				if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+					tg3_phydsp_write(tp, MII_TG3_DSP_TAP26,
+							 0x0000);
+					TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+				}
 			}
 			/* Fallthrough */
 		case TG3_CL45_D7_EEERES_STAT_LP_100TX:
@@ -1967,8 +1963,9 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
 			     (MII_TG3_CTRL_AS_MASTER |
 			      MII_TG3_CTRL_ENABLE_AS_MASTER));
 
-		/* Enable SM_DSP_CLOCK and 6dB.  */
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+		err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
+		if (err)
+			return err;
 
 		/* Block the PHY control access.  */
 		tg3_phydsp_write(tp, 0x8005, 0x0800);
@@ -1987,13 +1984,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
 	tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
 	tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000);
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
-		/* Set Extended packet length bit for jumbo frames */
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4400);
-	} else {
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
-	}
+	TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
 
 	tg3_writephy(tp, MII_TG3_CTRL, phy9_orig);
 
@@ -2081,33 +2072,39 @@ static int tg3_phy_reset(struct tg3 *tp)
 		tg3_phy_toggle_apd(tp, false);
 
 out:
-	if (tp->phy_flags & TG3_PHYFLG_ADC_BUG) {
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+	if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) &&
+	    !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
 		tg3_phydsp_write(tp, 0x201f, 0x2aaa);
 		tg3_phydsp_write(tp, 0x000a, 0x0323);
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+		TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
 	}
+
 	if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) {
 		tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
 		tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
 	}
+
 	if (tp->phy_flags & TG3_PHYFLG_BER_BUG) {
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
-		tg3_phydsp_write(tp, 0x000a, 0x310b);
-		tg3_phydsp_write(tp, 0x201f, 0x9506);
-		tg3_phydsp_write(tp, 0x401f, 0x14e2);
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+		if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+			tg3_phydsp_write(tp, 0x000a, 0x310b);
+			tg3_phydsp_write(tp, 0x201f, 0x9506);
+			tg3_phydsp_write(tp, 0x401f, 0x14e2);
+			TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+		}
 	} else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) {
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
-		tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
-		if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) {
-			tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b);
-			tg3_writephy(tp, MII_TG3_TEST1,
-				     MII_TG3_TEST1_TRIM_EN | 0x4);
-		} else
-			tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b);
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+		if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+			tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
+			if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) {
+				tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b);
+				tg3_writephy(tp, MII_TG3_TEST1,
+					     MII_TG3_TEST1_TRIM_EN | 0x4);
+			} else
+				tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b);
+
+			TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+		}
 	}
+
 	/* Set Extended packet length bit (bit 14) on all chips that */
 	/* support jumbo frames */
 	if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) {
@@ -3011,11 +3008,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
 		tw32(TG3_CPMU_EEE_MODE,
 		     tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
 
-		/* Enable SM_DSP clock and tx 6dB coding. */
-		val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-		      MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
-		      MII_TG3_AUXCTL_ACTL_TX_6DB;
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+		TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
 
 		switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
 		case ASIC_REV_5717:
@@ -3044,10 +3037,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
 		}
 		tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
 
-		/* Turn off SM_DSP clock. */
-		val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-		      MII_TG3_AUXCTL_ACTL_TX_6DB;
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+		TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
 	}
 
 	if (tp->link_config.autoneg == AUTONEG_DISABLE &&
-- 
1.7.3.4



^ permalink raw reply related


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