LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] powerpc: Enable NO_BOOTMEM
From: Emil Medve @ 2014-05-08  7:05 UTC (permalink / raw)
  To: benh, linuxppc-dev; +Cc: Emil Medve
In-Reply-To: <1399532702-1514-1-git-send-email-Emilian.Medve@Freescale.com>

Currently bootmem is just a wrapper around/on top of memblock. This
eliminates from the build/kernel image the bootmem code and the
initialization wrapper code just as other ARHC(es) did: x86, arm,
etc

For now only cover !NUMA systems

Signed-off-by: Emil Medve <Emilian.Medve@Freescale.com>
---

v2: Acknowledge that NUMA systems/builds are not covered by this patch

v3: Don't re-define NO_BOOTMEM
    Update the commit message

 arch/powerpc/Kconfig  | 1 +
 arch/powerpc/mm/mem.c | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index e099899..3499303 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -105,6 +105,7 @@ config PPC
 	select HAVE_ARCH_KGDB
 	select HAVE_KRETPROBES
 	select HAVE_ARCH_TRACEHOOK
+	select NO_BOOTMEM if !NUMA
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP
 	select HAVE_DMA_ATTRS
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index eaf5d1d8..d3e1d5f 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -187,10 +187,12 @@ EXPORT_SYMBOL_GPL(walk_system_ram_range);
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 void __init do_init_bootmem(void)
 {
+#ifndef CONFIG_NO_BOOTMEM
 	unsigned long start, bootmap_pages;
 	struct memblock_region *reg;
 	int boot_mapsize;
 	phys_addr_t _total_lowmem;
+#endif
 	phys_addr_t _lowmem_end_addr;
 
 #ifndef CONFIG_HIGHMEM
@@ -203,6 +205,7 @@ void __init do_init_bootmem(void)
 	max_low_pfn = _lowmem_end_addr >> PAGE_SHIFT;
 	min_low_pfn = MEMORY_START >> PAGE_SHIFT;
 
+#ifndef CONFIG_NO_BOOTMEM
 	/*
 	 * Find an area to use for the bootmem bitmap.  Calculate the size of
 	 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
@@ -214,12 +217,14 @@ void __init do_init_bootmem(void)
 	start = memblock_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
 
 	boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
+#endif
 
 	/* Place all memblock_regions in the same node and merge contiguous
 	 * memblock_regions
 	 */
 	memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0);
 
+#ifndef CONFIG_NO_BOOTMEM
 	/* Add all physical memory to the bootmem map, mark each area
 	 * present.
 	 */
@@ -234,11 +239,14 @@ void __init do_init_bootmem(void)
 			reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
 		}
 	}
+#endif
 
 	/* XXX need to clip this if using highmem? */
 	sparse_memory_present_with_active_regions(0);
 
+#ifndef CONFIG_NO_BOOTMEM
 	init_bootmem_done = 1;
+#endif
 }
 
 /* mark pages that don't exist as nosave */
-- 
1.9.2

^ permalink raw reply related

* [PATCH 2/2 v3] powerpc: Enable NO_BOOTMEM
From: Emil Medve @ 2014-05-08  7:06 UTC (permalink / raw)
  To: benh, linuxppc-dev; +Cc: Emil Medve
In-Reply-To: <1399532799-1557-1-git-send-email-Emilian.Medve@Freescale.com>

Currently bootmem is just a wrapper around/on top of memblock. This
eliminates from the build/kernel image the bootmem code and the
initialization wrapper code just as other ARHC(es) did: x86, arm,
etc

For now only cover !NUMA systems

Signed-off-by: Emil Medve <Emilian.Medve@Freescale.com>
---

v2: Acknowledge that NUMA systems/builds are not covered by this patch

v3: Don't re-define NO_BOOTMEM
    Update the commit message

 arch/powerpc/Kconfig  | 1 +
 arch/powerpc/mm/mem.c | 8 ++++++++
 2 files changed, 9 insertions(+)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index e099899..3499303 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -105,6 +105,7 @@ config PPC
 	select HAVE_ARCH_KGDB
 	select HAVE_KRETPROBES
 	select HAVE_ARCH_TRACEHOOK
+	select NO_BOOTMEM if !NUMA
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP
 	select HAVE_DMA_ATTRS
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index eaf5d1d8..d3e1d5f 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -187,10 +187,12 @@ EXPORT_SYMBOL_GPL(walk_system_ram_range);
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 void __init do_init_bootmem(void)
 {
+#ifndef CONFIG_NO_BOOTMEM
 	unsigned long start, bootmap_pages;
 	struct memblock_region *reg;
 	int boot_mapsize;
 	phys_addr_t _total_lowmem;
+#endif
 	phys_addr_t _lowmem_end_addr;
 
 #ifndef CONFIG_HIGHMEM
@@ -203,6 +205,7 @@ void __init do_init_bootmem(void)
 	max_low_pfn = _lowmem_end_addr >> PAGE_SHIFT;
 	min_low_pfn = MEMORY_START >> PAGE_SHIFT;
 
+#ifndef CONFIG_NO_BOOTMEM
 	/*
 	 * Find an area to use for the bootmem bitmap.  Calculate the size of
 	 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
@@ -214,12 +217,14 @@ void __init do_init_bootmem(void)
 	start = memblock_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
 
 	boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
+#endif
 
 	/* Place all memblock_regions in the same node and merge contiguous
 	 * memblock_regions
 	 */
 	memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0);
 
+#ifndef CONFIG_NO_BOOTMEM
 	/* Add all physical memory to the bootmem map, mark each area
 	 * present.
 	 */
@@ -234,11 +239,14 @@ void __init do_init_bootmem(void)
 			reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
 		}
 	}
+#endif
 
 	/* XXX need to clip this if using highmem? */
 	sparse_memory_present_with_active_regions(0);
 
+#ifndef CONFIG_NO_BOOTMEM
 	init_bootmem_done = 1;
+#endif
 }
 
 /* mark pages that don't exist as nosave */
-- 
1.9.2

^ permalink raw reply related

* [PATCH 1/2 v3] bootmem/powerpc: Unify bootmem initialization
From: Emil Medve @ 2014-05-08  7:06 UTC (permalink / raw)
  To: benh, linuxppc-dev; +Cc: Emil Medve

Unify the low/highmem code path from do_init_bootmem() by using (the)
lowmem related variables/parameters even when the low/highmem split
is not needed (64-bit) or configured. In such cases the "lowmem"
variables/parameters continue to observe the definition by referring
to memory directly mapped by the kernel

Signed-off-by: Emil Medve <Emilian.Medve@Freescale.com>
---

v2: Rebased, no changes

v3: No changes

 arch/powerpc/mm/mem.c | 36 ++++++++++++++++--------------------
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 32202c9..eaf5d1d8 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -188,27 +188,31 @@ EXPORT_SYMBOL_GPL(walk_system_ram_range);
 void __init do_init_bootmem(void)
 {
 	unsigned long start, bootmap_pages;
-	unsigned long total_pages;
 	struct memblock_region *reg;
 	int boot_mapsize;
+	phys_addr_t _total_lowmem;
+	phys_addr_t _lowmem_end_addr;
 
-	max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
-	total_pages = (memblock_end_of_DRAM() - memstart_addr) >> PAGE_SHIFT;
-#ifdef CONFIG_HIGHMEM
-	total_pages = total_lowmem >> PAGE_SHIFT;
-	max_low_pfn = lowmem_end_addr >> PAGE_SHIFT;
+#ifndef CONFIG_HIGHMEM
+	_lowmem_end_addr = memblock_end_of_DRAM();
+#else
+	_lowmem_end_addr = lowmem_end_addr;
 #endif
 
+	max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
+	max_low_pfn = _lowmem_end_addr >> PAGE_SHIFT;
+	min_low_pfn = MEMORY_START >> PAGE_SHIFT;
+
 	/*
 	 * Find an area to use for the bootmem bitmap.  Calculate the size of
 	 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
 	 * Add 1 additional page in case the address isn't page-aligned.
 	 */
-	bootmap_pages = bootmem_bootmap_pages(total_pages);
+	_total_lowmem = _lowmem_end_addr - memstart_addr;
+	bootmap_pages = bootmem_bootmap_pages(_total_lowmem >> PAGE_SHIFT);
 
 	start = memblock_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
 
-	min_low_pfn = MEMORY_START >> PAGE_SHIFT;
 	boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
 
 	/* Place all memblock_regions in the same node and merge contiguous
@@ -219,26 +223,18 @@ void __init do_init_bootmem(void)
 	/* Add all physical memory to the bootmem map, mark each area
 	 * present.
 	 */
-#ifdef CONFIG_HIGHMEM
-	free_bootmem_with_active_regions(0, lowmem_end_addr >> PAGE_SHIFT);
+	free_bootmem_with_active_regions(0, max_low_pfn);
 
 	/* reserve the sections we're already using */
 	for_each_memblock(reserved, reg) {
-		unsigned long top = reg->base + reg->size - 1;
-		if (top < lowmem_end_addr)
+		if (reg->base + reg->size - 1 < _lowmem_end_addr)
 			reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
-		else if (reg->base < lowmem_end_addr) {
-			unsigned long trunc_size = lowmem_end_addr - reg->base;
+		else if (reg->base < _lowmem_end_addr) {
+			unsigned long trunc_size = _lowmem_end_addr - reg->base;
 			reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
 		}
 	}
-#else
-	free_bootmem_with_active_regions(0, max_pfn);
 
-	/* reserve the sections we're already using */
-	for_each_memblock(reserved, reg)
-		reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
-#endif
 	/* XXX need to clip this if using highmem? */
 	sparse_memory_present_with_active_regions(0);
 
-- 
1.9.2

^ permalink raw reply related

* [RFC PATCH] powerpc: fix wrong sp saved in save_stack_trace()
From: Li Zhong @ 2014-05-08  9:01 UTC (permalink / raw)
  To: PowerPC email list; +Cc: Paul Mackerras

I found stack trace couldn't be saved sometimes. After some
investigation, it seems that when function trace is enabled, 

void save_stack_trace(struct stack_trace *trace)
{
        unsigned long sp;

        asm("mr %0,1" : "=r" (sp));

        save_context_stack(trace, sp, current, 1);
}

is compiled into: 

c0000000000432c0 <.save_stack_trace>:
c0000000000432c0:       7c 08 02 a6     mflr    r0
c0000000000432c4:       f8 01 00 10     std     r0,16(r1)
c0000000000432c8:       f8 21 ff 81     stdu    r1,-128(r1)
c0000000000432cc:       f8 61 00 70     std     r3,112(r1)
c0000000000432d0:       4b fc 77 bd     bl      c00000000000aa8c
<._mcount>
c0000000000432d4:       60 00 00 00     nop
c0000000000432d8:       7c 24 0b 78     mr      r4,r1

c0000000000432dc:       e8 ad 02 78     ld      r5,632(r13)
c0000000000432e0:       e8 61 00 70     ld      r3,112(r1)
c0000000000432e4:       38 c0 00 01     li      r6,1
c0000000000432e8:       38 21 00 80     addi    r1,r1,128
c0000000000432ec:       e8 01 00 10     ld      r0,16(r1)
c0000000000432f0:       7c 08 03 a6     mtlr    r0
c0000000000432f4:       4b ff fe 5c     b       c000000000043150
<.save_context_stack>
c0000000000432f8:       60 00 00 00     nop
c0000000000432fc:       60 42 00 00     ori     r2,r2,0

new stack frame -128(r1) is created to call ._mcount, and this new r1 is
copied into sp as the stack pointer, which then could be overwritten by
save_context_stack's prolog. 

I don't know how to specify in C that the embedded asm be compiled after
r1 being added back to the original value. But as a workaround, maybe we
could move this embedded asm into save_context_stack(). 

Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/stacktrace.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
index 3d30ef1..5c0b461 100644
--- a/arch/powerpc/kernel/stacktrace.c
+++ b/arch/powerpc/kernel/stacktrace.c
@@ -22,6 +22,9 @@
 static void save_context_stack(struct stack_trace *trace, unsigned long sp,
 			struct task_struct *tsk, int savesched)
 {
+	if (tsk == current)
+		asm("mr %0,1" : "=r" (sp));
+
 	for (;;) {
 		unsigned long *stack = (unsigned long *) sp;
 		unsigned long newsp, ip;
@@ -48,11 +51,7 @@ static void save_context_stack(struct stack_trace *trace, unsigned long sp,
 
 void save_stack_trace(struct stack_trace *trace)
 {
-	unsigned long sp;
-
-	asm("mr %0,1" : "=r" (sp));
-
-	save_context_stack(trace, sp, current, 1);
+	save_context_stack(trace, 0, current, 1);
 }
 EXPORT_SYMBOL_GPL(save_stack_trace);
 

^ permalink raw reply related

* [PATCH V4 0/2] mm: FAULT_AROUND_ORDER patchset performance data for powerpc
From: Madhavan Srinivasan @ 2014-05-08  9:28 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, linux-mm, linux-arch, x86
  Cc: riel, ak, peterz, rusty, dave.hansen, Madhavan Srinivasan, paulus,
	mgorman, akpm, mingo, kirill.shutemov

Kirill A. Shutemov with 8c6e50b029 commit introduced
vm_ops->map_pages() for mapping easy accessible pages around
fault address in hope to reduce number of minor page faults.

This patch creates infrastructure to modify the FAULT_AROUND_ORDER
value using mm/Kconfig. This will enable architecture maintainers
to decide on suitable FAULT_AROUND_ORDER value based on
performance data for that architecture. First patch also defaults
FAULT_AROUND_ORDER Kconfig element to 4. Second patch list
out the performance numbers for powerpc (platform pseries) and
initialize the fault around order variable for pseries platform of
powerpc.

V4 Changes:
  Replaced the BUILD_BUG_ON with VM_BUG_ON.
  Moved fault_around_pages() and fault_around_mask() functions outside of
   #ifdef CONFIG_DEBUG_FS.

V3 Changes:
  Replaced FAULT_AROUND_ORDER macro to a variable to support arch's that
   supports sub platforms.
  Made changes in commit messages.

V2 Changes:
  Created Kconfig parameter for FAULT_AROUND_ORDER
  Added check in do_read_fault to handle FAULT_AROUND_ORDER value of 0
  Made changes in commit messages.

Madhavan Srinivasan (2):
  mm: move FAULT_AROUND_ORDER to arch/
  powerpc/pseries: init fault_around_order for pseries

 arch/powerpc/platforms/pseries/pseries.h |    2 ++
 arch/powerpc/platforms/pseries/setup.c   |    5 +++++
 mm/Kconfig                               |    8 ++++++++
 mm/memory.c                              |   25 ++++++-------------------
 4 files changed, 21 insertions(+), 19 deletions(-)

-- 
1.7.10.4

^ permalink raw reply

* [PATCH V4 2/2] powerpc/pseries: init fault_around_order for pseries
From: Madhavan Srinivasan @ 2014-05-08  9:28 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, linux-mm, linux-arch, x86
  Cc: riel, ak, peterz, rusty, dave.hansen, Madhavan Srinivasan, paulus,
	mgorman, akpm, mingo, kirill.shutemov
In-Reply-To: <1399541296-18810-1-git-send-email-maddy@linux.vnet.ibm.com>

Performance data for different FAULT_AROUND_ORDER values from 4 socket
Power7 system (128 Threads and 128GB memory). perf stat with repeat of 5
is used to get the stddev values. Test ran in v3.14 kernel (Baseline) and
v3.15-rc1 for different fault around order values. %change here is calculated
in this method ((new value - baseline)/baseline). And negative %change says
its a drop in time.

FAULT_AROUND_ORDER      Baseline        1               3               4               5               8

Linux build (make -j64)
minor-faults            47,437,359      35,279,286      25,425,347      23,461,275      22,002,189      21,435,836
times in seconds        347.302528420   344.061588460   340.974022391   348.193508116   348.673900158   350.986543618
 stddev for time        ( +-  1.50% )   ( +-  0.73% )   ( +-  1.13% )   ( +-  1.01% )   ( +-  1.89% )   ( +-  1.55% )
 %chg time to baseline                  -0.9%           -1.8%           0.2%            0.39%           1.06%

Linux rebuild (make -j64)
minor-faults            941,552         718,319         486,625         440,124         410,510         397,416
times in seconds        30.569834718    31.219637539    31.319370649    31.434285472    31.972367174    31.443043580
 stddev for time        ( +-  1.07% )   ( +-  0.13% )   ( +-  0.43% )   ( +-  0.18% )   ( +-  0.95% )   ( +-  0.58% )
 %chg time to baseline                  2.1%            2.4%            2.8%            4.58%           2.85%

Binutils build (make all -j64 )
minor-faults            474,821         371,380         269,463         247,715         235,255         228,337
times in seconds        53.882492432    53.584289348    53.882773216    53.755816431    53.607824348    53.423759642
 stddev for time        ( +-  0.08% )   ( +-  0.56% )   ( +-  0.17% )   ( +-  0.11% )   ( +-  0.60% )   ( +-  0.69% )
 %chg time to baseline                  -0.55%          0.0%            -0.23%          -0.51%          -0.85%

Two synthetic tests: access every word in file in sequential/random order.

Sequential access 16GiB file
FAULT_AROUND_ORDER      Baseline        1               3               4               5               8
1 thread
       minor-faults     263,148         131,166         32,908          16,514          8,260           1,093
       times in seconds 53.091138345    53.113191672    53.188776177    53.233017218    53.206841347    53.429979442
       stddev for time  ( +-  0.06% )   ( +-  0.07% )   ( +-  0.08% )   ( +-  0.09% )   ( +-  0.03% )   ( +-  0.03% )
       %chg time to baseline            0.04%           0.18%           0.26%           0.21%           0.63%
8 threads
       minor-faults     2,097,267       1,048,753       262,237         131,397         65,621          8,274
       times in seconds 55.173790028    54.591880790    54.824623287    54.802162211    54.969680503    54.790387715
       stddev for time  ( +-  0.78% )   ( +-  0.09% )   ( +-  0.08% )   ( +-  0.07% )   ( +-  0.28% )   ( +-  0.05% )
       %chg time to baseline            -1.05%          -0.63%          -0.67%          -0.36%          -0.69%
32 threads
       minor-faults     8,388,751       4,195,621       1,049,664       525,461         262,535         32,924
       times in seconds 60.431573046    60.669110744    60.485336388    60.697789706    60.077959564    60.588855032
       stddev for time  ( +-  0.44% )   ( +-  0.27% )   ( +-  0.46% )   ( +-  0.67% )   ( +-  0.31% )   ( +-  0.49% )
       %chg time to baseline            0.39%           0.08%           0.44%           -0.58%          0.25%
64 threads
       minor-faults     16,777,409      8,607,527       2,289,766       1,202,264       598,405         67,587
       times in seconds 96.932617720    100.675418760   102.109880836   103.881733383   102.580199555   105.751194041
       stddev for time  ( +-  1.39% )   ( +-  1.06% )   ( +-  0.99% )   ( +-  0.76% )   ( +-  1.65% )   ( +-  1.60% )
       %chg time to baseline            3.86%           5.34%           7.16%           5.82%           9.09%
128 threads
       minor-faults     33,554,705      17,375,375      4,682,462       2,337,245       1,179,007       134,819
       times in seconds 128.766704495   115.659225437   120.353046307   115.291871270   115.450886036   113.991902150
       stddev for time  ( +-  2.93% )   ( +-  0.30% )   ( +-  2.93% )   ( +-  1.24% )   ( +-  1.03% )   ( +-  0.70% )
       %chg time to baseline            -10.17%         -6.53%          -10.46%         -10.34%         -11.47%

Random access 1GiB file
FAULT_AROUND_ORDER      Baseline        1               3               4               5               8
1 thread
       minor-faults     17,155          8,678           2,126           1,097           581             134
       times in seconds 51.904430523    51.658017987    51.919270792    51.560531738    52.354431597    51.976469502
       stddev for time  ( +-  3.19% )   ( +-  1.35% )   ( +-  1.56% )   ( +-  0.91% )   ( +-  1.70% )   ( +-  2.02% )
       %chg time to baseline            -0.47%          0.02%           -0.66%          0.86%           0.13%
8 threads
       minor-faults     131,844         70,705          17,457          8,505           4,251           598
       times in seconds 58.162813956    54.991706305    54.952675791    55.323057492    54.755587379    53.376722828
       stddev for time  ( +-  1.44% )   ( +-  0.69% )   ( +-  1.23% )   ( +-  2.78% )   ( +-  1.90% )   ( +-  2.91% )
       %chg time to baseline            -5.45%          -5.52%          -4.88%          -5.86%          -8.22%
32 threads
       minor-faults     524,437         270,760         67,069          33,414          16,641          2,204
       times in seconds 69.981777072    76.539570015    79.753578505    76.245943618    77.254258344    79.072596831
       stddev for time  ( +-  2.81% )   ( +-  1.95% )   ( +-  2.66% )   ( +-  0.99% )   ( +-  2.35% )   ( +-  3.22% )
       %chg time to baseline            9.37%           13.96%          8.95%           10.39%          12.98%
64 threads
       minor-faults     1,049,117       527,451         134,016         66,638          33,391          4,559
       times in seconds 108.024517536   117.575067996   115.322659914   111.943998437   115.049450815   119.218450840
       stddev for time  ( +-  2.40% )   ( +-  1.77% )   ( +-  1.19% )   ( +-  3.29% )   ( +-  2.32% )   ( +-  1.42% )
       %chg time to baseline            8.84%           6.75%           3.62%           6.5%            10.3%
128 threads
       minor-faults     2,097,440       1,054,360       267,042         133,328         66,532          8,652
       times in seconds 155.055861167   153.059625968   152.449492156   151.024005282   150.844647770   155.954366718
       stddev for time  ( +-  1.32% )   ( +-  1.14% )   ( +-  1.32% )   ( +-  0.81% )   ( +-  0.75% )   ( +-  0.72% )
       %chg time to baseline            -1.28%          -1.68%          -2.59%          -2.71%          0.57%

In case of kernel build, fault around order (fao) value of 1 and 3 wins when compared to 4 (but bit noisy).
Incase of kernel rebuild, slowdown for fao > 0 is seen. Incase of synthetic test, there are sporadic agains, but mostly
slowdown. No clear sweet spot fao value that can be suggested for the ppc64/pseries with the current
performance data. Hence, patch suggest value of zero to the fao.

Worst case scenario: we touch one page every 16M to demonstrate overhead.

Touch only one page in page table in 16GiB file
FAULT_AROUND_ORDER      Baseline        1               3               4               5               8
1 thread
       minor-faults     1,104           1,090           1,071           1,068           1,065           1,063
       times in seconds 0.006583298     0.008531502     0.019733795     0.036033763     0.062300553     0.406857086
       stddev for time  ( +-  2.79% )   ( +-  2.42% )   ( +-  3.47% )   ( +-  2.81% )   ( +-  2.01% )   ( +-  1.33% )
8 threads
       minor-faults     8,279           8,264           8,245           8,243           8,239           8,240
       times in seconds 0.044572398     0.057211811     0.107606306     0.205626815     0.381679120     2.647979955
       stddev for time  ( +-  1.95% )   ( +-  2.98% )   ( +-  1.74% )   ( +-  2.80% )   ( +-  2.01% )   ( +-  1.86% )
32 threads
       minor-faults     32,879          32,864          32,849          32,845          32,839          32,843
       times in seconds 0.197659343     0.218486087     0.445116407     0.694235883     1.296894038     9.127517045
       stddev for time  ( +-  3.05% )   ( +-  3.05% )   ( +-  4.33% )   ( +-  3.08% )   ( +-  3.75% )   ( +-  0.56% )
64 threads
       minor-faults     65,680          65,664          65,646          65,645          65,640          65,647
       times in seconds 0.455537304     0.489688780     0.866490093     1.427393118     2.379628982     17.059295051
       stddev for time  ( +-  4.01% )   ( +-  4.13% )   ( +-  2.92% )   ( +-  1.68% )   ( +-  1.79% )   ( +-  0.48% )
128 threads
       minor-faults     131,279         131,265         131,250         131,245         131,241         131,254
       times in seconds 1.026880651     1.095327536     1.721728274     2.808233068     4.662729948     31.732848290
       stddev for time  ( +-  6.85% )   ( +-  4.09% )   ( +-  1.71% )   ( +-  3.45% )   ( +-  2.40% )   ( +-  0.68% )

Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/pseries.h |    2 ++
 arch/powerpc/platforms/pseries/setup.c   |    5 +++++
 2 files changed, 7 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 9921953..6e6c993 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -17,6 +17,8 @@ struct device_node;
 extern void request_event_sources_irqs(struct device_node *np,
 				       irq_handler_t handler, const char *name);
 
+extern unsigned int fault_around_order;
+
 #include <linux/of.h>
 
 extern void __init fw_hypertas_feature_init(const char *hypertas,
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 2db8cc6..4391c3c 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -465,6 +465,11 @@ static void __init pSeries_setup_arch(void)
 {
 	set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
 
+	/*
+	 * Defaulting to zero since no sweet spot value found in the performance test.
+	 */
+	fault_around_order = 0;
+
 	/* Discover PIC type and setup ppc_md accordingly */
 	pseries_discover_pic();
 
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH V4 1/2] mm: move FAULT_AROUND_ORDER to arch/
From: Madhavan Srinivasan @ 2014-05-08  9:28 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, linux-mm, linux-arch, x86
  Cc: riel, ak, peterz, rusty, dave.hansen, Madhavan Srinivasan, paulus,
	mgorman, akpm, mingo, kirill.shutemov
In-Reply-To: <1399541296-18810-1-git-send-email-maddy@linux.vnet.ibm.com>

Kirill A. Shutemov with 8c6e50b029 commit introduced
vm_ops->map_pages() for mapping easy accessible pages around
fault address in hope to reduce number of minor page faults.

This patch creates infrastructure to modify the FAULT_AROUND_ORDER
value using mm/Kconfig. This will enable architecture maintainers
to decide on suitable FAULT_AROUND_ORDER value based on
performance data for that architecture. Patch also defaults
FAULT_AROUND_ORDER Kconfig element to 4.

Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
 mm/Kconfig  |    8 ++++++++
 mm/memory.c |   25 ++++++-------------------
 2 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/mm/Kconfig b/mm/Kconfig
index ebe5880..c7fc4f1 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -176,6 +176,14 @@ config MOVABLE_NODE
 config HAVE_BOOTMEM_INFO_NODE
 	def_bool n
 
+#
+# Fault around order is a control knob to decide the fault around pages.
+# Default value is set to 4 , but the arch can override it as desired.
+#
+config FAULT_AROUND_ORDER
+	int
+	default	4
+
 # eventually, we can have this option just 'select SPARSEMEM'
 config MEMORY_HOTPLUG
 	bool "Allow for memory hot-add"
diff --git a/mm/memory.c b/mm/memory.c
index 037b812..e3931ef 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3402,11 +3402,9 @@ void do_set_pte(struct vm_area_struct *vma, unsigned long address,
 	update_mmu_cache(vma, address, pte);
 }
 
-#define FAULT_AROUND_ORDER 4
+unsigned int fault_around_order __read_mostly = CONFIG_FAULT_AROUND_ORDER;
 
 #ifdef CONFIG_DEBUG_FS
-static unsigned int fault_around_order = FAULT_AROUND_ORDER;
-
 static int fault_around_order_get(void *data, u64 *val)
 {
 	*val = fault_around_order;
@@ -3415,7 +3413,6 @@ static int fault_around_order_get(void *data, u64 *val)
 
 static int fault_around_order_set(void *data, u64 val)
 {
-	BUILD_BUG_ON((1UL << FAULT_AROUND_ORDER) > PTRS_PER_PTE);
 	if (1UL << val > PTRS_PER_PTE)
 		return -EINVAL;
 	fault_around_order = val;
@@ -3435,31 +3432,21 @@ static int __init fault_around_debugfs(void)
 	return 0;
 }
 late_initcall(fault_around_debugfs);
+#endif
 
 static inline unsigned long fault_around_pages(void)
 {
-	return 1UL << fault_around_order;
-}
-
-static inline unsigned long fault_around_mask(void)
-{
-	return ~((1UL << (PAGE_SHIFT + fault_around_order)) - 1);
-}
-#else
-static inline unsigned long fault_around_pages(void)
-{
 	unsigned long nr_pages;
 
-	nr_pages = 1UL << FAULT_AROUND_ORDER;
-	BUILD_BUG_ON(nr_pages > PTRS_PER_PTE);
+	nr_pages = 1UL << fault_around_order;
+	VM_BUG_ON(nr_pages > PTRS_PER_PTE);
 	return nr_pages;
 }
 
 static inline unsigned long fault_around_mask(void)
 {
-	return ~((1UL << (PAGE_SHIFT + FAULT_AROUND_ORDER)) - 1);
+	return ~((1UL << (PAGE_SHIFT + fault_around_order)) - 1);
 }
-#endif
 
 static void do_fault_around(struct vm_area_struct *vma, unsigned long address,
 		pte_t *pte, pgoff_t pgoff, unsigned int flags)
@@ -3515,7 +3502,7 @@ static int do_read_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	 * if page by the offset is not ready to be mapped (cold cache or
 	 * something).
 	 */
-	if (vma->vm_ops->map_pages) {
+	if ((vma->vm_ops->map_pages) && fault_around_order) {
 		pte = pte_offset_map_lock(mm, pmd, address, &ptl);
 		do_fault_around(vma, address, pte, pgoff, flags);
 		if (!pte_same(*pte, orig_pte))
-- 
1.7.10.4

^ permalink raw reply related

* Re: [PATCH RFC v12 3/7] dma: mpc512x: add support for peripheral transfers
From: Alexander Popov @ 2014-05-08  9:49 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Lars-Peter Clausen, Arnd Bergmann, Gerhard Sittig,
	Andy Shevchenko, Alexander Popov, dmaengine, Dan Williams,
	Anatolij Gustschin, linuxppc-dev
In-Reply-To: <20140502170333.GJ32284@intel.com>

Hello, Vinod.
Thanks for your feedback.

2014-05-02 21:03 GMT+04:00 Vinod Koul <vinod.koul@intel.com>:
> On Wed, Apr 23, 2014 at 05:53:25PM +0400, Alexander Popov wrote:
>> +static struct dma_async_tx_descriptor *
>> +mpc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
>> +             unsigned int sg_len, enum dma_transfer_direction direction,
>> +             unsigned long flags, void *context)
>> +{
>> +     struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan);
>> +     struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan);
>> +     struct mpc_dma_desc *mdesc = NULL;
>> +     dma_addr_t per_paddr;
>> +     u32 tcd_nunits;
>> +     struct mpc_dma_tcd *tcd;
>> +     unsigned long iflags;
>> +     struct scatterlist *sg;
>> +     size_t len;
>> +     int iter, i;
>> +
>> +     /* Currently there is no proper support for scatter/gather */
> Why? Is this HW or SW limitation?
This is the software limitation.

As Gerhard noticed, unfortunately the Linux DMA API combines
peripheral access with scatter/gather function.

But the original MPC512x DMA driver already uses scatter/gather feature
of the hardware for chaining together individual mpc_dma_desc's
in mpc_dma_execute() while mpc_dma_desc itself cannot use
scatter/gather feature, because each mpc_dma_desc is associated
with exactly one mpc_dma_tcd.

>> +             if (direction == DMA_DEV_TO_MEM) {
>> +                     tcd->saddr = per_paddr;
>> +                     tcd->daddr = sg_dma_address(sg);
>> +                     tcd->soff = 0;
>> +                     tcd->doff = 4;
> what are these?
SOFF is source address signed offset. It is applied to the current
source address to form the next-state value as each source read is completed.
DOFF is destination address signed offset.

>> +     case DMA_TERMINATE_ALL:
>> +             /* Disable channel requests */
>> +             mdma = dma_chan_to_mpc_dma(chan);
>> +
>> +             spin_lock_irqsave(&mchan->lock, flags);
>> +
>> +             out_8(&mdma->regs->dmacerq, chan->chan_id);
>> +             list_splice_tail_init(&mchan->prepared, &mchan->free);
>> +             list_splice_tail_init(&mchan->queued, &mchan->free);
>> +             list_splice_tail_init(&mchan->active, &mchan->free);
>> +
>> +             spin_unlock_irqrestore(&mchan->lock, flags);
>> +
>> +             return 0;
> empty line after this pls
ok

>> +     case DMA_SLAVE_CONFIG:
>> +             /*
>> +              * Constraints:
>> +              *  - only transfers between a peripheral device and
>> +              *     memory are supported;
>> +              *  - minimal transfer chunk is 4 bytes and consequently
>> +              *     source and destination addresses must be 4-byte aligned
>> +              *     and transfer size must be aligned on (4 * maxburst)
>> +              *     boundary;
>> +              *  - during the transfer RAM address is being incremented by
>> +              *     the size of minimal transfer chunk;
>> +              *  - peripheral port's address is constant during the transfer.
>> +              */
>> +
>> +             cfg = (void *)arg;
>> +
>> +             if (cfg->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES ||
>> +                 cfg->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES ||
> and why this limtation, doesnt seem covered above?
I created this limitation because FIFO registers of LPC and SDHC
support _only_ 4-byte access.

I tried to cover this limitation in the statement "minimal transfer chunk
is 4 bytes". Should I make it more explicit?

>> +                 !IS_ALIGNED(cfg->src_addr, 4) ||
>> +                 !IS_ALIGNED(cfg->dst_addr, 4)) {
>> +                     return -EINVAL;
>> +             }
>> +
>> +             spin_lock_irqsave(&mchan->lock, flags);
>> +
>> +             mchan->src_per_paddr = cfg->src_addr;
>> +             mchan->src_tcd_nunits = cfg->src_maxburst;
>> +             mchan->dst_per_paddr = cfg->dst_addr;
>> +             mchan->dst_tcd_nunits = cfg->dst_maxburst;
>> +
>> +             /* Apply defaults */
>> +             if (mchan->src_tcd_nunits == 0)
>> +                     mchan->src_tcd_nunits = 1;
>> +             if (mchan->dst_tcd_nunits == 0)
>> +                     mchan->dst_tcd_nunits = 1;
>> +
>> +             spin_unlock_irqrestore(&mchan->lock, flags);
>> +
>> +             return 0;
> empty line here too
ok

Best regards,
Alexander

^ permalink raw reply

* Re: [PATCH v4 8/8] DMA: Freescale: add suspend resume functions for DMA driver
From: Hongbo Zhang @ 2014-05-08  9:52 UTC (permalink / raw)
  To: Shevchenko, Andriy
  Cc: dmaengine@vger.kernel.org, leo.li@freescale.com, Koul, Vinod,
	linux-kernel@vger.kernel.org, vkoul@infradead.org,
	scottwood@freescale.com, Williams, Dan J,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1399451493.2677.11.camel@smile.fi.intel.com>


On 05/07/2014 04:31 PM, Shevchenko, Andriy wrote:
> On Sun, 2014-05-04 at 18:22 +0800, Hongbo Zhang wrote:
>> On 05/03/2014 12:46 AM, Vinod Koul wrote:
>>> On Fri, Apr 18, 2014 at 04:17:51PM +0800, hongbo.zhang@freescale.com wrote:
>>>> From: Hongbo Zhang <hongbo.zhang@freescale.com>
>>>>
>>>> This patch adds suspend resume functions for Freescale DMA driver.
>>>> .prepare callback is used to stop further descriptors from being added into the
>>>> pending queue, and also issue pending queues into execution if there is any.
>>>> .suspend callback makes sure all the pending jobs are cleaned up and all the
>>>> channels are idle, and save the mode registers.
>>>> .resume callback re-initializes the channels by restore the mode registers.
>>>>
>>>> +
>>>> +static const struct dev_pm_ops fsldma_pm_ops = {
>>>> +	.prepare	= fsldma_prepare,
>>>> +	.suspend	= fsldma_suspend,
>>>> +	.resume		= fsldma_resume,
>>>> +};
>>> I think this is not correct. We discussed this sometime back on list. The
>>> DMAengine drivers should use late resume and early suspend to ensure they get
>>> suspended after clients (who should use normal ones) and resume before them
>>>
>> OK, will update it like this:
>> use .suspend to take place of current .prepare
> Could you remove this at all?
>
> Answering to your previous statements I could say that.
> Device drivers (DMAc users) that don't implement .suspend callback are
> on their own with troubles, you have not to care about them in the DMA
> driver.

Thanks for pointing out this issue.
Then how to handle the descriptors in the pending list if there is any?
a. let them finished.
     but if the DMA user has already suspended prior DMA controller, it 
is meaningless somehow and may even ask for trouble.
b. don't touch them.
     after resume these pending descriptors could be executed, it is 
also meaningless because the resumed DMA user may in different state 
from before being suspended.
c. delete them.
     should we do this? is is a bit crude?
d. return a non-success value
     then the whole suspend process is reversed, e.g. suspend fails.
I've looked through some dma drivers, most of them is in case b.

>> use .suspend_late to take place of current .suspend
>> use .resume_early to take place of current .resume
>>
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe dmaengine" 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 v4 6/8] DMA: Freescale: change descriptor release process for supporting async_tx
From: Hongbo Zhang @ 2014-05-08 10:03 UTC (permalink / raw)
  To: Vinod Koul, dan.j.williams
  Cc: leo.li, vkoul, linux-kernel, scottwood, dmaengine, linuxppc-dev
In-Reply-To: <20140502165053.GH32284@intel.com>


On 05/03/2014 12:50 AM, Vinod Koul wrote:
> On Fri, Apr 18, 2014 at 04:17:49PM +0800, hongbo.zhang@freescale.com wrote:
>
> This need review from Dan ...
>
Dan, could you please have a look at this? thanks.

^ permalink raw reply

* Re: [PATCH V5] KVM: PPC: BOOK3S: Use the saved dar value and generic make_dsisr
From: Alexander Graf @ 2014-05-08 10:06 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: paulus, linuxppc-dev, kvm-ppc, kvm
In-Reply-To: <1399386622-21407-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com>

On 05/06/2014 04:30 PM, Aneesh Kumar K.V wrote:
> Although it's optional IBM POWER cpus always had DAR value set on
> alignment interrupt. So don't try to compute these values.
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

The patch body is fine now. The commit message however is not. The patch 
does two things:

   * Merge DSISR calculation with Linux's implementation
   * Use the real DAR on book3s_64 alignment interrupts

In fact, you probably should make this 2 patches.


Alex

^ permalink raw reply

* Re: [PATCH V2] KVM: PPC: BOOK3S: HV: Prefer CMA region for hash page table allocation
From: Alexander Graf @ 2014-05-08 10:11 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: paulus, linuxppc-dev, kvm-ppc, kvm
In-Reply-To: <1399391658-1308-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com>

On 05/06/2014 05:54 PM, Aneesh Kumar K.V wrote:
> Today when KVM tries to reserve memory for the hash page table it
> allocates from the normal page allocator first. If that fails it
> falls back to CMA's reserved region. One of the side effects of
> this is that we could end up exhausting the page allocator and
> get linux into OOM conditions while we still have plenty of space
> available in CMA.
>
> This patch addresses this issue by first trying hash page table
> allocation from CMA's reserved region before falling back to the normal
> page allocator. So if we run out of memory, we really are out of memory.
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

Thanks, applied to kvm-ppc-queue.


Alex

^ permalink raw reply

* Re: [PATCH V2] KVM: PPC: BOOK3S: HV: Add mixed page-size support for guest
From: Alexander Graf @ 2014-05-08 10:12 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: paulus, linuxppc-dev, kvm-ppc, kvm
In-Reply-To: <1399399296-17711-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com>

On 05/06/2014 08:01 PM, Aneesh Kumar K.V wrote:
> On recent IBM Power CPUs, while the hashed page table is looked up using
> the page size from the segmentation hardware (i.e. the SLB), it is
> possible to have the HPT entry indicate a larger page size.  Thus for
> example it is possible to put a 16MB page in a 64kB segment, but since
> the hash lookup is done using a 64kB page size, it may be necessary to
> put multiple entries in the HPT for a single 16MB page.  This
> capability is called mixed page-size segment (MPSS).  With MPSS,
> there are two relevant page sizes: the base page size, which is the
> size used in searching the HPT, and the actual page size, which is the
> size indicated in the HPT entry. [ Note that the actual page size is
> always >= base page size ].
>
> We use "ibm,segment-page-sizes" device tree node to advertise
> the MPSS support to PAPR guest. The penc encoding indicates whether
> we support a specific combination of base page size and actual
> page size in the same segment. We also use the penc value in the
> LP encoding of HPTE entry.
>
> This patch exposes MPSS support to KVM guest by advertising the
> feature via "ibm,segment-page-sizes". It also adds the necessary changes
> to decode the base page size and the actual page size correctly from the
> HPTE entry.
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

Thanks, applied to kvm-ppc-queue.


Alex

^ permalink raw reply

* [PATCH] net: get rid of SET_ETHTOOL_OPS
From: Wilfried Klaebe @ 2014-05-08 11:53 UTC (permalink / raw)
  To: netdev
  Cc: Nandini Hanumanthagowda, Sarah Sharp, Anders Larsen,
	Nicolas Ferre, Rasesh Mody, Andreas Herrmann, K. Y. Srinivasan,
	Aaron Marburg, Andy Gospodarek, Roland Stigge, Wei Yongjun,
	Aaro Koskinen, Sathya Perla, Jingoo Han, Manish Chopra,
	Luka Perkov, Pravin B Shelar, Jan Dumon, Jeff Kirsher,
	Arend van Spriel, xen-devel, Alex Duyck, Mugunthan V N,
	wangweidong, Peter Senna Tschudin, Girish K S, Jesse Gross,
	Frank Blaschka, Rob Herring, Libo Chen, Jonas Gorski,
	Antonio Quartulli, Nathan Hintz, Ben Hutchings, Nobuhiro Iwamatsu,
	Christian Riesch, Wei Liu, Neil Horman, Sergei Shtylyov,
	Alexandre Bounine, Dept-HSGLinuxNICDev, linux-usb, linux-wireless,
	Hyong-Youb Kim, H Hartley Sweeten, Greg Kroah-Hartman,
	linux-driver, Andrew Morton, Sorbica Shieh, Christian Benvenuti,
	b.a.t.m.a.n, Marek Lindner, Chris Snook, Denis Kirjanov,
	virtualization, Eric Dumazet, Santosh Raspatur, Himangi Saraogi,
	Shradha Shah, Casey Leedom, Gary Zambrano, Tushar Behera,
	Vipul Pandya, linux-s390, Eric W. Biederman, Don Skidmore,
	Rafał Miłecki, Amir Vadai, Jesse Brandeburg,
	Julian Anastasov, Ariel Elior, Tobias Klauser,
	Govindarajulu Varadarajan, Ben Boeckel, Shahed Shaikh, Jon Mason,
	Sony Chacko, Joe Perches, John Greene, devel, Giuseppe Cavallaro,
	Boris Ostrovsky, Subbu Seetharaman, Justin van Wijngaarden,
	Mirko Lindner, Thomas Petazzoni, Iulia Manda, Julia Lawall,
	Neel Patel, Bruce Allan, e1000-devel, Rajesh Borundia,
	David Vrabel, Martin Schwidefsky, linux390, dev, Archana kumari,
	Mike Rapoport, bridge, Petko Manolov, Simon Horman,
	Siva Reddy Kallam, Jason Wang, Dimitris Michailidis,
	Heiko Carstens, Paul Gortmaker, Maxime Bizon, Cong Wang,
	Sujith Sankar, Florian Fainelli, Sabrina Dubroca, linux-rdma,
	Tony Lindgren, Alexander Gordeev, Francois Romieu, Grant Likely,
	hayeswang, Jay Cliburn, Rusty Russell, Byungho An, Grant Grundler,
	Haiyang Zhang, Mitch Williams, Ajit Khaparde, Petri Gynther,
	hahnjo, Ron Mercer, Thadeu Lima de Souza Cascardo, trivial,
	Hauke Mehrtens, Marek Belisko, Lad, Prabhakar, Felipe Balbi,
	Daniel Mack, Mark Einon, David S. Miller, Nishanth Menon,
	Daniel Dodge, Michael S. Tsirkin, VMware, Inc., Shreyas Bhatewara,
	Ursula Braun, Masanari Iida, Zhao, Gang, Yijing Wang,
	Carolyn Wyborny, Peter Hüwe, Ivan Vecera, Laurent Pinchart,
	linux-acenic, Isaku Yamahata, Lubomir Rintel, Ben Dooks,
	dingtianhong, Or Gerlitz, Nishank Trivedi, Sebastian Hesselbarth,
	devel, Realtek linux nic maintainers, Linux NICS, Ian Campbell,
	Konrad Rzeszutek Wilk, Jouni Malinen, Greg Rose, Markus Pargmann,
	Andy Shevchenko, Jitendra Kalsaria, Alan Cox,
	Solarflare linux maintainers, Simon Wunderlich, Stephen Hemminger,
	Daniel Borkmann, John Ronciak, nios2-dev, Johannes Berg,
	linuxppc-dev, Bjørn Mork

Dave Miller mentioned he'd like to see SET_ETHTOOL_OPS gone.
This does that.

Compile tested only, but I'd seriously wonder if this broke anything.

Suggested-by: Dave Miller <davem@davemloft.net>
Signed-off-by: Wilfried Klaebe <w-lkml@lebenslange-mailadresse.de>

---

Applies against v3.15-rc4.

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
index c4b3940..078cadd 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
@@ -105,5 +105,5 @@ static const struct ethtool_ops ipoib_ethtool_ops = {
 
 void ipoib_set_ethtool_ops(struct net_device *dev)
 {
-	SET_ETHTOOL_OPS(dev, &ipoib_ethtool_ops);
+	dev->ethtool_ops = &ipoib_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/3com/3c509.c b/drivers/net/ethernet/3com/3c509.c
index 35df0b9..a968654 100644
--- a/drivers/net/ethernet/3com/3c509.c
+++ b/drivers/net/ethernet/3com/3c509.c
@@ -534,7 +534,7 @@ static int el3_common_init(struct net_device *dev)
 	/* The EL3-specific entries in the device structure. */
 	dev->netdev_ops = &netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
-	SET_ETHTOOL_OPS(dev, &ethtool_ops);
+	dev->ethtool_ops = &ethtool_ops;
 
 	err = register_netdev(dev);
 	if (err) {
diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c
index 063557e..f18647c 100644
--- a/drivers/net/ethernet/3com/3c589_cs.c
+++ b/drivers/net/ethernet/3com/3c589_cs.c
@@ -218,7 +218,7 @@ static int tc589_probe(struct pcmcia_device *link)
 	dev->netdev_ops = &el3_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
-	SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+	dev->ethtool_ops = &netdev_ethtool_ops;
 
 	return tc589_config(link);
 }
diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c
index 465cc71..e13b046 100644
--- a/drivers/net/ethernet/3com/typhoon.c
+++ b/drivers/net/ethernet/3com/typhoon.c
@@ -2435,7 +2435,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netif_napi_add(dev, &tp->napi, typhoon_poll, 16);
 	dev->watchdog_timeo	= TX_TIMEOUT;
 
-	SET_ETHTOOL_OPS(dev, &typhoon_ethtool_ops);
+	dev->ethtool_ops = &typhoon_ethtool_ops;
 
 	/* We can handle scatter gather, up to 16 entries, and
 	 * we can do IP checksumming (only version 4, doh...)
diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c
index 171d73c..40dbbf7 100644
--- a/drivers/net/ethernet/adaptec/starfire.c
+++ b/drivers/net/ethernet/adaptec/starfire.c
@@ -784,7 +784,7 @@ static int starfire_init_one(struct pci_dev *pdev,
 
 	dev->netdev_ops = &netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
-	SET_ETHTOOL_OPS(dev, &ethtool_ops);
+	dev->ethtool_ops = &ethtool_ops;
 
 	netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work);
 
diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c
index 1517e9df..9a6991b 100644
--- a/drivers/net/ethernet/alteon/acenic.c
+++ b/drivers/net/ethernet/alteon/acenic.c
@@ -476,7 +476,7 @@ static int acenic_probe_one(struct pci_dev *pdev,
 	dev->watchdog_timeo = 5*HZ;
 
 	dev->netdev_ops = &ace_netdev_ops;
-	SET_ETHTOOL_OPS(dev, &ace_ethtool_ops);
+	dev->ethtool_ops = &ace_ethtool_ops;
 
 	/* we only display this string ONCE */
 	if (!boards_found)
diff --git a/drivers/net/ethernet/altera/altera_tse_ethtool.c b/drivers/net/ethernet/altera/altera_tse_ethtool.c
index 319ca74..8ac4bd2 100644
--- a/drivers/net/ethernet/altera/altera_tse_ethtool.c
+++ b/drivers/net/ethernet/altera/altera_tse_ethtool.c
@@ -231,5 +231,5 @@ static const struct ethtool_ops tse_ethtool_ops = {
 
 void altera_tse_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &tse_ethtool_ops);
+	netdev->ethtool_ops = &tse_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index 26efaaa..068dc7c 100644
--- a/drivers/net/ethernet/amd/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -1900,7 +1900,7 @@ static int amd8111e_probe_one(struct pci_dev *pdev,
 
 	/* Initialize driver entry points */
 	dev->netdev_ops = &amd8111e_netdev_ops;
-	SET_ETHTOOL_OPS(dev, &ops);
+	dev->ethtool_ops = &ops;
 	dev->irq =pdev->irq;
 	dev->watchdog_timeo = AMD8111E_TX_TIMEOUT;
 	netif_napi_add(dev, &lp->napi, amd8111e_rx_poll, 32);
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index a2bd91e..a78e4c1 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -1229,7 +1229,7 @@ static int au1000_probe(struct platform_device *pdev)
 	dev->base_addr = base->start;
 	dev->irq = irq;
 	dev->netdev_ops = &au1000_netdev_ops;
-	SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
+	dev->ethtool_ops = &au1000_ethtool_ops;
 	dev->watchdog_timeo = ETH_TX_TIMEOUT;
 
 	/*
diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c
index 08569fe..abf3b15 100644
--- a/drivers/net/ethernet/amd/nmclan_cs.c
+++ b/drivers/net/ethernet/amd/nmclan_cs.c
@@ -457,7 +457,7 @@ static int nmclan_probe(struct pcmcia_device *link)
     lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
 
     dev->netdev_ops = &mace_netdev_ops;
-    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+    dev->ethtool_ops = &netdev_ethtool_ops;
     dev->watchdog_timeo = TX_TIMEOUT;
 
     return nmclan_config(link);
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
index 17bb9ce..49faa97 100644
--- a/drivers/net/ethernet/atheros/alx/main.c
+++ b/drivers/net/ethernet/atheros/alx/main.c
@@ -1302,7 +1302,7 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	netdev->netdev_ops = &alx_netdev_ops;
-	SET_ETHTOOL_OPS(netdev, &alx_ethtool_ops);
+	netdev->ethtool_ops = &alx_ethtool_ops;
 	netdev->irq = pdev->irq;
 	netdev->watchdog_timeo = ALX_WATCHDOG_TIME;
 
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
index 859ea84..ecacaae 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
@@ -305,5 +305,5 @@ static const struct ethtool_ops atl1c_ethtool_ops = {
 
 void atl1c_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &atl1c_ethtool_ops);
+	netdev->ethtool_ops = &atl1c_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c
index 82b2386..206e9b7 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c
@@ -388,5 +388,5 @@ static const struct ethtool_ops atl1e_ethtool_ops = {
 
 void atl1e_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &atl1e_ethtool_ops);
+	netdev->ethtool_ops = &atl1e_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c
index 78befb5..2587fed 100644
--- a/drivers/net/ethernet/atheros/atlx/atl2.c
+++ b/drivers/net/ethernet/atheros/atlx/atl2.c
@@ -1396,7 +1396,7 @@ static int atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	atl2_setup_pcicmd(pdev);
 
 	netdev->netdev_ops = &atl2_netdev_ops;
-	SET_ETHTOOL_OPS(netdev, &atl2_ethtool_ops);
+	netdev->ethtool_ops = &atl2_ethtool_ops;
 	netdev->watchdog_timeo = 5 * HZ;
 	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index 05ba625..ca5a20a 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -2380,7 +2380,7 @@ static int b44_init_one(struct ssb_device *sdev,
 	netif_napi_add(dev, &bp->napi, b44_poll, 64);
 	dev->watchdog_timeo = B44_TX_TIMEOUT;
 	dev->irq = sdev->irq;
-	SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
+	dev->ethtool_ops = &b44_ethtool_ops;
 
 	err = ssb_bus_powerup(sdev->bus, 0);
 	if (err) {
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index a7d11f5..1e7bba9c 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1898,7 +1898,7 @@ static int bcm_enet_probe(struct platform_device *pdev)
 	dev->netdev_ops = &bcm_enet_ops;
 	netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
 
-	SET_ETHTOOL_OPS(dev, &bcm_enet_ethtool_ops);
+	dev->ethtool_ops = &bcm_enet_ethtool_ops;
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	ret = register_netdev(dev);
@@ -2784,7 +2784,7 @@ static int bcm_enetsw_probe(struct platform_device *pdev)
 	/* register netdevice */
 	dev->netdev_ops = &bcm_enetsw_ops;
 	netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
-	SET_ETHTOOL_OPS(dev, &bcm_enetsw_ethtool_ops);
+	dev->ethtool_ops = &bcm_enetsw_ethtool_ops;
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	spin_lock_init(&priv->enetsw_mdio_lock);
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index 0297a79..05c6af6 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -1436,7 +1436,7 @@ static int bgmac_probe(struct bcma_device *core)
 		return -ENOMEM;
 	net_dev->netdev_ops = &bgmac_netdev_ops;
 	net_dev->irq = core->irq;
-	SET_ETHTOOL_OPS(net_dev, &bgmac_ethtool_ops);
+	net_dev->ethtool_ops = &bgmac_ethtool_ops;
 	bgmac = netdev_priv(net_dev);
 	bgmac->net_dev = net_dev;
 	bgmac->core = core;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index b6de05e..0322409 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -3506,8 +3506,6 @@ static const struct ethtool_ops bnx2x_vf_ethtool_ops = {
 
 void bnx2x_set_ethtool_ops(struct bnx2x *bp, struct net_device *netdev)
 {
-	if (IS_PF(bp))
-		SET_ETHTOOL_OPS(netdev, &bnx2x_ethtool_ops);
-	else /* vf */
-		SET_ETHTOOL_OPS(netdev, &bnx2x_vf_ethtool_ops);
+	netdev->ethtool_ops = (IS_PF(bp)) ?
+		&bnx2x_ethtool_ops : &bnx2x_vf_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 0966bd0..5ba1cfb 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -2481,7 +2481,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
 	dev_set_drvdata(&pdev->dev, dev);
 	ether_addr_copy(dev->dev_addr, macaddr);
 	dev->watchdog_timeo = 2 * HZ;
-	SET_ETHTOOL_OPS(dev, &bcmgenet_ethtool_ops);
+	dev->ethtool_ops = &bcmgenet_ethtool_ops;
 	dev->netdev_ops = &bcmgenet_netdev_ops;
 	netif_napi_add(dev, &priv->napi, bcmgenet_poll, 64);
 
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index f9e1508..adca62b 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -1137,5 +1137,5 @@ static const struct ethtool_ops bnad_ethtool_ops = {
 void
 bnad_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &bnad_ethtool_ops);
+	netdev->ethtool_ops = &bnad_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 521dfea..25d6b2a 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -1737,7 +1737,7 @@ static int xgmac_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, ndev);
 	ether_setup(ndev);
 	ndev->netdev_ops = &xgmac_netdev_ops;
-	SET_ETHTOOL_OPS(ndev, &xgmac_ethtool_ops);
+	ndev->ethtool_ops = &xgmac_ethtool_ops;
 	spin_lock_init(&priv->stats_lock);
 	INIT_WORK(&priv->tx_timeout_work, xgmac_tx_timeout_work);
 
diff --git a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
index 0fe7ff7..c1b2c1d 100644
--- a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
+++ b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
@@ -1100,7 +1100,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 		netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
 
-		SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
+		netdev->ethtool_ops = &t1_ethtool_ops;
 	}
 
 	if (t1_init_sw_modules(adapter, bi) < 0) {
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
index 07bbb71..3ed5079 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
@@ -3291,7 +3291,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 			netdev->features |= NETIF_F_HIGHDMA;
 
 		netdev->netdev_ops = &cxgb_netdev_ops;
-		SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
+		netdev->ethtool_ops = &cxgb_ethtool_ops;
 	}
 
 	pci_set_drvdata(pdev, adapter);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 6fe5891..7c61f89 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -6074,7 +6074,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		netdev->priv_flags |= IFF_UNICAST_FLT;
 
 		netdev->netdev_ops = &cxgb4_netdev_ops;
-		SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
+		netdev->ethtool_ops = &cxgb_ethtool_ops;
 	}
 
 	pci_set_drvdata(pdev, adapter);
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index 5285928..ff1cdd1 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -2664,7 +2664,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
 		netdev->priv_flags |= IFF_UNICAST_FLT;
 
 		netdev->netdev_ops = &cxgb4vf_netdev_ops;
-		SET_ETHTOOL_OPS(netdev, &cxgb4vf_ethtool_ops);
+		netdev->ethtool_ops = &cxgb4vf_ethtool_ops;
 
 		/*
 		 * Initialize the hardware/software state for the port.
diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
index 47e3562..58a8c67 100644
--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
+++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
@@ -253,5 +253,5 @@ static const struct ethtool_ops enic_ethtool_ops = {
 
 void enic_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &enic_ethtool_ops);
+	netdev->ethtool_ops = &enic_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index 1642de7..8616608 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -1703,7 +1703,7 @@ static int tulip_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 #ifdef CONFIG_TULIP_NAPI
 	netif_napi_add(dev, &tp->napi, tulip_poll, 16);
 #endif
-	SET_ETHTOOL_OPS(dev, &ops);
+	dev->ethtool_ops = &ops;
 
 	if (register_netdev(dev))
 		goto err_out_free_ring;
diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
index 4fb756d..2324f2d 100644
--- a/drivers/net/ethernet/dlink/dl2k.c
+++ b/drivers/net/ethernet/dlink/dl2k.c
@@ -227,7 +227,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 	dev->netdev_ops = &netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
-	SET_ETHTOOL_OPS(dev, &ethtool_ops);
+	dev->ethtool_ops = &ethtool_ops;
 #if 0
 	dev->features = NETIF_F_IP_CSUM;
 #endif
diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c
index d9e5ca0..433c1e1 100644
--- a/drivers/net/ethernet/dlink/sundance.c
+++ b/drivers/net/ethernet/dlink/sundance.c
@@ -577,7 +577,7 @@ static int sundance_probe1(struct pci_dev *pdev,
 
 	/* The chip-specific entries in the device structure. */
 	dev->netdev_ops = &netdev_ops;
-	SET_ETHTOOL_OPS(dev, &ethtool_ops);
+	dev->ethtool_ops = &ethtool_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	pci_set_drvdata(pdev, dev);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a186454..9a9e7c7 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -4301,7 +4301,7 @@ static void be_netdev_init(struct net_device *netdev)
 
 	netdev->netdev_ops = &be_netdev_ops;
 
-	SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
+	netdev->ethtool_ops = &be_ethtool_ops;
 }
 
 static void be_unmap_pci_bars(struct be_adapter *adapter)
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index 68069ea..c77fa4a 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -1210,7 +1210,7 @@ static int ftgmac100_probe(struct platform_device *pdev)
 
 	SET_NETDEV_DEV(netdev, &pdev->dev);
 
-	SET_ETHTOOL_OPS(netdev, &ftgmac100_ethtool_ops);
+	netdev->ethtool_ops = &ftgmac100_ethtool_ops;
 	netdev->netdev_ops = &ftgmac100_netdev_ops;
 	netdev->features = NETIF_F_IP_CSUM | NETIF_F_GRO;
 
diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c
index 8be5b40..4ff1adc 100644
--- a/drivers/net/ethernet/faraday/ftmac100.c
+++ b/drivers/net/ethernet/faraday/ftmac100.c
@@ -1085,7 +1085,7 @@ static int ftmac100_probe(struct platform_device *pdev)
 	}
 
 	SET_NETDEV_DEV(netdev, &pdev->dev);
-	SET_ETHTOOL_OPS(netdev, &ftmac100_ethtool_ops);
+	netdev->ethtool_ops = &ftmac100_ethtool_ops;
 	netdev->netdev_ops = &ftmac100_netdev_ops;
 
 	platform_set_drvdata(pdev, netdev);
diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
index 413329e..cc83350 100644
--- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
+++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
@@ -417,5 +417,5 @@ static const struct ethtool_ops uec_ethtool_ops = {
 
 void uec_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &uec_ethtool_ops);
+	netdev->ethtool_ops = &uec_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
index 7becab1..cfe7a74 100644
--- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
+++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
@@ -256,7 +256,7 @@ static int fmvj18x_probe(struct pcmcia_device *link)
     dev->netdev_ops = &fjn_netdev_ops;
     dev->watchdog_timeo = TX_TIMEOUT;
 
-    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+    dev->ethtool_ops = &netdev_ethtool_ops;
 
     return fmvj18x_config(link);
 } /* fmvj18x_attach */
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
index 95837b9..6055e3e 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
@@ -278,5 +278,5 @@ static const struct ethtool_ops ehea_ethtool_ops = {
 
 void ehea_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &ehea_ethtool_ops);
+	netdev->ethtool_ops = &ehea_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index ae342fd..87bd953 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -2879,7 +2879,7 @@ static int emac_probe(struct platform_device *ofdev)
 		dev->commac.ops = &emac_commac_sg_ops;
 	} else
 		ndev->netdev_ops = &emac_netdev_ops;
-	SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
+	ndev->ethtool_ops = &emac_ethtool_ops;
 
 	netif_carrier_off(ndev);
 
diff --git a/drivers/net/ethernet/icplus/ipg.c b/drivers/net/ethernet/icplus/ipg.c
index 25045ae..5727779 100644
--- a/drivers/net/ethernet/icplus/ipg.c
+++ b/drivers/net/ethernet/icplus/ipg.c
@@ -2245,7 +2245,7 @@ static int ipg_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	 */
 	dev->netdev_ops = &ipg_netdev_ops;
 	SET_NETDEV_DEV(dev, &pdev->dev);
-	SET_ETHTOOL_OPS(dev, &ipg_ethtool_ops);
+	dev->ethtool_ops = &ipg_ethtool_ops;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
 	if (rc)
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
index b56461c..9d979d7 100644
--- a/drivers/net/ethernet/intel/e100.c
+++ b/drivers/net/ethernet/intel/e100.c
@@ -2854,7 +2854,7 @@ static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->hw_features |= NETIF_F_RXALL;
 
 	netdev->netdev_ops = &e100_netdev_ops;
-	SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
+	netdev->ethtool_ops = &e100_ethtool_ops;
 	netdev->watchdog_timeo = E100_WATCHDOG_PERIOD;
 	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
index 73a8aee..341889a 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
@@ -1905,5 +1905,5 @@ static const struct ethtool_ops e1000_ethtool_ops = {
 
 void e1000_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
+	netdev->ethtool_ops = &e1000_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index cad250b..d9f8a2d 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -2315,5 +2315,5 @@ static const struct ethtool_ops e1000_ethtool_ops = {
 
 void e1000e_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
+	netdev->ethtool_ops = &e1000_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 03d99cb..7673f86 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1692,5 +1692,5 @@ static const struct ethtool_ops i40e_ethtool_ops = {
 
 void i40e_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &i40e_ethtool_ops);
+	netdev->ethtool_ops = &i40e_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
index 8b0db1c..4defd51 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -389,5 +389,5 @@ static struct ethtool_ops i40evf_ethtool_ops = {
  **/
 void i40evf_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &i40evf_ethtool_ops);
+	netdev->ethtool_ops = &i40evf_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index e5570ac..30b76e1 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -3029,5 +3029,5 @@ static const struct ethtool_ops igb_ethtool_ops = {
 
 void igb_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &igb_ethtool_ops);
+	netdev->ethtool_ops = &igb_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c
index 90eef07..f58170b 100644
--- a/drivers/net/ethernet/intel/igbvf/ethtool.c
+++ b/drivers/net/ethernet/intel/igbvf/ethtool.c
@@ -476,5 +476,5 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
 
 void igbvf_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &igbvf_ethtool_ops);
+	netdev->ethtool_ops = &igbvf_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
index dbb7dd2..1da2d98 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
@@ -656,5 +656,5 @@ static const struct ethtool_ops ixgb_ethtool_ops = {
 
 void ixgb_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
+	netdev->ethtool_ops = &ixgb_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 6c55c14..31d7268 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -3099,5 +3099,5 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
 
 void ixgbe_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &ixgbe_ethtool_ops);
+	netdev->ethtool_ops = &ixgbe_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
index 1baecb6..a757f07 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
@@ -813,5 +813,5 @@ static const struct ethtool_ops ixgbevf_ethtool_ops = {
 
 void ixgbevf_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &ixgbevf_ethtool_ops);
+	netdev->ethtool_ops = &ixgbevf_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index b7b8d74..df1d1b9 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2889,7 +2889,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 	if (err)
 		goto out;
 
-	SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
+	dev->ethtool_ops = &mv643xx_eth_ethtool_ops;
 
 	init_pscr(mp, pd->speed, pd->duplex);
 
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 14786c8..72bc47f 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2813,7 +2813,7 @@ static int mvneta_probe(struct platform_device *pdev)
 	dev->watchdog_timeo = 5 * HZ;
 	dev->netdev_ops = &mvneta_netdev_ops;
 
-	SET_ETHTOOL_OPS(dev, &mvneta_eth_tool_ops);
+	dev->ethtool_ops = &mvneta_eth_tool_ops;
 
 	pp = netdev_priv(dev);
 
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index b358c2f..8f5aa7c 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -1488,7 +1488,7 @@ static int pxa168_eth_probe(struct platform_device *pdev)
 	dev->netdev_ops = &pxa168_eth_netdev_ops;
 	dev->watchdog_timeo = 2 * HZ;
 	dev->base_addr = 0;
-	SET_ETHTOOL_OPS(dev, &pxa168_ethtool_ops);
+	dev->ethtool_ops = &pxa168_ethtool_ops;
 
 	INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
 
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index b811064..6969338 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4760,7 +4760,7 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,
 
 	SET_NETDEV_DEV(dev, &hw->pdev->dev);
 	dev->irq = hw->pdev->irq;
-	SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops);
+	dev->ethtool_ops = &sky2_ethtool_ops;
 	dev->watchdog_timeo = TX_WATCHDOG;
 	dev->netdev_ops = &sky2_netdev_ops[port];
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 7e4b172..36af5e7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2539,7 +2539,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
 	netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
 	netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
 
-	SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
+	dev->ethtool_ops = &mlx4_en_ethtool_ops;
 
 	/*
 	 * Set driver features
diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c
index 16435b3..6c7c78ba 100644
--- a/drivers/net/ethernet/micrel/ks8695net.c
+++ b/drivers/net/ethernet/micrel/ks8695net.c
@@ -1504,15 +1504,15 @@ ks8695_probe(struct platform_device *pdev)
 	if (ksp->phyiface_regs && ksp->link_irq == -1) {
 		ks8695_init_switch(ksp);
 		ksp->dtype = KS8695_DTYPE_LAN;
-		SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
+		ndev->ethtool_ops = &ks8695_ethtool_ops;
 	} else if (ksp->phyiface_regs && ksp->link_irq != -1) {
 		ks8695_init_wan_phy(ksp);
 		ksp->dtype = KS8695_DTYPE_WAN;
-		SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops);
+		ndev->ethtool_ops = &ks8695_wan_ethtool_ops;
 	} else {
 		/* No initialisation since HPNA does not have a PHY */
 		ksp->dtype = KS8695_DTYPE_HPNA;
-		SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
+		ndev->ethtool_ops = &ks8695_ethtool_ops;
 	}
 
 	/* And bring up the net_device with the net core */
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c
index e0c92e0..13767eb 100644
--- a/drivers/net/ethernet/micrel/ks8851.c
+++ b/drivers/net/ethernet/micrel/ks8851.c
@@ -1471,7 +1471,7 @@ static int ks8851_probe(struct spi_device *spi)
 
 	skb_queue_head_init(&ks->txq);
 
-	SET_ETHTOOL_OPS(ndev, &ks8851_ethtool_ops);
+	ndev->ethtool_ops = &ks8851_ethtool_ops;
 	SET_NETDEV_DEV(ndev, &spi->dev);
 
 	spi_set_drvdata(spi, ks);
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index 14ac0e2..4b9592c1 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -7106,7 +7106,7 @@ static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id)
 		}
 
 		dev->netdev_ops = &netdev_ops;
-		SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+		dev->ethtool_ops = &netdev_ethtool_ops;
 		if (register_netdev(dev))
 			goto pcidev_init_reg_err;
 		port_set_power_saving(port, true);
diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c
index c7b40aa..b1b5f66 100644
--- a/drivers/net/ethernet/microchip/enc28j60.c
+++ b/drivers/net/ethernet/microchip/enc28j60.c
@@ -1593,7 +1593,7 @@ static int enc28j60_probe(struct spi_device *spi)
 	dev->irq = spi->irq;
 	dev->netdev_ops = &enc28j60_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
-	SET_ETHTOOL_OPS(dev, &enc28j60_ethtool_ops);
+	dev->ethtool_ops = &enc28j60_ethtool_ops;
 
 	enc28j60_lowpower(priv, true);
 
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 130f6b2..f3d5d79 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -4112,7 +4112,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer,
 		    (unsigned long)mgp);
 
-	SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops);
+	netdev->ethtool_ops = &myri10ge_ethtool_ops;
 	INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog);
 	status = register_netdev(netdev);
 	if (status != 0) {
diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index 64ec2a4..291fba8 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -927,7 +927,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)
 	dev->netdev_ops = &natsemi_netdev_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
-	SET_ETHTOOL_OPS(dev, &ethtool_ops);
+	dev->ethtool_ops = &ethtool_ops;
 
 	if (mtu)
 		dev->mtu = mtu;
diff --git a/drivers/net/ethernet/natsemi/ns83820.c b/drivers/net/ethernet/natsemi/ns83820.c
index dbccf1d..19bb824 100644
--- a/drivers/net/ethernet/natsemi/ns83820.c
+++ b/drivers/net/ethernet/natsemi/ns83820.c
@@ -2030,7 +2030,7 @@ static int ns83820_init_one(struct pci_dev *pci_dev,
 		pci_dev->subsystem_vendor, pci_dev->subsystem_device);
 
 	ndev->netdev_ops = &netdev_ops;
-	SET_ETHTOOL_OPS(ndev, &ops);
+	ndev->ethtool_ops = &ops;
 	ndev->watchdog_timeo = 5 * HZ;
 	pci_set_drvdata(pci_dev, ndev);
 
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index a2844ff..190538d 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -7919,7 +7919,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
 	/*  Driver entry points */
 	dev->netdev_ops = &s2io_netdev_ops;
-	SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+	dev->ethtool_ops = &netdev_ethtool_ops;
 	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
 		NETIF_F_TSO | NETIF_F_TSO6 |
 		NETIF_F_RXCSUM | NETIF_F_LRO;
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c b/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c
index f8f0738..ddcc81a 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c
@@ -1128,5 +1128,5 @@ static const struct ethtool_ops vxge_ethtool_ops = {
 
 void vxge_initialize_ethtool_ops(struct net_device *ndev)
 {
-	SET_ETHTOOL_OPS(ndev, &vxge_ethtool_ops);
+	ndev->ethtool_ops = &vxge_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index fddb464..e8235c5 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -5766,7 +5766,7 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
 		dev->netdev_ops = &nv_netdev_ops_optimized;
 
 	netif_napi_add(dev, &np->napi, nv_napi_poll, RX_WORK_PER_LOOP);
-	SET_ETHTOOL_OPS(dev, &ops);
+	dev->ethtool_ops = &ops;
 	dev->watchdog_timeo = NV_WATCHDOG_TIMEO;
 
 	pci_set_drvdata(pci_dev, dev);
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c
index 826f0cc..114d2fe 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c
@@ -508,5 +508,5 @@ static const struct ethtool_ops pch_gbe_ethtool_ops = {
 
 void pch_gbe_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &pch_gbe_ethtool_ops);
+	netdev->ethtool_ops = &pch_gbe_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c
index b6bdeb3..9a997e4 100644
--- a/drivers/net/ethernet/packetengines/hamachi.c
+++ b/drivers/net/ethernet/packetengines/hamachi.c
@@ -724,10 +724,8 @@ static int hamachi_init_one(struct pci_dev *pdev,
 
 	/* The Hamachi-specific entries in the device structure. */
 	dev->netdev_ops = &hamachi_netdev_ops;
-	if (chip_tbl[hmp->chip_id].flags & CanHaveMII)
-		SET_ETHTOOL_OPS(dev, &ethtool_ops);
-	else
-		SET_ETHTOOL_OPS(dev, &ethtool_ops_no_mii);
+	dev->ethtool_ops = (chip_tbl[hmp->chip_id].flags & CanHaveMII) ?
+		&ethtool_ops : &ethtool_ops_no_mii;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	if (mtu)
 		dev->mtu = mtu;
diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c
index 9a6cb48..69a8dc0 100644
--- a/drivers/net/ethernet/packetengines/yellowfin.c
+++ b/drivers/net/ethernet/packetengines/yellowfin.c
@@ -472,7 +472,7 @@ static int yellowfin_init_one(struct pci_dev *pdev,
 
 	/* The Yellowfin-specific entries in the device structure. */
 	dev->netdev_ops = &netdev_ops;
-	SET_ETHTOOL_OPS(dev, &ethtool_ops);
+	dev->ethtool_ops = &ethtool_ops;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
 	if (mtu)
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index f09c35d..5bf0581 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -1373,7 +1373,7 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
 
 	netxen_nic_change_mtu(netdev, netdev->mtu);
 
-	SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
+	netdev->ethtool_ops = &netxen_nic_ethtool_ops;
 
 	netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
 	                      NETIF_F_RXCSUM;
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index 2eabd44..b5d6bc1 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -3838,7 +3838,7 @@ static int ql3xxx_probe(struct pci_dev *pdev,
 
 	/* Set driver entry points */
 	ndev->netdev_ops = &ql3xxx_netdev_ops;
-	SET_ETHTOOL_OPS(ndev, &ql3xxx_ethtool_ops);
+	ndev->ethtool_ops = &ql3xxx_ethtool_ops;
 	ndev->watchdog_timeo = 5 * HZ;
 
 	netif_napi_add(ndev, &qdev->napi, ql_poll, 64);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index dbf7539..4bdbdca 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2222,10 +2222,8 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
 
 	qlcnic_change_mtu(netdev, netdev->mtu);
 
-	if (qlcnic_sriov_vf_check(adapter))
-		SET_ETHTOOL_OPS(netdev, &qlcnic_sriov_vf_ethtool_ops);
-	else
-		SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops);
+	netdev->ethtool_ops = (qlcnic_sriov_vf_check(adapter)) ?
+		&qlcnic_sriov_vf_ethtool_ops : &qlcnic_ethtool_ops;
 
 	netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
 			     NETIF_F_IPV6_CSUM | NETIF_F_GRO |
@@ -2630,7 +2628,7 @@ err_out_disable_pdev:
 err_out_maintenance_mode:
 	set_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state);
 	netdev->netdev_ops = &qlcnic_netdev_failed_ops;
-	SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_failed_ops);
+	netdev->ethtool_ops = &qlcnic_ethtool_failed_ops;
 	ahw->port_type = QLCNIC_XGBE;
 
 	if (qlcnic_83xx_check(adapter))
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index 0a1d76a..79b86e9 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -4770,7 +4770,7 @@ static int qlge_probe(struct pci_dev *pdev,
 	ndev->irq = pdev->irq;
 
 	ndev->netdev_ops = &qlge_netdev_ops;
-	SET_ETHTOOL_OPS(ndev, &qlge_ethtool_ops);
+	ndev->ethtool_ops = &qlge_ethtool_ops;
 	ndev->watchdog_timeo = 10 * HZ;
 
 	err = register_netdev(ndev);
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index aa1c079..be425ad 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -7125,7 +7125,7 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	for (i = 0; i < ETH_ALEN; i++)
 		dev->dev_addr[i] = RTL_R8(MAC0 + i);
 
-	SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
+	dev->ethtool_ops = &rtl8169_ethtool_ops;
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
 
 	netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 6a9509c..967314c 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -2843,7 +2843,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 		ndev->netdev_ops = &sh_eth_netdev_ops_tsu;
 	else
 		ndev->netdev_ops = &sh_eth_netdev_ops;
-	SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
+	ndev->ethtool_ops = &sh_eth_ethtool_ops;
 	ndev->watchdog_timeo = TX_TIMEOUT;
 
 	/* debug message level */
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
index 0415fa5..c0981ae 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
@@ -520,5 +520,5 @@ static const struct ethtool_ops sxgbe_ethtool_ops = {
 
 void sxgbe_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &sxgbe_ethtool_ops);
+	netdev->ethtool_ops = &sxgbe_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 63d595f..1e27404 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -2248,7 +2248,7 @@ static int efx_register_netdev(struct efx_nic *efx)
 	} else {
 		net_dev->netdev_ops = &efx_farch_netdev_ops;
 	}
-	SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops);
+	net_dev->ethtool_ops = &efx_ethtool_ops;
 	net_dev->gso_max_segs = EFX_TSO_MAX_SEGS;
 
 	rtnl_lock();
diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c
index acbbe48..a863399 100644
--- a/drivers/net/ethernet/sis/sis190.c
+++ b/drivers/net/ethernet/sis/sis190.c
@@ -1877,7 +1877,7 @@ static int sis190_init_one(struct pci_dev *pdev,
 
 	dev->netdev_ops = &sis190_netdev_ops;
 
-	SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops);
+	dev->ethtool_ops = &sis190_ethtool_ops;
 	dev->watchdog_timeo = SIS190_TX_TIMEOUT;
 
 	spin_lock_init(&tp->lock);
diff --git a/drivers/net/ethernet/smsc/smc91c92_cs.c b/drivers/net/ethernet/smsc/smc91c92_cs.c
index c7a4868..6b33127 100644
--- a/drivers/net/ethernet/smsc/smc91c92_cs.c
+++ b/drivers/net/ethernet/smsc/smc91c92_cs.c
@@ -318,7 +318,7 @@ static int smc91c92_probe(struct pcmcia_device *link)
 
     /* The SMC91c92-specific entries in the device structure. */
     dev->netdev_ops = &smc_netdev_ops;
-    SET_ETHTOOL_OPS(dev, &ethtool_ops);
+    dev->ethtool_ops = &ethtool_ops;
     dev->watchdog_timeo = TX_TIMEOUT;
 
     smc->mii_if.dev = dev;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index c5f9cb8..c963394 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -784,5 +784,5 @@ static const struct ethtool_ops stmmac_ethtool_ops = {
 
 void stmmac_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &stmmac_ethtool_ops);
+	netdev->ethtool_ops = &stmmac_ethtool_ops;
 }
diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c
index 2ead877..38da73a 100644
--- a/drivers/net/ethernet/tehuti/tehuti.c
+++ b/drivers/net/ethernet/tehuti/tehuti.c
@@ -2413,7 +2413,7 @@ static void bdx_set_ethtool_ops(struct net_device *netdev)
 		.get_ethtool_stats = bdx_get_ethtool_stats,
 	};
 
-	SET_ETHTOOL_OPS(netdev, &bdx_ethtool_ops);
+	netdev->ethtool_ops = &bdx_ethtool_ops;
 }
 
 /**
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 36aa109..6ecab3c 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1975,7 +1975,7 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev,
 	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 
 	ndev->netdev_ops = &cpsw_netdev_ops;
-	SET_ETHTOOL_OPS(ndev, &cpsw_ethtool_ops);
+	ndev->ethtool_ops = &cpsw_ethtool_ops;
 	netif_napi_add(ndev, &priv_sl2->napi, cpsw_poll, CPSW_POLL_WEIGHT);
 
 	/* register the network device */
@@ -2204,7 +2204,7 @@ static int cpsw_probe(struct platform_device *pdev)
 	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 
 	ndev->netdev_ops = &cpsw_netdev_ops;
-	SET_ETHTOOL_OPS(ndev, &cpsw_ethtool_ops);
+	ndev->ethtool_ops = &cpsw_ethtool_ops;
 	netif_napi_add(ndev, &priv->napi, cpsw_poll, CPSW_POLL_WEIGHT);
 
 	/* register the network device */
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 8f0e69c..e76eae5 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1980,7 +1980,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
 	}
 
 	ndev->netdev_ops = &emac_netdev_ops;
-	SET_ETHTOOL_OPS(ndev, &ethtool_ops);
+	ndev->ethtool_ops = &ethtool_ops;
 	netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT);
 
 	/* register the network device */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 31e55fb..2170db5 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -715,7 +715,7 @@ static int netvsc_probe(struct hv_device *dev,
 	net->features = NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_SG | NETIF_F_RXCSUM |
 			NETIF_F_IP_CSUM | NETIF_F_TSO;
 
-	SET_ETHTOOL_OPS(net, &ethtool_ops);
+	net->ethtool_ops = &ethtool_ops;
 	SET_NETDEV_DEV(net, &dev->device);
 
 	/* Notify the netvsc driver of the new device */
diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
index 63aa9d9..27536aa 100644
--- a/drivers/net/ntb_netdev.c
+++ b/drivers/net/ntb_netdev.c
@@ -348,7 +348,7 @@ static int ntb_netdev_probe(struct pci_dev *pdev)
 	memcpy(ndev->dev_addr, ndev->perm_addr, ndev->addr_len);
 
 	ndev->netdev_ops = &ntb_netdev_ops;
-	SET_ETHTOOL_OPS(ndev, &ntb_ethtool_ops);
+	ndev->ethtool_ops = &ntb_ethtool_ops;
 
 	dev->qp = ntb_transport_create_queue(ndev, pdev, &ntb_netdev_handlers);
 	if (!dev->qp) {
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index a849718..dac7a0d 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -494,7 +494,7 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
 	ndev->mtu = RIO_MAX_MSG_SIZE - 14;
 	ndev->features = NETIF_F_LLTX;
 	SET_NETDEV_DEV(ndev, &mport->dev);
-	SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
+	ndev->ethtool_ops = &rionet_ethtool_ops;
 
 	spin_lock_init(&rnet->lock);
 	spin_lock_init(&rnet->tx_lock);
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 630caf4..8cfc3bb 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -793,7 +793,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
 
 	netdev->netdev_ops = &catc_netdev_ops;
 	netdev->watchdog_timeo = TX_TIMEOUT;
-	SET_ETHTOOL_OPS(netdev, &ops);
+	netdev->ethtool_ops = &ops;
 
 	catc->usbdev = usbdev;
 	catc->netdev = netdev;
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 660bd5e..a3a0586 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -2425,7 +2425,7 @@ static void hso_net_init(struct net_device *net)
 	net->type = ARPHRD_NONE;
 	net->mtu = DEFAULT_MTU - 14;
 	net->tx_queue_len = 10;
-	SET_ETHTOOL_OPS(net, &ops);
+	net->ethtool_ops = &ops;
 
 	/* and initialize the semaphore */
 	spin_lock_init(&hso_net->net_lock);
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index 421934c..f725707 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -524,7 +524,7 @@ static int ipheth_probe(struct usb_interface *intf,
 	usb_set_intfdata(intf, dev);
 
 	SET_NETDEV_DEV(netdev, &intf->dev);
-	SET_ETHTOOL_OPS(netdev, &ops);
+	netdev->ethtool_ops = &ops;
 
 	retval = register_netdev(netdev);
 	if (retval) {
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index a359d3b..dcb6d33 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -1171,7 +1171,7 @@ err_fw:
 	netdev->netdev_ops = &kaweth_netdev_ops;
 	netdev->watchdog_timeo = KAWETH_TX_TIMEOUT;
 	netdev->mtu = le16_to_cpu(kaweth->configuration.segment_size);
-	SET_ETHTOOL_OPS(netdev, &ops);
+	netdev->ethtool_ops = &ops;
 
 	/* kaweth is zeroed as part of alloc_netdev */
 	INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl);
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 03e8a15..f840802 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -1159,7 +1159,7 @@ static int pegasus_probe(struct usb_interface *intf,
 
 	net->watchdog_timeo = PEGASUS_TX_TIMEOUT;
 	net->netdev_ops = &pegasus_netdev_ops;
-	SET_ETHTOOL_OPS(net, &ops);
+	net->ethtool_ops = &ops;
 	pegasus->mii.dev = net;
 	pegasus->mii.mdio_read = mdio_read;
 	pegasus->mii.mdio_write = mdio_write;
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 3fbfb08..9f91c7a 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3452,7 +3452,7 @@ static int rtl8152_probe(struct usb_interface *intf,
 			      NETIF_F_TSO | NETIF_F_FRAGLIST |
 			      NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
 
-	SET_ETHTOOL_OPS(netdev, &ops);
+	netdev->ethtool_ops = &ops;
 	netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
 
 	tp->mii.dev = netdev;
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index da2c458..6e87e57 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -878,7 +878,7 @@ static int rtl8150_probe(struct usb_interface *intf,
 	dev->netdev = netdev;
 	netdev->netdev_ops = &rtl8150_netdev_ops;
 	netdev->watchdog_timeo = RTL8150_TX_TIMEOUT;
-	SET_ETHTOOL_OPS(netdev, &ops);
+	netdev->ethtool_ops = &ops;
 	dev->intr_interval = 100;	/* 100ms */
 
 	if (!alloc_all_urbs(dev)) {
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7b68746..3f83359 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1646,7 +1646,7 @@ static int virtnet_probe(struct virtio_device *vdev)
 	dev->netdev_ops = &virtnet_netdev;
 	dev->features = NETIF_F_HIGHDMA;
 
-	SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops);
+	dev->ethtool_ops = &virtnet_ethtool_ops;
 	SET_NETDEV_DEV(dev, &vdev->dev);
 
 	/* Do we support "hardware" checksums? */
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 600ab56..00e1202 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -635,5 +635,5 @@ static const struct ethtool_ops vmxnet3_ethtool_ops = {
 
 void vmxnet3_set_ethtool_ops(struct net_device *netdev)
 {
-	SET_ETHTOOL_OPS(netdev, &vmxnet3_ethtool_ops);
+	netdev->ethtool_ops = &vmxnet3_ethtool_ops;
 }
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 82355d5..457359c 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2706,7 +2706,7 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
 		return -EEXIST;
 	}
 
-	SET_ETHTOOL_OPS(dev, &vxlan_ethtool_ops);
+	dev->ethtool_ops = &vxlan_ethtool_ops;
 
 	/* create an fdb entry for a valid default destination */
 	if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) {
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 67db34e..52919ad 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -882,7 +882,7 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,
 	dev->mtu = local->mtu;
 
 
-	SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops);
+	dev->ethtool_ops = &prism2_ethtool_ops;
 
 }
 
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index ef05c5c..a755733 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -386,7 +386,7 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
 		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
 		NETIF_F_TSO | NETIF_F_TSO6;
 	dev->features = dev->hw_features | NETIF_F_RXCSUM;
-	SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops);
+	dev->ethtool_ops = &xenvif_ethtool_ops;
 
 	dev->tx_queue_len = XENVIF_QUEUE_LENGTH;
 
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 158b5e6..895355d 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1332,7 +1332,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
          */
 	netdev->features |= netdev->hw_features;
 
-	SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops);
+	netdev->ethtool_ops = &xennet_ethtool_ops;
 	SET_NETDEV_DEV(netdev, &dev->dev);
 
 	netif_set_gso_max_size(netdev, XEN_NETIF_MAX_TX_SIZE - MAX_TCP_HEADER);
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 8dea3f1..047b4da 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -964,10 +964,9 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
 	card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
 	card->dev->mtu = card->info.initial_mtu;
 	card->dev->netdev_ops = &qeth_l2_netdev_ops;
-	if (card->info.type != QETH_CARD_TYPE_OSN)
-		SET_ETHTOOL_OPS(card->dev, &qeth_l2_ethtool_ops);
-	else
-		SET_ETHTOOL_OPS(card->dev, &qeth_l2_osn_ops);
+	card->dev->ethtool_ops =
+		(card->info.type != QETH_CARD_TYPE_OSN) ?
+		&qeth_l2_ethtool_ops : &qeth_l2_osn_ops;
 	card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 	card->info.broadcast_capable = 1;
 	qeth_l2_request_initial_mac(card);
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 3524d34..0a59d24 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -3298,7 +3298,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
 	card->dev->ml_priv = card;
 	card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
 	card->dev->mtu = card->info.initial_mtu;
-	SET_ETHTOOL_OPS(card->dev, &qeth_l3_ethtool_ops);
+	card->dev->ethtool_ops = &qeth_l3_ethtool_ops;
 	card->dev->features |=	NETIF_F_HW_VLAN_CTAG_TX |
 				NETIF_F_HW_VLAN_CTAG_RX |
 				NETIF_F_HW_VLAN_CTAG_FILTER;
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index d329cf3..15e0f4d 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -4604,7 +4604,7 @@ static int et131x_pci_setup(struct pci_dev *pdev,
 	netdev->netdev_ops     = &et131x_netdev_ops;
 
 	SET_NETDEV_DEV(netdev, &pdev->dev);
-	SET_ETHTOOL_OPS(netdev, &et131x_ethtool_ops);
+	netdev->ethtool_ops = &et131x_ethtool_ops;
 
 	adapter = et131x_adapter_init(netdev, pdev);
 
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
index d6421b9..a6158be 100644
--- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
+++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
@@ -2249,7 +2249,7 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link,
 
 	ft1000InitProc(dev);
 	ft1000_card_present = 1;
-	SET_ETHTOOL_OPS(dev, &ops);
+	dev->ethtool_ops = &ops;
 	printk(KERN_INFO "ft1000: %s: addr 0x%04lx irq %d, MAC addr %pM\n",
 			dev->name, dev->base_addr, dev->irq, dev->dev_addr);
 	return dev;
diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c
index c83e337..9d95761 100644
--- a/drivers/staging/netlogic/xlr_net.c
+++ b/drivers/staging/netlogic/xlr_net.c
@@ -1066,7 +1066,7 @@ static int xlr_net_probe(struct platform_device *pdev)
 	xlr_set_rx_mode(ndev);
 
 	priv->num_rx_desc += MAX_NUM_DESC_SPILL;
-	SET_ETHTOOL_OPS(ndev, &xlr_ethtool_ops);
+	ndev->ethtool_ops = &xlr_ethtool_ops;
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 
 	/* Common registers, do one time initialization */
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index ff7214a..da9dd6b 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -469,7 +469,7 @@ int cvm_oct_common_init(struct net_device *dev)
 
 	/* We do our own locking, Linux doesn't need to */
 	dev->features |= NETIF_F_LLTX;
-	SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
+	dev->ethtool_ops = &cvm_oct_ethtool_ops;
 
 	cvm_oct_phy_setup_device(dev);
 	cvm_oct_set_mac_filter(dev);
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index b7d4f82..ce8e281 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -793,7 +793,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
 
 	net->netdev_ops = &eth_netdev_ops;
 
-	SET_ETHTOOL_OPS(net, &ops);
+	net->ethtool_ops = &ops;
 
 	dev->gadget = g;
 	SET_NETDEV_DEV(net, &g->dev);
@@ -850,7 +850,7 @@ struct net_device *gether_setup_name_default(const char *netname)
 
 	net->netdev_ops = &eth_netdev_ops;
 
-	SET_ETHTOOL_OPS(net, &ops);
+	net->ethtool_ops = &ops;
 	SET_NETDEV_DEVTYPE(net, &gadget_type);
 
 	return net;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7ed3a3a..06071f7 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -56,9 +56,6 @@ struct device;
 struct phy_device;
 /* 802.11 specific */
 struct wireless_dev;
-					/* source back-compat hooks */
-#define SET_ETHTOOL_OPS(netdev,ops) \
-	( (netdev)->ethtool_ops = (ops) )
 
 void netdev_set_default_ethtool_ops(struct net_device *dev,
 				    const struct ethtool_ops *ops);
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 744a59b..e7ee65d 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -884,7 +884,7 @@ static void batadv_softif_init_early(struct net_device *dev)
 	/* generate random address */
 	eth_hw_addr_random(dev);
 
-	SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops);
+	dev->ethtool_ops = &batadv_ethtool_ops;
 
 	memset(priv, 0, sizeof(*priv));
 }
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 3e2da2c..9212015 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -348,7 +348,7 @@ void br_dev_setup(struct net_device *dev)
 
 	dev->netdev_ops = &br_netdev_ops;
 	dev->destructor = br_dev_free;
-	SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
+	dev->ethtool_ops = &br_ethtool_ops;
 	SET_NETDEV_DEVTYPE(dev, &br_type);
 	dev->tx_queue_len = 0;
 	dev->priv_flags = IFF_EBRIDGE;
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 02c0e17..64c5af0 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -346,7 +346,7 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent,
 		return slave_dev;
 
 	slave_dev->features = master->vlan_features;
-	SET_ETHTOOL_OPS(slave_dev, &dsa_slave_ethtool_ops);
+	slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
 	eth_hw_addr_inherit(slave_dev, master);
 	slave_dev->tx_queue_len = 0;
 
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 729c687..789af92 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -130,7 +130,7 @@ static void do_setup(struct net_device *netdev)
 	netdev->priv_flags &= ~IFF_TX_SKB_SHARING;
 	netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
 	netdev->destructor = internal_dev_destructor;
-	SET_ETHTOOL_OPS(netdev, &internal_dev_ethtool_ops);
+	netdev->ethtool_ops = &internal_dev_ethtool_ops;
 	netdev->tx_queue_len = 0;
 
 	netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST |

^ permalink raw reply related

* [PATCH] powerpc/powernv: Correctly set hypervisor interrupt little endian bit on POWER8
From: Anton Blanchard @ 2014-05-08 12:31 UTC (permalink / raw)
  To: benh, paulus; +Cc: linuxppc-dev

HID0 IBM bit 19 is the HILE bit on POWER8. Set it to 0 to take
exceptions in big endian and to 1 to take them in little endian.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: b/arch/powerpc/include/asm/reg.h
===================================================================
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -397,6 +397,7 @@
 #define SPRN_HASH1	0x3D2		/* Primary Hash Address Register */
 #define SPRN_HASH2	0x3D3		/* Secondary Hash Address Resgister */
 #define SPRN_HID0	0x3F0		/* Hardware Implementation Register 0 */
+#define HID0_HILE_SH	(63 - 19)	/* Hypervisor interrupt little endian */
 #define HID0_HDICE_SH	(63 - 23)	/* 970 HDEC interrupt enable */
 #define HID0_EMCP	(1<<31)		/* Enable Machine Check pin */
 #define HID0_EBA	(1<<29)		/* Enable Bus Address Parity */
Index: b/arch/powerpc/kernel/cpu_setup_power.S
===================================================================
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ b/arch/powerpc/kernel/cpu_setup_power.S
@@ -60,6 +60,7 @@ _GLOBAL(__setup_cpu_power8)
 	bl	__init_HFSCR
 	bl	__init_tlb_power8
 	bl	__init_PMU_HV
+	bl	__init_HILE
 	mtlr	r11
 	blr
 
@@ -78,6 +79,7 @@ _GLOBAL(__restore_cpu_power8)
 	bl	__init_HFSCR
 	bl	__init_tlb_power8
 	bl	__init_PMU_HV
+	bl	__init_HILE
 	mtlr	r11
 	blr
 
@@ -132,6 +134,26 @@ __init_HFSCR:
 	mtspr	SPRN_HFSCR,r3
 	blr
 
+__init_HILE:
+	mfspr	r3,SPRN_HID0
+	li	r4,1
+	sldi	r4,r4,HID0_HILE_SH
+#ifdef __LITTLE_ENDIAN__
+	or	r3,r3,r4
+#else
+	andc	r3,r3,r4
+#endif
+	sync
+	mtspr	SPRN_HID0,r3
+	mfspr	r3,SPRN_HID0
+	mfspr	r3,SPRN_HID0
+	mfspr	r3,SPRN_HID0
+	mfspr	r3,SPRN_HID0
+	mfspr	r3,SPRN_HID0
+	mfspr	r3,SPRN_HID0
+	isync
+	blr
+
 /*
  * Clear the TLB using the specified IS form of tlbiel instruction
  * (invalidate by congruence class). P7 has 128 CCs., P8 has 512.

^ permalink raw reply

* Re: [PATCH] net: get rid of SET_ETHTOOL_OPS
From: Peter Senna Tschudin @ 2014-05-08 13:19 UTC (permalink / raw)
  To: netdev, Jay Cliburn, Chris Snook, Gary Zambrano, Ariel Elior,
	Florian Fainelli, Rasesh Mody, Santosh Raspatur,
	Dimitris Michailidis, Casey Leedom, Christian Benvenuti,
	Sujith Sankar, Govindarajulu Varadarajan, Neel Patel,
	Nishank Trivedi, Grant Grundler, Denis Kirjanov, Sathya Perla,
	Subbu Seetharaman, Ajit Khaparde, Li Yang,
	Thadeu Lima de Souza Cascardo, Francois Romieu, Sorbica Shieh,
	Jeff Kirsher, Jesse Brandeburg, Bruce Allan, Carolyn Wyborny,
	Don Skidmore, Greg Rose, Alex Duyck, John Ronciak, Mitch Williams,
	Linux NICS, Sebastian Hesselbarth, Thomas Petazzoni,
	Mirko Lindner, Stephen Hemminger, Amir Vadai, Hyong-Youb Kim,
	Jon Mason, Manish Chopra, Sony Chacko, Rajesh Borundia,
	Jitendra Kalsaria, Ron Mercer, linux-driver, Shahed Shaikh,
	Dept-HSGLinuxNICDev, Realtek linux nic maintainers, Byungho An,
	Girish K S, Siva Reddy Kallam, Vipul Pandya,
	Solarflare linux maintainers, Shradha Shah, Giuseppe Cavallaro,
	Andy Gospodarek, K. Y. Srinivasan, Haiyang Zhang, Jan Dumon,
	Petko Manolov, Rusty Russell, Michael S. Tsirkin,
	Shreyas Bhatewara, VMware, Inc., Jouni Malinen, John W. Linville,
	Ian Campbell, Wei Liu, Konrad Rzeszutek Wilk, Boris Ostrovsky,
	David Vrabel, Ursula Braun, Frank Blaschka, linux390,
	Martin Schwidefsky, Heiko Carstens, Mark Einon,
	Greg Kroah-Hartman, Marek Belisko, Felipe Balbi, David S. Miller,
	Marek Lindner, Simon Wunderlich, Antonio Quartulli, Jesse Gross,
	dingtianhong, Eric W. Biederman, Justin van Wijngaarden,
	Paul Gortmaker, Jingoo Han, Yijing Wang, Peter Hüwe,
	Nicolas Ferre, Joe Perches, H Hartley Sweeten, Johannes Berg,
	Peter Senna Tschudin, Sabrina Dubroca, John Greene, hahnjo,
	wangweidong, Maxime Bizon, Jonas Gorski, Julia Lawall,
	Rafał Miłecki, Hauke Mehrtens, Nathan Hintz,
	Rob Herring, Mugunthan V N, Andreas Herrmann, Neil Horman,
	Eric Dumazet, Grant Likely, Arend van Spriel, Petri Gynther,
	Libo Chen, Isaku Yamahata, Lubomir Rintel, Roland Stigge,
	Nishanth Menon, Alexander Gordeev, Julian Anastasov, Ivan Vecera,
	Andy Shevchenko, Anders Larsen, Sergei Shtylyov, Simon Horman,
	Laurent Pinchart, Nobuhiro Iwamatsu, Ben Dooks, Ben Boeckel,
	Peter Korsgaard, Ben Hutchings, Daniel Mack, Markus Pargmann,
	Tobias Klauser, Lad, Prabhakar, Christian Riesch, Tony Lindgren,
	Alexandre Bounine, Andrew Morton, Aaron Marburg, hayeswang,
	Cong Wang, Pravin B Shelar, Mike Rapoport, Daniel Borkmann,
	Or Gerlitz, Zhao, Gang, Daniel Dodge, Sarah Sharp, Tushar Behera,
	Archana kumari, Masanari Iida, Himangi Saraogi, Alan Cox,
	Jason Wang, Wei Yongjun, Iulia Manda, Nandini Hanumanthagowda,
	Aaro Koskinen, Luka Perkov, Bjørn Mork, linux-rdma,
	linux-acenic, nios2-dev, linuxppc-dev, e1000-devel, devel,
	linux-usb, virtualization, linux-wireless, xen-devel, linux-s390,
	devel, b.a.t.m.a.n, bridge, dev, trivial
In-Reply-To: <20140508115354.GB7875@kaos.lebenslange-mailadresse.de>

I think that it may be appropriate to submit this patch for linux-next
instead of 3.15-rc4...

On Thu, May 8, 2014 at 1:53 PM, Wilfried Klaebe
<w-lkml@lebenslange-mailadresse.de> wrote:
> Dave Miller mentioned he'd like to see SET_ETHTOOL_OPS gone.
> This does that.
>
> Compile tested only, but I'd seriously wonder if this broke anything.
>
> Suggested-by: Dave Miller <davem@davemloft.net>
> Signed-off-by: Wilfried Klaebe <w-lkml@lebenslange-mailadresse.de>
>
> ---
>
> Applies against v3.15-rc4.
>
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
> index c4b3940..078cadd 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
> +++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
> @@ -105,5 +105,5 @@ static const struct ethtool_ops ipoib_ethtool_ops = {
>
>  void ipoib_set_ethtool_ops(struct net_device *dev)
>  {
> -       SET_ETHTOOL_OPS(dev, &ipoib_ethtool_ops);
> +       dev->ethtool_ops = &ipoib_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/3com/3c509.c b/drivers/net/ethernet/3com/3c509.c
> index 35df0b9..a968654 100644
> --- a/drivers/net/ethernet/3com/3c509.c
> +++ b/drivers/net/ethernet/3com/3c509.c
> @@ -534,7 +534,7 @@ static int el3_common_init(struct net_device *dev)
>         /* The EL3-specific entries in the device structure. */
>         dev->netdev_ops = &netdev_ops;
>         dev->watchdog_timeo = TX_TIMEOUT;
> -       SET_ETHTOOL_OPS(dev, &ethtool_ops);
> +       dev->ethtool_ops = &ethtool_ops;
>
>         err = register_netdev(dev);
>         if (err) {
> diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c
> index 063557e..f18647c 100644
> --- a/drivers/net/ethernet/3com/3c589_cs.c
> +++ b/drivers/net/ethernet/3com/3c589_cs.c
> @@ -218,7 +218,7 @@ static int tc589_probe(struct pcmcia_device *link)
>         dev->netdev_ops = &el3_netdev_ops;
>         dev->watchdog_timeo = TX_TIMEOUT;
>
> -       SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
> +       dev->ethtool_ops = &netdev_ethtool_ops;
>
>         return tc589_config(link);
>  }
> diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c
> index 465cc71..e13b046 100644
> --- a/drivers/net/ethernet/3com/typhoon.c
> +++ b/drivers/net/ethernet/3com/typhoon.c
> @@ -2435,7 +2435,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>         netif_napi_add(dev, &tp->napi, typhoon_poll, 16);
>         dev->watchdog_timeo     = TX_TIMEOUT;
>
> -       SET_ETHTOOL_OPS(dev, &typhoon_ethtool_ops);
> +       dev->ethtool_ops = &typhoon_ethtool_ops;
>
>         /* We can handle scatter gather, up to 16 entries, and
>          * we can do IP checksumming (only version 4, doh...)
> diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c
> index 171d73c..40dbbf7 100644
> --- a/drivers/net/ethernet/adaptec/starfire.c
> +++ b/drivers/net/ethernet/adaptec/starfire.c
> @@ -784,7 +784,7 @@ static int starfire_init_one(struct pci_dev *pdev,
>
>         dev->netdev_ops = &netdev_ops;
>         dev->watchdog_timeo = TX_TIMEOUT;
> -       SET_ETHTOOL_OPS(dev, &ethtool_ops);
> +       dev->ethtool_ops = &ethtool_ops;
>
>         netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work);
>
> diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c
> index 1517e9df..9a6991b 100644
> --- a/drivers/net/ethernet/alteon/acenic.c
> +++ b/drivers/net/ethernet/alteon/acenic.c
> @@ -476,7 +476,7 @@ static int acenic_probe_one(struct pci_dev *pdev,
>         dev->watchdog_timeo = 5*HZ;
>
>         dev->netdev_ops = &ace_netdev_ops;
> -       SET_ETHTOOL_OPS(dev, &ace_ethtool_ops);
> +       dev->ethtool_ops = &ace_ethtool_ops;
>
>         /* we only display this string ONCE */
>         if (!boards_found)
> diff --git a/drivers/net/ethernet/altera/altera_tse_ethtool.c b/drivers/net/ethernet/altera/altera_tse_ethtool.c
> index 319ca74..8ac4bd2 100644
> --- a/drivers/net/ethernet/altera/altera_tse_ethtool.c
> +++ b/drivers/net/ethernet/altera/altera_tse_ethtool.c
> @@ -231,5 +231,5 @@ static const struct ethtool_ops tse_ethtool_ops = {
>
>  void altera_tse_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &tse_ethtool_ops);
> +       netdev->ethtool_ops = &tse_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
> index 26efaaa..068dc7c 100644
> --- a/drivers/net/ethernet/amd/amd8111e.c
> +++ b/drivers/net/ethernet/amd/amd8111e.c
> @@ -1900,7 +1900,7 @@ static int amd8111e_probe_one(struct pci_dev *pdev,
>
>         /* Initialize driver entry points */
>         dev->netdev_ops = &amd8111e_netdev_ops;
> -       SET_ETHTOOL_OPS(dev, &ops);
> +       dev->ethtool_ops = &ops;
>         dev->irq =pdev->irq;
>         dev->watchdog_timeo = AMD8111E_TX_TIMEOUT;
>         netif_napi_add(dev, &lp->napi, amd8111e_rx_poll, 32);
> diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
> index a2bd91e..a78e4c1 100644
> --- a/drivers/net/ethernet/amd/au1000_eth.c
> +++ b/drivers/net/ethernet/amd/au1000_eth.c
> @@ -1229,7 +1229,7 @@ static int au1000_probe(struct platform_device *pdev)
>         dev->base_addr = base->start;
>         dev->irq = irq;
>         dev->netdev_ops = &au1000_netdev_ops;
> -       SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
> +       dev->ethtool_ops = &au1000_ethtool_ops;
>         dev->watchdog_timeo = ETH_TX_TIMEOUT;
>
>         /*
> diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c
> index 08569fe..abf3b15 100644
> --- a/drivers/net/ethernet/amd/nmclan_cs.c
> +++ b/drivers/net/ethernet/amd/nmclan_cs.c
> @@ -457,7 +457,7 @@ static int nmclan_probe(struct pcmcia_device *link)
>      lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
>
>      dev->netdev_ops = &mace_netdev_ops;
> -    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
> +    dev->ethtool_ops = &netdev_ethtool_ops;
>      dev->watchdog_timeo = TX_TIMEOUT;
>
>      return nmclan_config(link);
> diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
> index 17bb9ce..49faa97 100644
> --- a/drivers/net/ethernet/atheros/alx/main.c
> +++ b/drivers/net/ethernet/atheros/alx/main.c
> @@ -1302,7 +1302,7 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>         }
>
>         netdev->netdev_ops = &alx_netdev_ops;
> -       SET_ETHTOOL_OPS(netdev, &alx_ethtool_ops);
> +       netdev->ethtool_ops = &alx_ethtool_ops;
>         netdev->irq = pdev->irq;
>         netdev->watchdog_timeo = ALX_WATCHDOG_TIME;
>
> diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
> index 859ea84..ecacaae 100644
> --- a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
> +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
> @@ -305,5 +305,5 @@ static const struct ethtool_ops atl1c_ethtool_ops = {
>
>  void atl1c_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &atl1c_ethtool_ops);
> +       netdev->ethtool_ops = &atl1c_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c
> index 82b2386..206e9b7 100644
> --- a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c
> +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c
> @@ -388,5 +388,5 @@ static const struct ethtool_ops atl1e_ethtool_ops = {
>
>  void atl1e_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &atl1e_ethtool_ops);
> +       netdev->ethtool_ops = &atl1e_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c
> index 78befb5..2587fed 100644
> --- a/drivers/net/ethernet/atheros/atlx/atl2.c
> +++ b/drivers/net/ethernet/atheros/atlx/atl2.c
> @@ -1396,7 +1396,7 @@ static int atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>         atl2_setup_pcicmd(pdev);
>
>         netdev->netdev_ops = &atl2_netdev_ops;
> -       SET_ETHTOOL_OPS(netdev, &atl2_ethtool_ops);
> +       netdev->ethtool_ops = &atl2_ethtool_ops;
>         netdev->watchdog_timeo = 5 * HZ;
>         strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
>
> diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
> index 05ba625..ca5a20a 100644
> --- a/drivers/net/ethernet/broadcom/b44.c
> +++ b/drivers/net/ethernet/broadcom/b44.c
> @@ -2380,7 +2380,7 @@ static int b44_init_one(struct ssb_device *sdev,
>         netif_napi_add(dev, &bp->napi, b44_poll, 64);
>         dev->watchdog_timeo = B44_TX_TIMEOUT;
>         dev->irq = sdev->irq;
> -       SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
> +       dev->ethtool_ops = &b44_ethtool_ops;
>
>         err = ssb_bus_powerup(sdev->bus, 0);
>         if (err) {
> diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
> index a7d11f5..1e7bba9c 100644
> --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
> +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
> @@ -1898,7 +1898,7 @@ static int bcm_enet_probe(struct platform_device *pdev)
>         dev->netdev_ops = &bcm_enet_ops;
>         netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
>
> -       SET_ETHTOOL_OPS(dev, &bcm_enet_ethtool_ops);
> +       dev->ethtool_ops = &bcm_enet_ethtool_ops;
>         SET_NETDEV_DEV(dev, &pdev->dev);
>
>         ret = register_netdev(dev);
> @@ -2784,7 +2784,7 @@ static int bcm_enetsw_probe(struct platform_device *pdev)
>         /* register netdevice */
>         dev->netdev_ops = &bcm_enetsw_ops;
>         netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
> -       SET_ETHTOOL_OPS(dev, &bcm_enetsw_ethtool_ops);
> +       dev->ethtool_ops = &bcm_enetsw_ethtool_ops;
>         SET_NETDEV_DEV(dev, &pdev->dev);
>
>         spin_lock_init(&priv->enetsw_mdio_lock);
> diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
> index 0297a79..05c6af6 100644
> --- a/drivers/net/ethernet/broadcom/bgmac.c
> +++ b/drivers/net/ethernet/broadcom/bgmac.c
> @@ -1436,7 +1436,7 @@ static int bgmac_probe(struct bcma_device *core)
>                 return -ENOMEM;
>         net_dev->netdev_ops = &bgmac_netdev_ops;
>         net_dev->irq = core->irq;
> -       SET_ETHTOOL_OPS(net_dev, &bgmac_ethtool_ops);
> +       net_dev->ethtool_ops = &bgmac_ethtool_ops;
>         bgmac = netdev_priv(net_dev);
>         bgmac->net_dev = net_dev;
>         bgmac->core = core;
> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
> index b6de05e..0322409 100644
> --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
> +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
> @@ -3506,8 +3506,6 @@ static const struct ethtool_ops bnx2x_vf_ethtool_ops = {
>
>  void bnx2x_set_ethtool_ops(struct bnx2x *bp, struct net_device *netdev)
>  {
> -       if (IS_PF(bp))
> -               SET_ETHTOOL_OPS(netdev, &bnx2x_ethtool_ops);
> -       else /* vf */
> -               SET_ETHTOOL_OPS(netdev, &bnx2x_vf_ethtool_ops);
> +       netdev->ethtool_ops = (IS_PF(bp)) ?
> +               &bnx2x_ethtool_ops : &bnx2x_vf_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
> index 0966bd0..5ba1cfb 100644
> --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
> +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
> @@ -2481,7 +2481,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
>         dev_set_drvdata(&pdev->dev, dev);
>         ether_addr_copy(dev->dev_addr, macaddr);
>         dev->watchdog_timeo = 2 * HZ;
> -       SET_ETHTOOL_OPS(dev, &bcmgenet_ethtool_ops);
> +       dev->ethtool_ops = &bcmgenet_ethtool_ops;
>         dev->netdev_ops = &bcmgenet_netdev_ops;
>         netif_napi_add(dev, &priv->napi, bcmgenet_poll, 64);
>
> diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
> index f9e1508..adca62b 100644
> --- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
> +++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
> @@ -1137,5 +1137,5 @@ static const struct ethtool_ops bnad_ethtool_ops = {
>  void
>  bnad_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &bnad_ethtool_ops);
> +       netdev->ethtool_ops = &bnad_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
> index 521dfea..25d6b2a 100644
> --- a/drivers/net/ethernet/calxeda/xgmac.c
> +++ b/drivers/net/ethernet/calxeda/xgmac.c
> @@ -1737,7 +1737,7 @@ static int xgmac_probe(struct platform_device *pdev)
>         platform_set_drvdata(pdev, ndev);
>         ether_setup(ndev);
>         ndev->netdev_ops = &xgmac_netdev_ops;
> -       SET_ETHTOOL_OPS(ndev, &xgmac_ethtool_ops);
> +       ndev->ethtool_ops = &xgmac_ethtool_ops;
>         spin_lock_init(&priv->stats_lock);
>         INIT_WORK(&priv->tx_timeout_work, xgmac_tx_timeout_work);
>
> diff --git a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
> index 0fe7ff7..c1b2c1d 100644
> --- a/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
> +++ b/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
> @@ -1100,7 +1100,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>
>                 netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
>
> -               SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
> +               netdev->ethtool_ops = &t1_ethtool_ops;
>         }
>
>         if (t1_init_sw_modules(adapter, bi) < 0) {
> diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
> index 07bbb71..3ed5079 100644
> --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
> +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
> @@ -3291,7 +3291,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>                         netdev->features |= NETIF_F_HIGHDMA;
>
>                 netdev->netdev_ops = &cxgb_netdev_ops;
> -               SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
> +               netdev->ethtool_ops = &cxgb_ethtool_ops;
>         }
>
>         pci_set_drvdata(pdev, adapter);
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> index 6fe5891..7c61f89 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> @@ -6074,7 +6074,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>                 netdev->priv_flags |= IFF_UNICAST_FLT;
>
>                 netdev->netdev_ops = &cxgb4_netdev_ops;
> -               SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
> +               netdev->ethtool_ops = &cxgb_ethtool_ops;
>         }
>
>         pci_set_drvdata(pdev, adapter);
> diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
> index 5285928..ff1cdd1 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
> @@ -2664,7 +2664,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
>                 netdev->priv_flags |= IFF_UNICAST_FLT;
>
>                 netdev->netdev_ops = &cxgb4vf_netdev_ops;
> -               SET_ETHTOOL_OPS(netdev, &cxgb4vf_ethtool_ops);
> +               netdev->ethtool_ops = &cxgb4vf_ethtool_ops;
>
>                 /*
>                  * Initialize the hardware/software state for the port.
> diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
> index 47e3562..58a8c67 100644
> --- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
> +++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
> @@ -253,5 +253,5 @@ static const struct ethtool_ops enic_ethtool_ops = {
>
>  void enic_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &enic_ethtool_ops);
> +       netdev->ethtool_ops = &enic_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
> index 1642de7..8616608 100644
> --- a/drivers/net/ethernet/dec/tulip/tulip_core.c
> +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
> @@ -1703,7 +1703,7 @@ static int tulip_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>  #ifdef CONFIG_TULIP_NAPI
>         netif_napi_add(dev, &tp->napi, tulip_poll, 16);
>  #endif
> -       SET_ETHTOOL_OPS(dev, &ops);
> +       dev->ethtool_ops = &ops;
>
>         if (register_netdev(dev))
>                 goto err_out_free_ring;
> diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
> index 4fb756d..2324f2d 100644
> --- a/drivers/net/ethernet/dlink/dl2k.c
> +++ b/drivers/net/ethernet/dlink/dl2k.c
> @@ -227,7 +227,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
>         }
>         dev->netdev_ops = &netdev_ops;
>         dev->watchdog_timeo = TX_TIMEOUT;
> -       SET_ETHTOOL_OPS(dev, &ethtool_ops);
> +       dev->ethtool_ops = &ethtool_ops;
>  #if 0
>         dev->features = NETIF_F_IP_CSUM;
>  #endif
> diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c
> index d9e5ca0..433c1e1 100644
> --- a/drivers/net/ethernet/dlink/sundance.c
> +++ b/drivers/net/ethernet/dlink/sundance.c
> @@ -577,7 +577,7 @@ static int sundance_probe1(struct pci_dev *pdev,
>
>         /* The chip-specific entries in the device structure. */
>         dev->netdev_ops = &netdev_ops;
> -       SET_ETHTOOL_OPS(dev, &ethtool_ops);
> +       dev->ethtool_ops = &ethtool_ops;
>         dev->watchdog_timeo = TX_TIMEOUT;
>
>         pci_set_drvdata(pdev, dev);
> diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
> index a186454..9a9e7c7 100644
> --- a/drivers/net/ethernet/emulex/benet/be_main.c
> +++ b/drivers/net/ethernet/emulex/benet/be_main.c
> @@ -4301,7 +4301,7 @@ static void be_netdev_init(struct net_device *netdev)
>
>         netdev->netdev_ops = &be_netdev_ops;
>
> -       SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
> +       netdev->ethtool_ops = &be_ethtool_ops;
>  }
>
>  static void be_unmap_pci_bars(struct be_adapter *adapter)
> diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
> index 68069ea..c77fa4a 100644
> --- a/drivers/net/ethernet/faraday/ftgmac100.c
> +++ b/drivers/net/ethernet/faraday/ftgmac100.c
> @@ -1210,7 +1210,7 @@ static int ftgmac100_probe(struct platform_device *pdev)
>
>         SET_NETDEV_DEV(netdev, &pdev->dev);
>
> -       SET_ETHTOOL_OPS(netdev, &ftgmac100_ethtool_ops);
> +       netdev->ethtool_ops = &ftgmac100_ethtool_ops;
>         netdev->netdev_ops = &ftgmac100_netdev_ops;
>         netdev->features = NETIF_F_IP_CSUM | NETIF_F_GRO;
>
> diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c
> index 8be5b40..4ff1adc 100644
> --- a/drivers/net/ethernet/faraday/ftmac100.c
> +++ b/drivers/net/ethernet/faraday/ftmac100.c
> @@ -1085,7 +1085,7 @@ static int ftmac100_probe(struct platform_device *pdev)
>         }
>
>         SET_NETDEV_DEV(netdev, &pdev->dev);
> -       SET_ETHTOOL_OPS(netdev, &ftmac100_ethtool_ops);
> +       netdev->ethtool_ops = &ftmac100_ethtool_ops;
>         netdev->netdev_ops = &ftmac100_netdev_ops;
>
>         platform_set_drvdata(pdev, netdev);
> diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
> index 413329e..cc83350 100644
> --- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
> +++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
> @@ -417,5 +417,5 @@ static const struct ethtool_ops uec_ethtool_ops = {
>
>  void uec_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &uec_ethtool_ops);
> +       netdev->ethtool_ops = &uec_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
> index 7becab1..cfe7a74 100644
> --- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
> +++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
> @@ -256,7 +256,7 @@ static int fmvj18x_probe(struct pcmcia_device *link)
>      dev->netdev_ops = &fjn_netdev_ops;
>      dev->watchdog_timeo = TX_TIMEOUT;
>
> -    SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
> +    dev->ethtool_ops = &netdev_ethtool_ops;
>
>      return fmvj18x_config(link);
>  } /* fmvj18x_attach */
> diff --git a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
> index 95837b9..6055e3e 100644
> --- a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
> +++ b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
> @@ -278,5 +278,5 @@ static const struct ethtool_ops ehea_ethtool_ops = {
>
>  void ehea_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &ehea_ethtool_ops);
> +       netdev->ethtool_ops = &ehea_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
> index ae342fd..87bd953 100644
> --- a/drivers/net/ethernet/ibm/emac/core.c
> +++ b/drivers/net/ethernet/ibm/emac/core.c
> @@ -2879,7 +2879,7 @@ static int emac_probe(struct platform_device *ofdev)
>                 dev->commac.ops = &emac_commac_sg_ops;
>         } else
>                 ndev->netdev_ops = &emac_netdev_ops;
> -       SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
> +       ndev->ethtool_ops = &emac_ethtool_ops;
>
>         netif_carrier_off(ndev);
>
> diff --git a/drivers/net/ethernet/icplus/ipg.c b/drivers/net/ethernet/icplus/ipg.c
> index 25045ae..5727779 100644
> --- a/drivers/net/ethernet/icplus/ipg.c
> +++ b/drivers/net/ethernet/icplus/ipg.c
> @@ -2245,7 +2245,7 @@ static int ipg_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>          */
>         dev->netdev_ops = &ipg_netdev_ops;
>         SET_NETDEV_DEV(dev, &pdev->dev);
> -       SET_ETHTOOL_OPS(dev, &ipg_ethtool_ops);
> +       dev->ethtool_ops = &ipg_ethtool_ops;
>
>         rc = pci_request_regions(pdev, DRV_NAME);
>         if (rc)
> diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
> index b56461c..9d979d7 100644
> --- a/drivers/net/ethernet/intel/e100.c
> +++ b/drivers/net/ethernet/intel/e100.c
> @@ -2854,7 +2854,7 @@ static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>         netdev->hw_features |= NETIF_F_RXALL;
>
>         netdev->netdev_ops = &e100_netdev_ops;
> -       SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
> +       netdev->ethtool_ops = &e100_ethtool_ops;
>         netdev->watchdog_timeo = E100_WATCHDOG_PERIOD;
>         strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
>
> diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
> index 73a8aee..341889a 100644
> --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
> +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
> @@ -1905,5 +1905,5 @@ static const struct ethtool_ops e1000_ethtool_ops = {
>
>  void e1000_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
> +       netdev->ethtool_ops = &e1000_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
> index cad250b..d9f8a2d 100644
> --- a/drivers/net/ethernet/intel/e1000e/ethtool.c
> +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
> @@ -2315,5 +2315,5 @@ static const struct ethtool_ops e1000_ethtool_ops = {
>
>  void e1000e_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
> +       netdev->ethtool_ops = &e1000_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> index 03d99cb..7673f86 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
> @@ -1692,5 +1692,5 @@ static const struct ethtool_ops i40e_ethtool_ops = {
>
>  void i40e_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &i40e_ethtool_ops);
> +       netdev->ethtool_ops = &i40e_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
> index 8b0db1c..4defd51 100644
> --- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
> +++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
> @@ -389,5 +389,5 @@ static struct ethtool_ops i40evf_ethtool_ops = {
>   **/
>  void i40evf_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &i40evf_ethtool_ops);
> +       netdev->ethtool_ops = &i40evf_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
> index e5570ac..30b76e1 100644
> --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
> +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
> @@ -3029,5 +3029,5 @@ static const struct ethtool_ops igb_ethtool_ops = {
>
>  void igb_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &igb_ethtool_ops);
> +       netdev->ethtool_ops = &igb_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c
> index 90eef07..f58170b 100644
> --- a/drivers/net/ethernet/intel/igbvf/ethtool.c
> +++ b/drivers/net/ethernet/intel/igbvf/ethtool.c
> @@ -476,5 +476,5 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
>
>  void igbvf_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &igbvf_ethtool_ops);
> +       netdev->ethtool_ops = &igbvf_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
> index dbb7dd2..1da2d98 100644
> --- a/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
> +++ b/drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c
> @@ -656,5 +656,5 @@ static const struct ethtool_ops ixgb_ethtool_ops = {
>
>  void ixgb_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
> +       netdev->ethtool_ops = &ixgb_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
> index 6c55c14..31d7268 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
> @@ -3099,5 +3099,5 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
>
>  void ixgbe_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &ixgbe_ethtool_ops);
> +       netdev->ethtool_ops = &ixgbe_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
> index 1baecb6..a757f07 100644
> --- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
> +++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
> @@ -813,5 +813,5 @@ static const struct ethtool_ops ixgbevf_ethtool_ops = {
>
>  void ixgbevf_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &ixgbevf_ethtool_ops);
> +       netdev->ethtool_ops = &ixgbevf_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
> index b7b8d74..df1d1b9 100644
> --- a/drivers/net/ethernet/marvell/mv643xx_eth.c
> +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
> @@ -2889,7 +2889,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
>         if (err)
>                 goto out;
>
> -       SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
> +       dev->ethtool_ops = &mv643xx_eth_ethtool_ops;
>
>         init_pscr(mp, pd->speed, pd->duplex);
>
> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
> index 14786c8..72bc47f 100644
> --- a/drivers/net/ethernet/marvell/mvneta.c
> +++ b/drivers/net/ethernet/marvell/mvneta.c
> @@ -2813,7 +2813,7 @@ static int mvneta_probe(struct platform_device *pdev)
>         dev->watchdog_timeo = 5 * HZ;
>         dev->netdev_ops = &mvneta_netdev_ops;
>
> -       SET_ETHTOOL_OPS(dev, &mvneta_eth_tool_ops);
> +       dev->ethtool_ops = &mvneta_eth_tool_ops;
>
>         pp = netdev_priv(dev);
>
> diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
> index b358c2f..8f5aa7c 100644
> --- a/drivers/net/ethernet/marvell/pxa168_eth.c
> +++ b/drivers/net/ethernet/marvell/pxa168_eth.c
> @@ -1488,7 +1488,7 @@ static int pxa168_eth_probe(struct platform_device *pdev)
>         dev->netdev_ops = &pxa168_eth_netdev_ops;
>         dev->watchdog_timeo = 2 * HZ;
>         dev->base_addr = 0;
> -       SET_ETHTOOL_OPS(dev, &pxa168_ethtool_ops);
> +       dev->ethtool_ops = &pxa168_ethtool_ops;
>
>         INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
>
> diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
> index b811064..6969338 100644
> --- a/drivers/net/ethernet/marvell/sky2.c
> +++ b/drivers/net/ethernet/marvell/sky2.c
> @@ -4760,7 +4760,7 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,
>
>         SET_NETDEV_DEV(dev, &hw->pdev->dev);
>         dev->irq = hw->pdev->irq;
> -       SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops);
> +       dev->ethtool_ops = &sky2_ethtool_ops;
>         dev->watchdog_timeo = TX_WATCHDOG;
>         dev->netdev_ops = &sky2_netdev_ops[port];
>
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index 7e4b172..36af5e7 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -2539,7 +2539,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
>         netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
>         netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
>
> -       SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
> +       dev->ethtool_ops = &mlx4_en_ethtool_ops;
>
>         /*
>          * Set driver features
> diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c
> index 16435b3..6c7c78ba 100644
> --- a/drivers/net/ethernet/micrel/ks8695net.c
> +++ b/drivers/net/ethernet/micrel/ks8695net.c
> @@ -1504,15 +1504,15 @@ ks8695_probe(struct platform_device *pdev)
>         if (ksp->phyiface_regs && ksp->link_irq == -1) {
>                 ks8695_init_switch(ksp);
>                 ksp->dtype = KS8695_DTYPE_LAN;
> -               SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
> +               ndev->ethtool_ops = &ks8695_ethtool_ops;
>         } else if (ksp->phyiface_regs && ksp->link_irq != -1) {
>                 ks8695_init_wan_phy(ksp);
>                 ksp->dtype = KS8695_DTYPE_WAN;
> -               SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops);
> +               ndev->ethtool_ops = &ks8695_wan_ethtool_ops;
>         } else {
>                 /* No initialisation since HPNA does not have a PHY */
>                 ksp->dtype = KS8695_DTYPE_HPNA;
> -               SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
> +               ndev->ethtool_ops = &ks8695_ethtool_ops;
>         }
>
>         /* And bring up the net_device with the net core */
> diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c
> index e0c92e0..13767eb 100644
> --- a/drivers/net/ethernet/micrel/ks8851.c
> +++ b/drivers/net/ethernet/micrel/ks8851.c
> @@ -1471,7 +1471,7 @@ static int ks8851_probe(struct spi_device *spi)
>
>         skb_queue_head_init(&ks->txq);
>
> -       SET_ETHTOOL_OPS(ndev, &ks8851_ethtool_ops);
> +       ndev->ethtool_ops = &ks8851_ethtool_ops;
>         SET_NETDEV_DEV(ndev, &spi->dev);
>
>         spi_set_drvdata(spi, ks);
> diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
> index 14ac0e2..4b9592c1 100644
> --- a/drivers/net/ethernet/micrel/ksz884x.c
> +++ b/drivers/net/ethernet/micrel/ksz884x.c
> @@ -7106,7 +7106,7 @@ static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id)
>                 }
>
>                 dev->netdev_ops = &netdev_ops;
> -               SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
> +               dev->ethtool_ops = &netdev_ethtool_ops;
>                 if (register_netdev(dev))
>                         goto pcidev_init_reg_err;
>                 port_set_power_saving(port, true);
> diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c
> index c7b40aa..b1b5f66 100644
> --- a/drivers/net/ethernet/microchip/enc28j60.c
> +++ b/drivers/net/ethernet/microchip/enc28j60.c
> @@ -1593,7 +1593,7 @@ static int enc28j60_probe(struct spi_device *spi)
>         dev->irq = spi->irq;
>         dev->netdev_ops = &enc28j60_netdev_ops;
>         dev->watchdog_timeo = TX_TIMEOUT;
> -       SET_ETHTOOL_OPS(dev, &enc28j60_ethtool_ops);
> +       dev->ethtool_ops = &enc28j60_ethtool_ops;
>
>         enc28j60_lowpower(priv, true);
>
> diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
> index 130f6b2..f3d5d79 100644
> --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
> +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
> @@ -4112,7 +4112,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>         setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer,
>                     (unsigned long)mgp);
>
> -       SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops);
> +       netdev->ethtool_ops = &myri10ge_ethtool_ops;
>         INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog);
>         status = register_netdev(netdev);
>         if (status != 0) {
> diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
> index 64ec2a4..291fba8 100644
> --- a/drivers/net/ethernet/natsemi/natsemi.c
> +++ b/drivers/net/ethernet/natsemi/natsemi.c
> @@ -927,7 +927,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)
>         dev->netdev_ops = &natsemi_netdev_ops;
>         dev->watchdog_timeo = TX_TIMEOUT;
>
> -       SET_ETHTOOL_OPS(dev, &ethtool_ops);
> +       dev->ethtool_ops = &ethtool_ops;
>
>         if (mtu)
>                 dev->mtu = mtu;
> diff --git a/drivers/net/ethernet/natsemi/ns83820.c b/drivers/net/ethernet/natsemi/ns83820.c
> index dbccf1d..19bb824 100644
> --- a/drivers/net/ethernet/natsemi/ns83820.c
> +++ b/drivers/net/ethernet/natsemi/ns83820.c
> @@ -2030,7 +2030,7 @@ static int ns83820_init_one(struct pci_dev *pci_dev,
>                 pci_dev->subsystem_vendor, pci_dev->subsystem_device);
>
>         ndev->netdev_ops = &netdev_ops;
> -       SET_ETHTOOL_OPS(ndev, &ops);
> +       ndev->ethtool_ops = &ops;
>         ndev->watchdog_timeo = 5 * HZ;
>         pci_set_drvdata(pci_dev, ndev);
>
> diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
> index a2844ff..190538d 100644
> --- a/drivers/net/ethernet/neterion/s2io.c
> +++ b/drivers/net/ethernet/neterion/s2io.c
> @@ -7919,7 +7919,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
>
>         /*  Driver entry points */
>         dev->netdev_ops = &s2io_netdev_ops;
> -       SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
> +       dev->ethtool_ops = &netdev_ethtool_ops;
>         dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
>                 NETIF_F_TSO | NETIF_F_TSO6 |
>                 NETIF_F_RXCSUM | NETIF_F_LRO;
> diff --git a/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c b/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c
> index f8f0738..ddcc81a 100644
> --- a/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c
> +++ b/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c
> @@ -1128,5 +1128,5 @@ static const struct ethtool_ops vxge_ethtool_ops = {
>
>  void vxge_initialize_ethtool_ops(struct net_device *ndev)
>  {
> -       SET_ETHTOOL_OPS(ndev, &vxge_ethtool_ops);
> +       ndev->ethtool_ops = &vxge_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
> index fddb464..e8235c5 100644
> --- a/drivers/net/ethernet/nvidia/forcedeth.c
> +++ b/drivers/net/ethernet/nvidia/forcedeth.c
> @@ -5766,7 +5766,7 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
>                 dev->netdev_ops = &nv_netdev_ops_optimized;
>
>         netif_napi_add(dev, &np->napi, nv_napi_poll, RX_WORK_PER_LOOP);
> -       SET_ETHTOOL_OPS(dev, &ops);
> +       dev->ethtool_ops = &ops;
>         dev->watchdog_timeo = NV_WATCHDOG_TIMEO;
>
>         pci_set_drvdata(pci_dev, dev);
> diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c
> index 826f0cc..114d2fe 100644
> --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c
> +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c
> @@ -508,5 +508,5 @@ static const struct ethtool_ops pch_gbe_ethtool_ops = {
>
>  void pch_gbe_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &pch_gbe_ethtool_ops);
> +       netdev->ethtool_ops = &pch_gbe_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c
> index b6bdeb3..9a997e4 100644
> --- a/drivers/net/ethernet/packetengines/hamachi.c
> +++ b/drivers/net/ethernet/packetengines/hamachi.c
> @@ -724,10 +724,8 @@ static int hamachi_init_one(struct pci_dev *pdev,
>
>         /* The Hamachi-specific entries in the device structure. */
>         dev->netdev_ops = &hamachi_netdev_ops;
> -       if (chip_tbl[hmp->chip_id].flags & CanHaveMII)
> -               SET_ETHTOOL_OPS(dev, &ethtool_ops);
> -       else
> -               SET_ETHTOOL_OPS(dev, &ethtool_ops_no_mii);
> +       dev->ethtool_ops = (chip_tbl[hmp->chip_id].flags & CanHaveMII) ?
> +               &ethtool_ops : &ethtool_ops_no_mii;
>         dev->watchdog_timeo = TX_TIMEOUT;
>         if (mtu)
>                 dev->mtu = mtu;
> diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c
> index 9a6cb48..69a8dc0 100644
> --- a/drivers/net/ethernet/packetengines/yellowfin.c
> +++ b/drivers/net/ethernet/packetengines/yellowfin.c
> @@ -472,7 +472,7 @@ static int yellowfin_init_one(struct pci_dev *pdev,
>
>         /* The Yellowfin-specific entries in the device structure. */
>         dev->netdev_ops = &netdev_ops;
> -       SET_ETHTOOL_OPS(dev, &ethtool_ops);
> +       dev->ethtool_ops = &ethtool_ops;
>         dev->watchdog_timeo = TX_TIMEOUT;
>
>         if (mtu)
> diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
> index f09c35d..5bf0581 100644
> --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
> +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
> @@ -1373,7 +1373,7 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
>
>         netxen_nic_change_mtu(netdev, netdev->mtu);
>
> -       SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
> +       netdev->ethtool_ops = &netxen_nic_ethtool_ops;
>
>         netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
>                               NETIF_F_RXCSUM;
> diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
> index 2eabd44..b5d6bc1 100644
> --- a/drivers/net/ethernet/qlogic/qla3xxx.c
> +++ b/drivers/net/ethernet/qlogic/qla3xxx.c
> @@ -3838,7 +3838,7 @@ static int ql3xxx_probe(struct pci_dev *pdev,
>
>         /* Set driver entry points */
>         ndev->netdev_ops = &ql3xxx_netdev_ops;
> -       SET_ETHTOOL_OPS(ndev, &ql3xxx_ethtool_ops);
> +       ndev->ethtool_ops = &ql3xxx_ethtool_ops;
>         ndev->watchdog_timeo = 5 * HZ;
>
>         netif_napi_add(ndev, &qdev->napi, ql_poll, 64);
> diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
> index dbf7539..4bdbdca 100644
> --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
> +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
> @@ -2222,10 +2222,8 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
>
>         qlcnic_change_mtu(netdev, netdev->mtu);
>
> -       if (qlcnic_sriov_vf_check(adapter))
> -               SET_ETHTOOL_OPS(netdev, &qlcnic_sriov_vf_ethtool_ops);
> -       else
> -               SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops);
> +       netdev->ethtool_ops = (qlcnic_sriov_vf_check(adapter)) ?
> +               &qlcnic_sriov_vf_ethtool_ops : &qlcnic_ethtool_ops;
>
>         netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
>                              NETIF_F_IPV6_CSUM | NETIF_F_GRO |
> @@ -2630,7 +2628,7 @@ err_out_disable_pdev:
>  err_out_maintenance_mode:
>         set_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state);
>         netdev->netdev_ops = &qlcnic_netdev_failed_ops;
> -       SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_failed_ops);
> +       netdev->ethtool_ops = &qlcnic_ethtool_failed_ops;
>         ahw->port_type = QLCNIC_XGBE;
>
>         if (qlcnic_83xx_check(adapter))
> diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
> index 0a1d76a..79b86e9 100644
> --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
> +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
> @@ -4770,7 +4770,7 @@ static int qlge_probe(struct pci_dev *pdev,
>         ndev->irq = pdev->irq;
>
>         ndev->netdev_ops = &qlge_netdev_ops;
> -       SET_ETHTOOL_OPS(ndev, &qlge_ethtool_ops);
> +       ndev->ethtool_ops = &qlge_ethtool_ops;
>         ndev->watchdog_timeo = 10 * HZ;
>
>         err = register_netdev(ndev);
> diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
> index aa1c079..be425ad 100644
> --- a/drivers/net/ethernet/realtek/r8169.c
> +++ b/drivers/net/ethernet/realtek/r8169.c
> @@ -7125,7 +7125,7 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
>         for (i = 0; i < ETH_ALEN; i++)
>                 dev->dev_addr[i] = RTL_R8(MAC0 + i);
>
> -       SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
> +       dev->ethtool_ops = &rtl8169_ethtool_ops;
>         dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
>
>         netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
> diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
> index 6a9509c..967314c 100644
> --- a/drivers/net/ethernet/renesas/sh_eth.c
> +++ b/drivers/net/ethernet/renesas/sh_eth.c
> @@ -2843,7 +2843,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
>                 ndev->netdev_ops = &sh_eth_netdev_ops_tsu;
>         else
>                 ndev->netdev_ops = &sh_eth_netdev_ops;
> -       SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
> +       ndev->ethtool_ops = &sh_eth_ethtool_ops;
>         ndev->watchdog_timeo = TX_TIMEOUT;
>
>         /* debug message level */
> diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
> index 0415fa5..c0981ae 100644
> --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
> +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c
> @@ -520,5 +520,5 @@ static const struct ethtool_ops sxgbe_ethtool_ops = {
>
>  void sxgbe_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &sxgbe_ethtool_ops);
> +       netdev->ethtool_ops = &sxgbe_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
> index 63d595f..1e27404 100644
> --- a/drivers/net/ethernet/sfc/efx.c
> +++ b/drivers/net/ethernet/sfc/efx.c
> @@ -2248,7 +2248,7 @@ static int efx_register_netdev(struct efx_nic *efx)
>         } else {
>                 net_dev->netdev_ops = &efx_farch_netdev_ops;
>         }
> -       SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops);
> +       net_dev->ethtool_ops = &efx_ethtool_ops;
>         net_dev->gso_max_segs = EFX_TSO_MAX_SEGS;
>
>         rtnl_lock();
> diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c
> index acbbe48..a863399 100644
> --- a/drivers/net/ethernet/sis/sis190.c
> +++ b/drivers/net/ethernet/sis/sis190.c
> @@ -1877,7 +1877,7 @@ static int sis190_init_one(struct pci_dev *pdev,
>
>         dev->netdev_ops = &sis190_netdev_ops;
>
> -       SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops);
> +       dev->ethtool_ops = &sis190_ethtool_ops;
>         dev->watchdog_timeo = SIS190_TX_TIMEOUT;
>
>         spin_lock_init(&tp->lock);
> diff --git a/drivers/net/ethernet/smsc/smc91c92_cs.c b/drivers/net/ethernet/smsc/smc91c92_cs.c
> index c7a4868..6b33127 100644
> --- a/drivers/net/ethernet/smsc/smc91c92_cs.c
> +++ b/drivers/net/ethernet/smsc/smc91c92_cs.c
> @@ -318,7 +318,7 @@ static int smc91c92_probe(struct pcmcia_device *link)
>
>      /* The SMC91c92-specific entries in the device structure. */
>      dev->netdev_ops = &smc_netdev_ops;
> -    SET_ETHTOOL_OPS(dev, &ethtool_ops);
> +    dev->ethtool_ops = &ethtool_ops;
>      dev->watchdog_timeo = TX_TIMEOUT;
>
>      smc->mii_if.dev = dev;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> index c5f9cb8..c963394 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> @@ -784,5 +784,5 @@ static const struct ethtool_ops stmmac_ethtool_ops = {
>
>  void stmmac_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &stmmac_ethtool_ops);
> +       netdev->ethtool_ops = &stmmac_ethtool_ops;
>  }
> diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c
> index 2ead877..38da73a 100644
> --- a/drivers/net/ethernet/tehuti/tehuti.c
> +++ b/drivers/net/ethernet/tehuti/tehuti.c
> @@ -2413,7 +2413,7 @@ static void bdx_set_ethtool_ops(struct net_device *netdev)
>                 .get_ethtool_stats = bdx_get_ethtool_stats,
>         };
>
> -       SET_ETHTOOL_OPS(netdev, &bdx_ethtool_ops);
> +       netdev->ethtool_ops = &bdx_ethtool_ops;
>  }
>
>  /**
> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
> index 36aa109..6ecab3c 100644
> --- a/drivers/net/ethernet/ti/cpsw.c
> +++ b/drivers/net/ethernet/ti/cpsw.c
> @@ -1975,7 +1975,7 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev,
>         ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
>
>         ndev->netdev_ops = &cpsw_netdev_ops;
> -       SET_ETHTOOL_OPS(ndev, &cpsw_ethtool_ops);
> +       ndev->ethtool_ops = &cpsw_ethtool_ops;
>         netif_napi_add(ndev, &priv_sl2->napi, cpsw_poll, CPSW_POLL_WEIGHT);
>
>         /* register the network device */
> @@ -2204,7 +2204,7 @@ static int cpsw_probe(struct platform_device *pdev)
>         ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
>
>         ndev->netdev_ops = &cpsw_netdev_ops;
> -       SET_ETHTOOL_OPS(ndev, &cpsw_ethtool_ops);
> +       ndev->ethtool_ops = &cpsw_ethtool_ops;
>         netif_napi_add(ndev, &priv->napi, cpsw_poll, CPSW_POLL_WEIGHT);
>
>         /* register the network device */
> diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
> index 8f0e69c..e76eae5 100644
> --- a/drivers/net/ethernet/ti/davinci_emac.c
> +++ b/drivers/net/ethernet/ti/davinci_emac.c
> @@ -1980,7 +1980,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
>         }
>
>         ndev->netdev_ops = &emac_netdev_ops;
> -       SET_ETHTOOL_OPS(ndev, &ethtool_ops);
> +       ndev->ethtool_ops = &ethtool_ops;
>         netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT);
>
>         /* register the network device */
> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> index 31e55fb..2170db5 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -715,7 +715,7 @@ static int netvsc_probe(struct hv_device *dev,
>         net->features = NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_SG | NETIF_F_RXCSUM |
>                         NETIF_F_IP_CSUM | NETIF_F_TSO;
>
> -       SET_ETHTOOL_OPS(net, &ethtool_ops);
> +       net->ethtool_ops = &ethtool_ops;
>         SET_NETDEV_DEV(net, &dev->device);
>
>         /* Notify the netvsc driver of the new device */
> diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
> index 63aa9d9..27536aa 100644
> --- a/drivers/net/ntb_netdev.c
> +++ b/drivers/net/ntb_netdev.c
> @@ -348,7 +348,7 @@ static int ntb_netdev_probe(struct pci_dev *pdev)
>         memcpy(ndev->dev_addr, ndev->perm_addr, ndev->addr_len);
>
>         ndev->netdev_ops = &ntb_netdev_ops;
> -       SET_ETHTOOL_OPS(ndev, &ntb_ethtool_ops);
> +       ndev->ethtool_ops = &ntb_ethtool_ops;
>
>         dev->qp = ntb_transport_create_queue(ndev, pdev, &ntb_netdev_handlers);
>         if (!dev->qp) {
> diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
> index a849718..dac7a0d 100644
> --- a/drivers/net/rionet.c
> +++ b/drivers/net/rionet.c
> @@ -494,7 +494,7 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
>         ndev->mtu = RIO_MAX_MSG_SIZE - 14;
>         ndev->features = NETIF_F_LLTX;
>         SET_NETDEV_DEV(ndev, &mport->dev);
> -       SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
> +       ndev->ethtool_ops = &rionet_ethtool_ops;
>
>         spin_lock_init(&rnet->lock);
>         spin_lock_init(&rnet->tx_lock);
> diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
> index 630caf4..8cfc3bb 100644
> --- a/drivers/net/usb/catc.c
> +++ b/drivers/net/usb/catc.c
> @@ -793,7 +793,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
>
>         netdev->netdev_ops = &catc_netdev_ops;
>         netdev->watchdog_timeo = TX_TIMEOUT;
> -       SET_ETHTOOL_OPS(netdev, &ops);
> +       netdev->ethtool_ops = &ops;
>
>         catc->usbdev = usbdev;
>         catc->netdev = netdev;
> diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
> index 660bd5e..a3a0586 100644
> --- a/drivers/net/usb/hso.c
> +++ b/drivers/net/usb/hso.c
> @@ -2425,7 +2425,7 @@ static void hso_net_init(struct net_device *net)
>         net->type = ARPHRD_NONE;
>         net->mtu = DEFAULT_MTU - 14;
>         net->tx_queue_len = 10;
> -       SET_ETHTOOL_OPS(net, &ops);
> +       net->ethtool_ops = &ops;
>
>         /* and initialize the semaphore */
>         spin_lock_init(&hso_net->net_lock);
> diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
> index 421934c..f725707 100644
> --- a/drivers/net/usb/ipheth.c
> +++ b/drivers/net/usb/ipheth.c
> @@ -524,7 +524,7 @@ static int ipheth_probe(struct usb_interface *intf,
>         usb_set_intfdata(intf, dev);
>
>         SET_NETDEV_DEV(netdev, &intf->dev);
> -       SET_ETHTOOL_OPS(netdev, &ops);
> +       netdev->ethtool_ops = &ops;
>
>         retval = register_netdev(netdev);
>         if (retval) {
> diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
> index a359d3b..dcb6d33 100644
> --- a/drivers/net/usb/kaweth.c
> +++ b/drivers/net/usb/kaweth.c
> @@ -1171,7 +1171,7 @@ err_fw:
>         netdev->netdev_ops = &kaweth_netdev_ops;
>         netdev->watchdog_timeo = KAWETH_TX_TIMEOUT;
>         netdev->mtu = le16_to_cpu(kaweth->configuration.segment_size);
> -       SET_ETHTOOL_OPS(netdev, &ops);
> +       netdev->ethtool_ops = &ops;
>
>         /* kaweth is zeroed as part of alloc_netdev */
>         INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl);
> diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
> index 03e8a15..f840802 100644
> --- a/drivers/net/usb/pegasus.c
> +++ b/drivers/net/usb/pegasus.c
> @@ -1159,7 +1159,7 @@ static int pegasus_probe(struct usb_interface *intf,
>
>         net->watchdog_timeo = PEGASUS_TX_TIMEOUT;
>         net->netdev_ops = &pegasus_netdev_ops;
> -       SET_ETHTOOL_OPS(net, &ops);
> +       net->ethtool_ops = &ops;
>         pegasus->mii.dev = net;
>         pegasus->mii.mdio_read = mdio_read;
>         pegasus->mii.mdio_write = mdio_write;
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index 3fbfb08..9f91c7a 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
> @@ -3452,7 +3452,7 @@ static int rtl8152_probe(struct usb_interface *intf,
>                               NETIF_F_TSO | NETIF_F_FRAGLIST |
>                               NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
>
> -       SET_ETHTOOL_OPS(netdev, &ops);
> +       netdev->ethtool_ops = &ops;
>         netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
>
>         tp->mii.dev = netdev;
> diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
> index da2c458..6e87e57 100644
> --- a/drivers/net/usb/rtl8150.c
> +++ b/drivers/net/usb/rtl8150.c
> @@ -878,7 +878,7 @@ static int rtl8150_probe(struct usb_interface *intf,
>         dev->netdev = netdev;
>         netdev->netdev_ops = &rtl8150_netdev_ops;
>         netdev->watchdog_timeo = RTL8150_TX_TIMEOUT;
> -       SET_ETHTOOL_OPS(netdev, &ops);
> +       netdev->ethtool_ops = &ops;
>         dev->intr_interval = 100;       /* 100ms */
>
>         if (!alloc_all_urbs(dev)) {
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 7b68746..3f83359 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1646,7 +1646,7 @@ static int virtnet_probe(struct virtio_device *vdev)
>         dev->netdev_ops = &virtnet_netdev;
>         dev->features = NETIF_F_HIGHDMA;
>
> -       SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops);
> +       dev->ethtool_ops = &virtnet_ethtool_ops;
>         SET_NETDEV_DEV(dev, &vdev->dev);
>
>         /* Do we support "hardware" checksums? */
> diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
> index 600ab56..00e1202 100644
> --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
> +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
> @@ -635,5 +635,5 @@ static const struct ethtool_ops vmxnet3_ethtool_ops = {
>
>  void vmxnet3_set_ethtool_ops(struct net_device *netdev)
>  {
> -       SET_ETHTOOL_OPS(netdev, &vmxnet3_ethtool_ops);
> +       netdev->ethtool_ops = &vmxnet3_ethtool_ops;
>  }
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index 82355d5..457359c 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -2706,7 +2706,7 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
>                 return -EEXIST;
>         }
>
> -       SET_ETHTOOL_OPS(dev, &vxlan_ethtool_ops);
> +       dev->ethtool_ops = &vxlan_ethtool_ops;
>
>         /* create an fdb entry for a valid default destination */
>         if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) {
> diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
> index 67db34e..52919ad 100644
> --- a/drivers/net/wireless/hostap/hostap_main.c
> +++ b/drivers/net/wireless/hostap/hostap_main.c
> @@ -882,7 +882,7 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,
>         dev->mtu = local->mtu;
>
>
> -       SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops);
> +       dev->ethtool_ops = &prism2_ethtool_ops;
>
>  }
>
> diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
> index ef05c5c..a755733 100644
> --- a/drivers/net/xen-netback/interface.c
> +++ b/drivers/net/xen-netback/interface.c
> @@ -386,7 +386,7 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
>                 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
>                 NETIF_F_TSO | NETIF_F_TSO6;
>         dev->features = dev->hw_features | NETIF_F_RXCSUM;
> -       SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops);
> +       dev->ethtool_ops = &xenvif_ethtool_ops;
>
>         dev->tx_queue_len = XENVIF_QUEUE_LENGTH;
>
> diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
> index 158b5e6..895355d 100644
> --- a/drivers/net/xen-netfront.c
> +++ b/drivers/net/xen-netfront.c
> @@ -1332,7 +1332,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
>           */
>         netdev->features |= netdev->hw_features;
>
> -       SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops);
> +       netdev->ethtool_ops = &xennet_ethtool_ops;
>         SET_NETDEV_DEV(netdev, &dev->dev);
>
>         netif_set_gso_max_size(netdev, XEN_NETIF_MAX_TX_SIZE - MAX_TCP_HEADER);
> diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
> index 8dea3f1..047b4da 100644
> --- a/drivers/s390/net/qeth_l2_main.c
> +++ b/drivers/s390/net/qeth_l2_main.c
> @@ -964,10 +964,9 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
>         card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
>         card->dev->mtu = card->info.initial_mtu;
>         card->dev->netdev_ops = &qeth_l2_netdev_ops;
> -       if (card->info.type != QETH_CARD_TYPE_OSN)
> -               SET_ETHTOOL_OPS(card->dev, &qeth_l2_ethtool_ops);
> -       else
> -               SET_ETHTOOL_OPS(card->dev, &qeth_l2_osn_ops);
> +       card->dev->ethtool_ops =
> +               (card->info.type != QETH_CARD_TYPE_OSN) ?
> +               &qeth_l2_ethtool_ops : &qeth_l2_osn_ops;
>         card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
>         card->info.broadcast_capable = 1;
>         qeth_l2_request_initial_mac(card);
> diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
> index 3524d34..0a59d24 100644
> --- a/drivers/s390/net/qeth_l3_main.c
> +++ b/drivers/s390/net/qeth_l3_main.c
> @@ -3298,7 +3298,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
>         card->dev->ml_priv = card;
>         card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
>         card->dev->mtu = card->info.initial_mtu;
> -       SET_ETHTOOL_OPS(card->dev, &qeth_l3_ethtool_ops);
> +       card->dev->ethtool_ops = &qeth_l3_ethtool_ops;
>         card->dev->features |=  NETIF_F_HW_VLAN_CTAG_TX |
>                                 NETIF_F_HW_VLAN_CTAG_RX |
>                                 NETIF_F_HW_VLAN_CTAG_FILTER;
> diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
> index d329cf3..15e0f4d 100644
> --- a/drivers/staging/et131x/et131x.c
> +++ b/drivers/staging/et131x/et131x.c
> @@ -4604,7 +4604,7 @@ static int et131x_pci_setup(struct pci_dev *pdev,
>         netdev->netdev_ops     = &et131x_netdev_ops;
>
>         SET_NETDEV_DEV(netdev, &pdev->dev);
> -       SET_ETHTOOL_OPS(netdev, &et131x_ethtool_ops);
> +       netdev->ethtool_ops = &et131x_ethtool_ops;
>
>         adapter = et131x_adapter_init(netdev, pdev);
>
> diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
> index d6421b9..a6158be 100644
> --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
> +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
> @@ -2249,7 +2249,7 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link,
>
>         ft1000InitProc(dev);
>         ft1000_card_present = 1;
> -       SET_ETHTOOL_OPS(dev, &ops);
> +       dev->ethtool_ops = &ops;
>         printk(KERN_INFO "ft1000: %s: addr 0x%04lx irq %d, MAC addr %pM\n",
>                         dev->name, dev->base_addr, dev->irq, dev->dev_addr);
>         return dev;
> diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c
> index c83e337..9d95761 100644
> --- a/drivers/staging/netlogic/xlr_net.c
> +++ b/drivers/staging/netlogic/xlr_net.c
> @@ -1066,7 +1066,7 @@ static int xlr_net_probe(struct platform_device *pdev)
>         xlr_set_rx_mode(ndev);
>
>         priv->num_rx_desc += MAX_NUM_DESC_SPILL;
> -       SET_ETHTOOL_OPS(ndev, &xlr_ethtool_ops);
> +       ndev->ethtool_ops = &xlr_ethtool_ops;
>         SET_NETDEV_DEV(ndev, &pdev->dev);
>
>         /* Common registers, do one time initialization */
> diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
> index ff7214a..da9dd6b 100644
> --- a/drivers/staging/octeon/ethernet.c
> +++ b/drivers/staging/octeon/ethernet.c
> @@ -469,7 +469,7 @@ int cvm_oct_common_init(struct net_device *dev)
>
>         /* We do our own locking, Linux doesn't need to */
>         dev->features |= NETIF_F_LLTX;
> -       SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
> +       dev->ethtool_ops = &cvm_oct_ethtool_ops;
>
>         cvm_oct_phy_setup_device(dev);
>         cvm_oct_set_mac_filter(dev);
> diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
> index b7d4f82..ce8e281 100644
> --- a/drivers/usb/gadget/u_ether.c
> +++ b/drivers/usb/gadget/u_ether.c
> @@ -793,7 +793,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
>
>         net->netdev_ops = &eth_netdev_ops;
>
> -       SET_ETHTOOL_OPS(net, &ops);
> +       net->ethtool_ops = &ops;
>
>         dev->gadget = g;
>         SET_NETDEV_DEV(net, &g->dev);
> @@ -850,7 +850,7 @@ struct net_device *gether_setup_name_default(const char *netname)
>
>         net->netdev_ops = &eth_netdev_ops;
>
> -       SET_ETHTOOL_OPS(net, &ops);
> +       net->ethtool_ops = &ops;
>         SET_NETDEV_DEVTYPE(net, &gadget_type);
>
>         return net;
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 7ed3a3a..06071f7 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -56,9 +56,6 @@ struct device;
>  struct phy_device;
>  /* 802.11 specific */
>  struct wireless_dev;
> -                                       /* source back-compat hooks */
> -#define SET_ETHTOOL_OPS(netdev,ops) \
> -       ( (netdev)->ethtool_ops = (ops) )
>
>  void netdev_set_default_ethtool_ops(struct net_device *dev,
>                                     const struct ethtool_ops *ops);
> diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
> index 744a59b..e7ee65d 100644
> --- a/net/batman-adv/soft-interface.c
> +++ b/net/batman-adv/soft-interface.c
> @@ -884,7 +884,7 @@ static void batadv_softif_init_early(struct net_device *dev)
>         /* generate random address */
>         eth_hw_addr_random(dev);
>
> -       SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops);
> +       dev->ethtool_ops = &batadv_ethtool_ops;
>
>         memset(priv, 0, sizeof(*priv));
>  }
> diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
> index 3e2da2c..9212015 100644
> --- a/net/bridge/br_device.c
> +++ b/net/bridge/br_device.c
> @@ -348,7 +348,7 @@ void br_dev_setup(struct net_device *dev)
>
>         dev->netdev_ops = &br_netdev_ops;
>         dev->destructor = br_dev_free;
> -       SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
> +       dev->ethtool_ops = &br_ethtool_ops;
>         SET_NETDEV_DEVTYPE(dev, &br_type);
>         dev->tx_queue_len = 0;
>         dev->priv_flags = IFF_EBRIDGE;
> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
> index 02c0e17..64c5af0 100644
> --- a/net/dsa/slave.c
> +++ b/net/dsa/slave.c
> @@ -346,7 +346,7 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent,
>                 return slave_dev;
>
>         slave_dev->features = master->vlan_features;
> -       SET_ETHTOOL_OPS(slave_dev, &dsa_slave_ethtool_ops);
> +       slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
>         eth_hw_addr_inherit(slave_dev, master);
>         slave_dev->tx_queue_len = 0;
>
> diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
> index 729c687..789af92 100644
> --- a/net/openvswitch/vport-internal_dev.c
> +++ b/net/openvswitch/vport-internal_dev.c
> @@ -130,7 +130,7 @@ static void do_setup(struct net_device *netdev)
>         netdev->priv_flags &= ~IFF_TX_SKB_SHARING;
>         netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
>         netdev->destructor = internal_dev_destructor;
> -       SET_ETHTOOL_OPS(netdev, &internal_dev_ethtool_ops);
> +       netdev->ethtool_ops = &internal_dev_ethtool_ops;
>         netdev->tx_queue_len = 0;
>
>         netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST |
>



-- 
Peter

^ permalink raw reply

* Re: [PATCH v2 3/4] KVM: PPC: Alow kvmppc_get_last_inst() to fail
From: Alexander Graf @ 2014-05-08 13:31 UTC (permalink / raw)
  To: mihai.caraman@freescale.com
  Cc: linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org,
	kvm-ppc@vger.kernel.org
In-Reply-To: <f5c0d1ca058346edb91f347eeb399cac@BY2PR03MB508.namprd03.prod.outlook.com>

On 05/06/2014 09:06 PM, mihai.caraman@freescale.com wrote:
>> -----Original Message-----
>> From: Alexander Graf [mailto:agraf@suse.de]
>> Sent: Friday, May 02, 2014 12:55 PM
>> To: Caraman Mihai Claudiu-B02008
>> Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; linuxppc-
>> dev@lists.ozlabs.org
>> Subject: Re: [PATCH v2 3/4] KVM: PPC: Alow kvmppc_get_last_inst() to fail
>>
>> On 05/01/2014 02:45 AM, Mihai Caraman wrote:
> ...
>>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h
>> b/arch/powerpc/include/asm/kvm_ppc.h
>>> index 4096f16..6e7c358 100644
>>> --- a/arch/powerpc/include/asm/kvm_ppc.h
>>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
>>> @@ -72,6 +72,8 @@ extern int kvmppc_sanity_check(struct kvm_vcpu
>> *vcpu);
>>>    extern int kvmppc_subarch_vcpu_init(struct kvm_vcpu *vcpu);
>>>    extern void kvmppc_subarch_vcpu_uninit(struct kvm_vcpu *vcpu);
>>>
>>> +extern int kvmppc_get_last_inst(struct kvm_vcpu *vcpu, u32 *inst);
>> Phew. Moving this into a separate function sure has some performance
>> implications. Was there no way to keep it in a header?
>>
>> You could just move it into its own .h file which we include after
>> kvm_ppc.h. That way everything's available. That would also help me a
>> lot with the little endian port where I'm also struggling with header
>> file inclusion order and kvmppc_need_byteswap().
> Great, I will do this.
>
>>> diff --git a/arch/powerpc/kvm/book3s_pr.c
>> b/arch/powerpc/kvm/book3s_pr.c
>>> index c5c052a..b7fffd1 100644
>>> --- a/arch/powerpc/kvm/book3s_pr.c
>>> +++ b/arch/powerpc/kvm/book3s_pr.c
>>> @@ -608,12 +608,9 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu,
>> ulong msr)
>>>    static int kvmppc_read_inst(struct kvm_vcpu *vcpu)
>>>    {
>>> -	ulong srr0 = kvmppc_get_pc(vcpu);
>>> -	u32 last_inst = kvmppc_get_last_inst(vcpu);
>>> -	int ret;
>>> +	u32 last_inst;
>>>
>>> -	ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &last_inst, false);
>>> -	if (ret == -ENOENT) {
>>> +	if (kvmppc_get_last_inst(vcpu, &last_inst) == -ENOENT) {
>> ENOENT?
> You have to tell us :) Why does kvmppc_ld() mix emulation_result
> enumeration with generic errors? Do you want to change that and
> use EMULATE_FAIL instead?

Haha you're right. Man, this code sucks :). No, leave it be for now.

>
>>>    		ulong msr = vcpu->arch.shared->msr;
>>>
>>>    		msr = kvmppc_set_field(msr, 33, 33, 1);
>>> @@ -867,15 +864,18 @@ int kvmppc_handle_exit_pr(struct kvm_run *run,
>> struct kvm_vcpu *vcpu,
>>>    	{
>>>    		enum emulation_result er;
>>>    		ulong flags;
>>> +		u32 last_inst;
>>>
>>>    program_interrupt:
>>>    		flags = vcpu->arch.shadow_srr1 & 0x1f0000ull;
>>> +		kvmppc_get_last_inst(vcpu, &last_inst);
>> No check for the return value?
> Should we queue a program exception and resume guest?

Depends on the return code. We need to be able to handle EMULATE_AGAIN 
everywhere now.

>
>>>    		if (vcpu->arch.shared->msr & MSR_PR) {
>>>    #ifdef EXIT_DEBUG
>>> -			printk(KERN_INFO "Userspace triggered 0x700 exception
>> at 0x%lx (0x%x)\n", kvmppc_get_pc(vcpu), kvmppc_get_last_inst(vcpu));
>>> +			pr_info("Userspace triggered 0x700 exception at\n"
>>> +			    "0x%lx (0x%x)\n", kvmppc_get_pc(vcpu), last_inst);
>>>    #endif
>>> -			if ((kvmppc_get_last_inst(vcpu) & 0xff0007ff) !=
>>> +			if ((last_inst & 0xff0007ff) !=
>>>    			    (INS_DCBZ & 0xfffffff7)) {
>>>    				kvmppc_core_queue_program(vcpu, flags);
>>>    				r = RESUME_GUEST;
>>> @@ -894,7 +894,7 @@ program_interrupt:
>>>    			break;
>>>    		case EMULATE_FAIL:
>>>    			printk(KERN_CRIT "%s: emulation at %lx failed
>> (%08x)\n",
>>> -			       __func__, kvmppc_get_pc(vcpu),
>> kvmppc_get_last_inst(vcpu));
>>> +			       __func__, kvmppc_get_pc(vcpu), last_inst);
>>>    			kvmppc_core_queue_program(vcpu, flags);
>>>    			r = RESUME_GUEST;
>>>    			break;
>>> @@ -911,8 +911,12 @@ program_interrupt:
>>>    		break;
>>>    	}
>>>    	case BOOK3S_INTERRUPT_SYSCALL:
>>> +	{
>>> +		u32 last_sc;
>>> +
>>> +		kvmppc_get_last_sc(vcpu, &last_sc);
>> No check for the return value?
> The existing code does not handle KVM_INST_FETCH_FAILED.
> How should we continue if papr is enabled and last_sc fails?

I'd say go back into the guest and try again ;). Keep in mind that sc 
already sets srr0 to pc + 4, so we need to subtract 4 from pc and then 
go back into the guest.

>
>>>    		if (vcpu->arch.papr_enabled &&
>>> -		    (kvmppc_get_last_sc(vcpu) == 0x44000022) &&
>>> +		    (last_sc == 0x44000022) &&
>>>    		    !(vcpu->arch.shared->msr & MSR_PR)) {
>>>    			/* SC 1 papr hypercalls */
>>>    			ulong cmd = kvmppc_get_gpr(vcpu, 3);
>>> @@ -957,6 +961,7 @@ program_interrupt:
>>>    			r = RESUME_GUEST;
>>>    		}
>>>    		break;
>>> +	}
>>>    	case BOOK3S_INTERRUPT_FP_UNAVAIL:
>>>    	case BOOK3S_INTERRUPT_ALTIVEC:
>>>    	case BOOK3S_INTERRUPT_VSX:
>>> @@ -985,15 +990,20 @@ program_interrupt:
>>>    		break;
>>>    	}
>>>    	case BOOK3S_INTERRUPT_ALIGNMENT:
>>> +	{
>>> +		u32 last_inst;
>>> +
>>>    		if (kvmppc_read_inst(vcpu) == EMULATE_DONE) {
>>> -			vcpu->arch.shared->dsisr = kvmppc_alignment_dsisr(vcpu,
>>> -				kvmppc_get_last_inst(vcpu));
>>> -			vcpu->arch.shared->dar = kvmppc_alignment_dar(vcpu,
>>> -				kvmppc_get_last_inst(vcpu));
>>> +			kvmppc_get_last_inst(vcpu, &last_inst);
>> I think with an error returning kvmppc_get_last_inst we can just use
>> completely get rid of kvmppc_read_inst() and only use
>> kvmppc_get_last_inst() instead.
> The only purpose of kvmppc_read_inst() function is to generate an
> instruction storage interrupt in case of load failure. It is also called
> from kvmppc_check_ext(). Do you suggest to get rid of this logic? Or to
> duplicate it in order to avoid kvmppc_get_last_inst() redundant call?

I don't think we need that logic. If we get EMULATE_AGAIN, we just have 
to make sure we go back into the guest. No need to inject an ISI into 
the guest - it'll do that all by itself.


Alex

^ permalink raw reply

* Re: [PATCH v2] powerpc/fsl: Added binding for Freescale CoreNet coherency fabric (CCF)
From: Kumar Gala @ 2014-05-08 14:00 UTC (permalink / raw)
  To: Diana Craciun; +Cc: scottwood, devicetree, linuxppc-dev
In-Reply-To: <1397833917-12611-1-git-send-email-diana.craciun@freescale.com>


On Apr 18, 2014, at 8:11 AM, Diana Craciun <diana.craciun@freescale.com> =
wrote:

> From: Diana Craciun <Diana.Craciun@freescale.com>
>=20
> The CoreNet coherency fabric is a fabric-oriented, conectivity
> infrastructure that enables the implementation of coherent, multicore
> systems. The CCF acts as a central interconnect for cores,
> platform-level caches, memory subsystem, peripheral devices and I/O =
host
> bridges in the system.
>=20
> Signed-off-by: Diana Craciun <Diana.Craciun@freescale.com>
> ---
> .../devicetree/bindings/powerpc/fsl/ccf.txt        | 36 =
++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
> create mode 100644 =
Documentation/devicetree/bindings/powerpc/fsl/ccf.txt
>=20
> diff --git a/Documentation/devicetree/bindings/powerpc/fsl/ccf.txt =
b/Documentation/devicetree/bindings/powerpc/fsl/ccf.txt
> new file mode 100644
> index 0000000..f0b7143
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/powerpc/fsl/ccf.txt
> @@ -0,0 +1,36 @@
> +Freescale CoreNet Coherency Fabric(CCF) Device Tree Binding
> +
> +DESCRIPTION
> +
> +The CoreNet coherency fabric is a fabric-oriented, connectivity =
infrastructure
> +that enables the implementation of coherent, multicore systems.
> +
> +Required properties:
> +
> +- compatible : <string>
> +		Must include "fsl,corenetX-cf", "fsl,corenet-cf" - =
CoreNet coherency=20
> +		fabric version X

Can we make this =91fsl,corenet-vX-cf=92.

corenet-v1-cf/corenet-v2-cf looks nicer than corenet1-cf/corenet2-cf

> +
> +- reg : <prop-encoded-array>
> +		A standard property. Represents the CCF registers.
> +
> +- interrupts : <prop-encoded-array>
> +		Interrupt mapping for CCF error interrupt.
> +
> +- fsl,ccf-num-csdids: <u32>
> +		Specifies the number of Coherency Subdomain ID Port =
Mapping
> +		Registers that are supported by the CCF.
> +
> +- fsl,ccf-num-snoopids: <u32>
> +		Specifies the number of Snoop ID Port Mapping Registers =
that
> +		are supported by CCF.
> +
> +Example:
> +
> +	corenet-cf@18000 {
> +		compatible =3D "fsl,corenet2-cf", "fsl,corenet-cf";
> +		reg =3D <0x18000 0x1000>;
> +		interrupts =3D <16 2 1 31>;
> +		fsl,ccf-num-csdids =3D <32>;
> +		fsl,ccf-num-snoopids =3D <32>;
> +	};
> --=20
> 1.7.11.7
>=20
>=20
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH v2] powerpc/fsl: Added binding for Freescale CoreNet coherency fabric (CCF)
From: Scott Wood @ 2014-05-08 23:18 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Diana Craciun, devicetree, linuxppc-dev
In-Reply-To: <6CE62BBF-BFF4-4F2C-8EFF-B6F87EE6EEE9@kernel.crashing.org>

On Thu, 2014-05-08 at 07:00 -0700, Kumar Gala wrote:
> On Apr 18, 2014, at 8:11 AM, Diana Craciun <diana.craciun@freescale.com> wrote:
> 
> > From: Diana Craciun <Diana.Craciun@freescale.com>
> > 
> > The CoreNet coherency fabric is a fabric-oriented, conectivity
> > infrastructure that enables the implementation of coherent, multicore
> > systems. The CCF acts as a central interconnect for cores,
> > platform-level caches, memory subsystem, peripheral devices and I/O host
> > bridges in the system.
> > 
> > Signed-off-by: Diana Craciun <Diana.Craciun@freescale.com>
> > ---
> > .../devicetree/bindings/powerpc/fsl/ccf.txt        | 36 ++++++++++++++++++++++
> > 1 file changed, 36 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/ccf.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/powerpc/fsl/ccf.txt b/Documentation/devicetree/bindings/powerpc/fsl/ccf.txt
> > new file mode 100644
> > index 0000000..f0b7143
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/powerpc/fsl/ccf.txt
> > @@ -0,0 +1,36 @@
> > +Freescale CoreNet Coherency Fabric(CCF) Device Tree Binding
> > +
> > +DESCRIPTION
> > +
> > +The CoreNet coherency fabric is a fabric-oriented, connectivity infrastructure
> > +that enables the implementation of coherent, multicore systems.
> > +
> > +Required properties:
> > +
> > +- compatible : <string>
> > +		Must include "fsl,corenetX-cf", "fsl,corenet-cf" - CoreNet coherency 
> > +		fabric version X
> 
> Can we make this ‘fsl,corenet-vX-cf’.
> 
> corenet-v1-cf/corenet-v2-cf looks nicer than corenet1-cf/corenet2-cf

How important is this?  We've already got corenet2-cf in SDK device
trees -- and while I know that's not binding on upstream in any way,
it's purely a cosmetic change.  Even if you disregard the SDK, is this
really worth going back and amending several pending patches over
(including a driver that I was waiting for this binding to settle before
sending)?  

FWIW, we have other instances of "deviceN", such as "fsl,etsec2",
"fsl,cpm2-<foo>","fsl,usb2-<foo>", and "fsl,elo3-dma".  We also call it
"corenet2" in U-Boot a lot.

If we must change it, I'd prefer "fsl,corenet-cf-vX.0".

-Scott

^ permalink raw reply

* [PATCH] powerpc: irq work racing with timer interrupt can result in timer interrupt hang
From: Anton Blanchard @ 2014-05-09  7:47 UTC (permalink / raw)
  To: benh, paulus, mpe, paulmck; +Cc: linuxppc-dev

I am seeing an issue where a CPU running perf eventually hangs.
Traces show timer interrupts happening every 4 seconds even
when a userspace task is running on the CPU. /proc/timer_list
also shows pending hrtimers have not run in over an hour,
including the scheduler.

Looking closer, decrementers_next_tb is getting set to
0xffffffffffffffff, and at that point we will never take
a timer interrupt again.

In __timer_interrupt() we set decrementers_next_tb to
0xffffffffffffffff and rely on ->event_handler to update it:

        *next_tb = ~(u64)0;
        if (evt->event_handler)
                evt->event_handler(evt);

In this case ->event_handler is hrtimer_interrupt. This will eventually
call back through the clockevents code with the next event to be
programmed:

static int decrementer_set_next_event(unsigned long evt,
                                      struct clock_event_device *dev)
{
        /* Don't adjust the decrementer if some irq work is pending */
        if (test_irq_work_pending())
                return 0;
        __get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt;

If irq work came in between these two points, we will return
before updating decrementers_next_tb and we never process a timer
interrupt again.

This looks to have been introduced by 0215f7d8c53f (powerpc: Fix races
with irq_work). Fix it by removing the early exit and relying on
code later on in the function to force an early decrementer:

       /* We may have raced with new irq work */
       if (test_irq_work_pending())
               set_dec(1);

Signed-off-by: Anton Blanchard <anton@samba.org>
Cc: stable@vger.kernel.org # 3.14+
---

diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 122a580..4f0b676 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -813,9 +888,6 @@ static void __init clocksource_init(void)
 static int decrementer_set_next_event(unsigned long evt,
 				      struct clock_event_device *dev)
 {
-	/* Don't adjust the decrementer if some irq work is pending */
-	if (test_irq_work_pending())
-		return 0;
 	__get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt;
 	set_dec(evt);
 

^ permalink raw reply related

* [PATCH RFC v2 00/10] EEH Support for VFIO PCI devices on PowerKVM guest
From: Gavin Shan @ 2014-05-09  7:49 UTC (permalink / raw)
  To: linuxppc-dev, kvm-ppc; +Cc: aik, alex.williamson, qiudayu, Gavin Shan

The series of patches intends to support EEH for PCI devices, which are
passed through to PowerKVM based guest via VFIO. The implementation is
straightforward based on the issues or problems we have to resolve to
support EEH for PowerKVM based guest.

- Emulation for EEH RTAS requests. All EEH RTAS requests goes to QEMU firstly.
  If QEMU can't handle it, the request will be sent to host via newly introduced
  VFIO container IOCTL command (VFIO_EEH_INFO) and gets handled in host kernel.

- The error injection infrastructure need support request from the userland
  utility "errinjct" and PowerKVM based guest. The userland utility "errinjct"
  works on pSeries platform well with dedicated syscall, which helps invoking
  RTAS service to fulfil error injection in kernel. From the perspective, it's
  reasonable to extend the syscall to support PowerNV platform so that OPAL call
  can be invoked in host kernel for injecting errors. The data transported
  between userland and kerenl is still following "struct rtas_args" for both
  cases of PowerNV (OPAL) and pSeries (RTAS).

The series of patches requires corresponding firmware changes from Mike Qiu to
support error injection and QEMU changes to support EEH for guest. QEMU patchset
will be sent separately.

Change log
==========
v1 -> v2:
	* EEH RTAS requests are routed to QEMU, and then possiblly to host kerenl.
	  The mechanism KVM in-kernel handling is dropped.
	* Error injection is reimplemented based syscall, instead of KVM in-kerenl
	  handling. The logic for error injection token management is moved to
	  QEMU. The error injection request is routed to QEMU and then possiblly
	  to host kernel.

Testing on P7
=============

- Emulex adapter

Testing on P8
=============

- Need more testing after design is finalized.

-----

Gavin Shan (10):
  drivers/vfio: Introduce CONFIG_VFIO_EEH
  powerpc/eeh: Info to trace passed devices
  powerpc/eeh: Search EEH device by guest address
  powerpc/eeh: Search EEH PE by guest address
  drivers/vfio: New IOCTL command VFIO_EEH_INFO
  powerpc/eeh: Avoid event on passed PE
  powerpc/powernv: Sync OPAL header file with firmware
  powerpc: Extend syscall ppc_rtas()
  powerpc/powernv: Implement ppc_call_opal()
  powerpc/powernv: Error injection infrastructure

arch/powerpc/include/asm/eeh.h                 |  52 +++++++++++++
arch/powerpc/include/asm/opal.h                |  74 +++++++++++++++++-
arch/powerpc/include/asm/rtas.h                |  10 ++-
arch/powerpc/include/asm/syscalls.h            |   2 +-
arch/powerpc/include/asm/systbl.h              |   2 +-
arch/powerpc/include/uapi/asm/unistd.h         |   2 +-
arch/powerpc/kernel/eeh.c                      |   8 ++
arch/powerpc/kernel/eeh_pe.c                   |  80 +++++++++++++++++++
arch/powerpc/kernel/rtas.c                     |  57 +++-----------
arch/powerpc/kernel/syscalls.c                 |  50 ++++++++++++
arch/powerpc/platforms/powernv/Makefile        |   3 +-
arch/powerpc/platforms/powernv/eeh-ioda.c      |   3 +-
arch/powerpc/platforms/powernv/eeh-vfio.c      | 584 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
arch/powerpc/platforms/powernv/errinject.c     | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++
arch/powerpc/platforms/powernv/opal-wrappers.S |   1 +
arch/powerpc/platforms/powernv/opal.c          |  93 ++++++++++++++++++++++
drivers/vfio/Kconfig                           |   6 ++
drivers/vfio/vfio_iommu_spapr_tce.c            |  12 +++
include/uapi/linux/vfio.h                      |  61 +++++++++++++++
kernel/sys_ni.c                                |   2 +-
20 files changed, 1271 insertions(+), 53 deletions(-)
create mode 100644 arch/powerpc/platforms/powernv/eeh-vfio.c
create mode 100644 arch/powerpc/platforms/powernv/errinject.c

Thanks,
Gavin

^ permalink raw reply

* [PATCH 06/10] powerpc/eeh: Avoid event on passed PE
From: Gavin Shan @ 2014-05-09  7:49 UTC (permalink / raw)
  To: linuxppc-dev, kvm-ppc; +Cc: aik, alex.williamson, qiudayu, Gavin Shan
In-Reply-To: <1399621782-23281-1-git-send-email-gwshan@linux.vnet.ibm.com>

If we detects frozen state on PE that has been passed to guest, we
needn't handle it. Instead, we rely on the guest to detect and recover
it. The patch avoid EEH event on the frozen passed PE so that the guest
can have chance to handle that.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/eeh.c                 | 8 ++++++++
 arch/powerpc/platforms/powernv/eeh-ioda.c | 3 ++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 9c6b899..6543f05 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -400,6 +400,14 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
 	if (ret > 0)
 		return ret;
 
+	/*
+	 * If the PE has been passed to guest, we won't check the
+	 * state. Instead, let the guest handle it if the PE has
+	 * been frozen.
+	 */
+	if (eeh_pe_passed(pe))
+		return 0;
+
 	/* If we already have a pending isolation event for this
 	 * slot, we know it's bad already, we don't need to check.
 	 * Do this checking under a lock; as multiple PCI devices
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index 1b5982f..03a3ed2 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -890,7 +890,8 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
 				opal_pci_eeh_freeze_clear(phb->opal_id, frozen_pe_no,
 					OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
 				ret = EEH_NEXT_ERR_NONE;
-			} else if ((*pe)->state & EEH_PE_ISOLATED) {
+			} else if ((*pe)->state & EEH_PE_ISOLATED ||
+				   eeh_pe_passed(*pe)) {
 				ret = EEH_NEXT_ERR_NONE;
 			} else {
 				pr_err("EEH: Frozen PHB#%x-PE#%x (%s) detected\n",
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 02/10] powerpc/eeh: Info to trace passed devices
From: Gavin Shan @ 2014-05-09  7:49 UTC (permalink / raw)
  To: linuxppc-dev, kvm-ppc; +Cc: aik, alex.williamson, qiudayu, Gavin Shan
In-Reply-To: <1399621782-23281-1-git-send-email-gwshan@linux.vnet.ibm.com>

The address of passed PCI devices (domain:bus:slot:func) might be
quite different from the perspective of host and guest. We have to
trace the address mapping so that we can emulate EEH RTAS requests
from guest. The patch introduces additional fields to eeh_pe and
eeh_dev for the purpose.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/eeh.h | 46 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 7782056..3268692 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -48,6 +48,14 @@ struct device_node;
 #define EEH_PE_RST_HOLD_TIME		250
 #define EEH_PE_RST_SETTLE_TIME		1800
 
+#ifdef CONFIG_VFIO_EEH
+struct eeh_vfio_pci_addr {
+	uint64_t	buid;		/* PHB BUID			*/
+	uint16_t	bdn;		/* Bus/Device/Function number	*/
+	uint32_t	pe_addr;	/* PE configuration address	*/
+};
+#endif /* CONFIG_VFIO_EEH */
+
 /*
  * The struct is used to trace PE related EEH functionality.
  * In theory, there will have one instance of the struct to
@@ -72,6 +80,7 @@ struct device_node;
 #define EEH_PE_RESET		(1 << 2)	/* PE reset in progress	*/
 
 #define EEH_PE_KEEP		(1 << 8)	/* Keep PE on hotplug	*/
+#define EEH_PE_PASSTHROUGH	(1 << 9)	/* PE owned by guest	*/
 
 struct eeh_pe {
 	int type;			/* PE type: PHB/Bus/Device	*/
@@ -85,6 +94,9 @@ struct eeh_pe {
 	struct timeval tstamp;		/* Time on first-time freeze	*/
 	int false_positives;		/* Times of reported #ff's	*/
 	struct eeh_pe *parent;		/* Parent PE			*/
+#ifdef CONFIG_VFIO_EEH
+	struct eeh_vfio_pci_addr gaddr;	/* Address in guest		*/
+#endif
 	struct list_head child_list;	/* Link PE to the child list	*/
 	struct list_head edevs;		/* Link list of EEH devices	*/
 	struct list_head child;		/* Child PEs			*/
@@ -93,6 +105,21 @@ struct eeh_pe {
 #define eeh_pe_for_each_dev(pe, edev, tmp) \
 		list_for_each_entry_safe(edev, tmp, &pe->edevs, list)
 
+static inline bool eeh_pe_passed(struct eeh_pe *pe)
+{
+	return pe ? !!(pe->state & EEH_PE_PASSTHROUGH) : false;
+}
+
+static inline void eeh_pe_set_passed(struct eeh_pe *pe, bool passed)
+{
+	if (pe) {
+		if (passed)
+			pe->state |= EEH_PE_PASSTHROUGH;
+		else
+			pe->state &= ~EEH_PE_PASSTHROUGH;
+	}
+}
+
 /*
  * The struct is used to trace EEH state for the associated
  * PCI device node or PCI device. In future, it might
@@ -110,6 +137,7 @@ struct eeh_pe {
 #define EEH_DEV_SYSFS		(1 << 9)	/* Sysfs created	*/
 #define EEH_DEV_REMOVED		(1 << 10)	/* Removed permanently	*/
 #define EEH_DEV_FRESET		(1 << 11)	/* Fundamental reset	*/
+#define EEH_DEV_PASSTHROUGH	(1 << 12)	/* Owned by guest	*/
 
 struct eeh_dev {
 	int mode;			/* EEH mode			*/
@@ -126,6 +154,9 @@ struct eeh_dev {
 	struct device_node *dn;		/* Associated device node	*/
 	struct pci_dev *pdev;		/* Associated PCI device	*/
 	struct pci_bus *bus;		/* PCI bus for partial hotplug	*/
+#ifdef CONFIG_VFIO_EEH
+	struct eeh_vfio_pci_addr gaddr;	/* Address in guest		*/
+#endif
 };
 
 static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev)
@@ -138,6 +169,21 @@ static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev)
 	return edev ? edev->pdev : NULL;
 }
 
+static inline bool eeh_dev_passed(struct eeh_dev *dev)
+{
+	return dev ? !!(dev->mode & EEH_DEV_PASSTHROUGH) : false;
+}
+
+static inline void eeh_dev_set_passed(struct eeh_dev *dev, bool passed)
+{
+	if (dev) {
+		if (passed)
+			dev->mode |= EEH_DEV_PASSTHROUGH;
+		else
+			dev->mode &= ~EEH_DEV_PASSTHROUGH;
+	}
+}
+
 /* Return values from eeh_ops::next_error */
 enum {
 	EEH_NEXT_ERR_NONE = 0,
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 01/10] drivers/vfio: Introduce CONFIG_VFIO_EEH
From: Gavin Shan @ 2014-05-09  7:49 UTC (permalink / raw)
  To: linuxppc-dev, kvm-ppc; +Cc: aik, alex.williamson, qiudayu, Gavin Shan
In-Reply-To: <1399621782-23281-1-git-send-email-gwshan@linux.vnet.ibm.com>

The patch introduces CONFIG_VFIO_EEH for more IOCTL commands on
tce_iommu_driver_ops to support EEH funtionality for PCI devices
that are passed through from host to guest.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 drivers/vfio/Kconfig | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
index af7b204..4f3293b 100644
--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -8,11 +8,17 @@ config VFIO_IOMMU_SPAPR_TCE
 	depends on VFIO && SPAPR_TCE_IOMMU
 	default n
 
+config VFIO_EEH
+	tristate
+	depends on EEH && VFIO_IOMMU_SPAPR_TCE
+	default n
+
 menuconfig VFIO
 	tristate "VFIO Non-Privileged userspace driver framework"
 	depends on IOMMU_API
 	select VFIO_IOMMU_TYPE1 if X86
 	select VFIO_IOMMU_SPAPR_TCE if (PPC_POWERNV || PPC_PSERIES)
+	select VFIO_EEH if PPC_POWERNV
 	select ANON_INODES
 	help
 	  VFIO provides a framework for secure userspace device drivers.
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 03/10] powerpc/eeh: Search EEH device by guest address
From: Gavin Shan @ 2014-05-09  7:49 UTC (permalink / raw)
  To: linuxppc-dev, kvm-ppc; +Cc: aik, alex.williamson, qiudayu, Gavin Shan
In-Reply-To: <1399621782-23281-1-git-send-email-gwshan@linux.vnet.ibm.com>

The patch introduces function eeh_vfio_dev_get() to search the EEH
device according to its guest address, which is made up of PHB BUID,
bus, slot and function number. The function is useful in the backends
for EEH RTAS emulation.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/eeh.h |  5 +++++
 arch/powerpc/kernel/eeh_pe.c   | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 3268692..8ffaf39 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -381,6 +381,11 @@ static inline void eeh_remove_device(struct pci_dev *dev) { }
 #define EEH_IO_ERROR_VALUE(size) (-1UL)
 #endif /* CONFIG_EEH */
 
+
+#ifdef CONFIG_VFIO_EEH
+struct eeh_dev *eeh_vfio_dev_get(struct eeh_vfio_pci_addr *addr);
+#endif /* CONFIG_VFIO_EEH */
+
 #ifdef CONFIG_PPC64
 /*
  * MMIO read/write operations with EEH support.
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index fbd01eb..d09f055 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -248,6 +248,48 @@ struct eeh_pe *eeh_pe_get(struct eeh_dev *edev)
 	return pe;
 }
 
+#ifdef CONFIG_VFIO_EEH
+static void *__eeh_vfio_dev_get(void *data, void *flag)
+{
+	struct eeh_pe *pe = (struct eeh_pe *)data;
+	struct eeh_vfio_pci_addr *addr = (struct eeh_vfio_pci_addr *)flag;
+	struct eeh_dev *edev, *tmp;
+
+	eeh_pe_for_each_dev(pe, edev, tmp) {
+		if (!eeh_dev_passed(edev))
+			continue;
+
+		/* Comparing the address in the guest */
+		if (addr->buid == edev->gaddr.buid &&
+		    addr->bdn  == edev->gaddr.bdn)
+			return edev;
+	}
+
+	return NULL;
+}
+
+/**
+ * eeh_vfio_dev_get - Search EEH device based on guest's address
+ * @addr: EEH device guest address
+ *
+ * Search the EEH device according to its guest's address, which
+ * is made up of PHB BUID, and PCI config address.
+ */
+struct eeh_dev *eeh_vfio_dev_get(struct eeh_vfio_pci_addr *addr)
+{
+	struct eeh_pe *root;
+	struct eeh_dev *edev;
+
+	list_for_each_entry(root, &eeh_phb_pe, child) {
+		edev = eeh_pe_traverse(root, __eeh_vfio_dev_get, addr);
+		if (edev)
+			return edev;
+	}
+
+	return NULL;
+}
+#endif /* CONFIG_VFIO_EEH */
+
 /**
  * eeh_pe_get_parent - Retrieve the parent PE
  * @edev: EEH device
-- 
1.8.3.2

^ 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