public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/hardened-patchset:master commit in: 3.2.11/, 2.6.32/, 3.2.9/
@ 2012-03-15 15:09 Anthony G. Basile
  0 siblings, 0 replies; only message in thread
From: Anthony G. Basile @ 2012-03-15 15:09 UTC (permalink / raw
  To: gentoo-commits

commit:     b7a6f90d3700011af95712bbd6f8ec4aa89a63e9
Author:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Thu Mar 15 15:08:55 2012 +0000
Commit:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Thu Mar 15 15:08:55 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-patchset.git;a=commit;h=b7a6f90d

Grsec/PaX: 2.9-2.6.32.58-201203131839 + 2.9-3.2.11-201203141956

---
 2.6.32/0000_README                                 |    2 +-
 ...20_grsecurity-2.9-2.6.32.58-201203131839.patch} |25219 +++++++++++++++++---
 2.6.32/4445_grsec-pax-without-grsec.patch          |   11 +-
 2.6.32/4450_grsec-kconfig-default-gids.patch       |   14 +-
 2.6.32/4460-grsec-kconfig-proc-user.patch          |    4 +-
 2.6.32/4465_selinux-avc_audit-log-curr_ip.patch    |    2 +-
 {3.2.9 => 3.2.11}/0000_README                      |    2 +-
 .../4420_grsecurity-2.9-3.2.11-201203141956.patch  | 2007 ++-
 {3.2.9 => 3.2.11}/4425_grsec_enable_xtpax.patch    |    0
 .../4430_grsec-remove-localversion-grsec.patch     |    0
 {3.2.9 => 3.2.11}/4435_grsec-mute-warnings.patch   |    0
 .../4440_grsec-remove-protected-paths.patch        |    2 +-
 .../4445_grsec-pax-without-grsec.patch             |   11 +-
 .../4450_grsec-kconfig-default-gids.patch          |   14 +-
 {3.2.9 => 3.2.11}/4455_grsec-kconfig-gentoo.patch  |    0
 .../4460-grsec-kconfig-proc-user.patch             |    4 +-
 .../4465_selinux-avc_audit-log-curr_ip.patch       |    2 +-
 {3.2.9 => 3.2.11}/4470_disable-compat_vdso.patch   |    0
 18 files changed, 23470 insertions(+), 3824 deletions(-)

diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index c4a9001..1858adf 100644
--- a/2.6.32/0000_README
+++ b/2.6.32/0000_README
@@ -22,7 +22,7 @@ Patch:	1056_linux-2.6.32.57.patch
 From:	http://www.kernel.org
 Desc:	Linux 2.6.32.57
 
-Patch:	4420_grsecurity-2.9-2.6.32.58-201203062047.patch
+Patch:	4420_grsecurity-2.9-2.6.32.58-201203131839.patch
 From:	http://www.grsecurity.net
 Desc:	hardened-sources base patch from upstream grsecurity
 

diff --git a/2.6.32/4420_grsecurity-2.9-2.6.32.58-201203062047.patch b/2.6.32/4420_grsecurity-2.9-2.6.32.58-201203131839.patch
similarity index 84%
rename from 2.6.32/4420_grsecurity-2.9-2.6.32.58-201203062047.patch
rename to 2.6.32/4420_grsecurity-2.9-2.6.32.58-201203131839.patch
index bbdf047..325d13c 100644
--- a/2.6.32/4420_grsecurity-2.9-2.6.32.58-201203062047.patch
+++ b/2.6.32/4420_grsecurity-2.9-2.6.32.58-201203131839.patch
@@ -1,5 +1,5 @@
 diff --git a/Documentation/dontdiff b/Documentation/dontdiff
-index e1efc40..47f0daf 100644
+index e1efc40..76e689e 100644
 --- a/Documentation/dontdiff
 +++ b/Documentation/dontdiff
 @@ -1,15 +1,19 @@
@@ -96,7 +96,15 @@ index e1efc40..47f0daf 100644
  keywords.c
  ksym.c*
  ksym.h*
-@@ -127,13 +148,16 @@ machtypes.h
+@@ -117,6 +138,7 @@ kxgettext
+ lkc_defs.h
+ lex.c
+ lex.*.c
++lib1funcs.S
+ logo_*.c
+ logo_*_clut224.c
+ logo_*_mono.c
+@@ -127,13 +149,16 @@ machtypes.h
  map
  maui_boot.h
  mconf
@@ -113,7 +121,7 @@ index e1efc40..47f0daf 100644
  mktables
  mktree
  modpost
-@@ -149,6 +173,7 @@ patches*
+@@ -149,6 +174,7 @@ patches*
  pca200e.bin
  pca200e_ecd.bin2
  piggy.gz
@@ -121,7 +129,7 @@ index e1efc40..47f0daf 100644
  piggyback
  pnmtologo
  ppc_defs.h*
-@@ -157,12 +182,15 @@ qconf
+@@ -157,12 +183,15 @@ qconf
  raid6altivec*.c
  raid6int*.c
  raid6tables.c
@@ -137,7 +145,7 @@ index e1efc40..47f0daf 100644
  sm_tbl*
  split-include
  syscalltab.h
-@@ -171,6 +199,7 @@ tftpboot.img
+@@ -171,6 +200,7 @@ tftpboot.img
  timeconst.h
  times.h*
  trix_boot.h
@@ -145,7 +153,7 @@ index e1efc40..47f0daf 100644
  utsrelease.h*
  vdso-syms.lds
  vdso.lds
-@@ -186,14 +215,20 @@ version.h*
+@@ -186,14 +216,20 @@ version.h*
  vmlinux
  vmlinux-*
  vmlinux.aout
@@ -184,8 +192,27 @@ index c840e7d..f4c451c 100644
  	pcbit=		[HW,ISDN]
  
  	pcd.		[PARIDE]
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 613da5d..4fe3eda 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -5725,6 +5725,14 @@ L:	netdev@vger.kernel.org
+ S:	Maintained
+ F:	drivers/net/vmxnet3/
+ 
++VMware PVSCSI driver
++M:	Alok Kataria <akataria@vmware.com>
++M:	VMware PV-Drivers <pv-drivers@vmware.com>
++L:	linux-scsi@vger.kernel.org
++S:	Maintained
++F:	drivers/scsi/vmw_pvscsi.c
++F:	drivers/scsi/vmw_pvscsi.h
++
+ VOLTAGE AND CURRENT REGULATOR FRAMEWORK
+ M:	Liam Girdwood <lrg@slimlogic.co.uk>
+ M:	Mark Brown <broonie@opensource.wolfsonmicro.com>
 diff --git a/Makefile b/Makefile
-index ed78982..bcc432e 100644
+index ed78982..cb8fa66 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -221,8 +221,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -220,7 +247,7 @@ index ed78982..bcc432e 100644
  			 include/linux/version.h headers_% \
  			 kernelrelease kernelversion
  
-@@ -526,6 +527,48 @@ else
+@@ -526,6 +527,50 @@ else
  KBUILD_CFLAGS	+= -O2
  endif
  
@@ -246,7 +273,9 @@ index ed78982..bcc432e 100644
 +CHECKER_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/checker_plugin.so -DCHECKER_PLUGIN
 +endif
 +endif
-+GCC_PLUGINS_CFLAGS := $(CONSTIFY_PLUGIN_CFLAGS) $(STACKLEAK_PLUGIN_CFLAGS) $(KALLOCSTAT_PLUGIN_CFLAGS) $(KERNEXEC_PLUGIN_CFLAGS) $(CHECKER_PLUGIN_CFLAGS)
++COLORIZE_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/colorize_plugin.so
++GCC_PLUGINS_CFLAGS := $(CONSTIFY_PLUGIN_CFLAGS) $(STACKLEAK_PLUGIN_CFLAGS) $(KALLOCSTAT_PLUGIN_CFLAGS)
++GCC_PLUGINS_CFLAGS += $(KERNEXEC_PLUGIN_CFLAGS) $(CHECKER_PLUGIN_CFLAGS) $(COLORIZE_PLUGIN_CFLAGS)
 +GCC_PLUGINS_AFLAGS := $(KERNEXEC_PLUGIN_AFLAGS)
 +export CONSTIFY_PLUGIN STACKLEAK_PLUGIN KERNEXEC_PLUGIN CHECKER_PLUGIN
 +ifeq ($(KBUILD_EXTMOD),)
@@ -269,7 +298,7 @@ index ed78982..bcc432e 100644
  include $(srctree)/arch/$(SRCARCH)/Makefile
  
  ifneq ($(CONFIG_FRAME_WARN),0)
-@@ -647,7 +690,7 @@ export mod_strip_cmd
+@@ -647,7 +692,7 @@ export mod_strip_cmd
  
  
  ifeq ($(KBUILD_EXTMOD),)
@@ -278,7 +307,7 @@ index ed78982..bcc432e 100644
  
  vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
  		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
-@@ -868,6 +911,8 @@ vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
+@@ -868,6 +913,8 @@ vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
  
  # The actual objects are generated when descending, 
  # make sure no implicit rule kicks in
@@ -287,7 +316,7 @@ index ed78982..bcc432e 100644
  $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
  
  # Handle descending into subdirectories listed in $(vmlinux-dirs)
-@@ -877,7 +922,7 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
+@@ -877,7 +924,7 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
  # Error messages still appears in the original language
  
  PHONY += $(vmlinux-dirs)
@@ -296,7 +325,7 @@ index ed78982..bcc432e 100644
  	$(Q)$(MAKE) $(build)=$@
  
  # Build the kernel release string
-@@ -986,6 +1031,7 @@ prepare0: archprepare FORCE
+@@ -986,6 +1033,7 @@ prepare0: archprepare FORCE
  	$(Q)$(MAKE) $(build)=. missing-syscalls
  
  # All the preparing..
@@ -304,7 +333,7 @@ index ed78982..bcc432e 100644
  prepare: prepare0
  
  # The asm symlink changes when $(ARCH) changes.
-@@ -1127,6 +1173,8 @@ all: modules
+@@ -1127,6 +1175,8 @@ all: modules
  #	using awk while concatenating to the final file.
  
  PHONY += modules
@@ -313,7 +342,7 @@ index ed78982..bcc432e 100644
  modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
  	$(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
  	@$(kecho) '  Building modules, stage 2.';
-@@ -1136,7 +1184,7 @@ modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
+@@ -1136,7 +1186,7 @@ modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
  
  # Target to prepare building external modules
  PHONY += modules_prepare
@@ -322,7 +351,7 @@ index ed78982..bcc432e 100644
  
  # Target to install modules
  PHONY += modules_install
-@@ -1201,7 +1249,7 @@ MRPROPER_FILES += .config .config.old include/asm .version .old_version \
+@@ -1201,7 +1251,7 @@ MRPROPER_FILES += .config .config.old include/asm .version .old_version \
                    include/linux/autoconf.h include/linux/version.h      \
                    include/linux/utsrelease.h                            \
                    include/linux/bounds.h include/asm*/asm-offsets.h     \
@@ -331,7 +360,7 @@ index ed78982..bcc432e 100644
  
  # clean - Delete most, but leave enough to build external modules
  #
-@@ -1245,7 +1293,7 @@ distclean: mrproper
+@@ -1245,7 +1295,7 @@ distclean: mrproper
  	@find $(srctree) $(RCS_FIND_IGNORE) \
  		\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
  		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
@@ -340,7 +369,7 @@ index ed78982..bcc432e 100644
  		-o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
  		-type f -print | xargs rm -f
  
-@@ -1292,6 +1340,7 @@ help:
+@@ -1292,6 +1342,7 @@ help:
  	@echo  '  modules_prepare - Set up for building external modules'
  	@echo  '  tags/TAGS	  - Generate tags file for editors'
  	@echo  '  cscope	  - Generate cscope index'
@@ -348,7 +377,7 @@ index ed78982..bcc432e 100644
  	@echo  '  kernelrelease	  - Output the release version string'
  	@echo  '  kernelversion	  - Output the version stored in Makefile'
  	@echo  '  headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
-@@ -1393,6 +1442,8 @@ PHONY += $(module-dirs) modules
+@@ -1393,6 +1444,8 @@ PHONY += $(module-dirs) modules
  $(module-dirs): crmodverdir $(objtree)/Module.symvers
  	$(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)
  
@@ -357,7 +386,7 @@ index ed78982..bcc432e 100644
  modules: $(module-dirs)
  	@$(kecho) '  Building modules, stage 2.';
  	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
-@@ -1448,7 +1499,7 @@ endif # KBUILD_EXTMOD
+@@ -1448,7 +1501,7 @@ endif # KBUILD_EXTMOD
  quiet_cmd_tags = GEN     $@
        cmd_tags = $(CONFIG_SHELL) $(srctree)/scripts/tags.sh $@
  
@@ -366,7 +395,7 @@ index ed78982..bcc432e 100644
  	$(call cmd,tags)
  
  # Scripts to check various things for consistency
-@@ -1513,17 +1564,21 @@ else
+@@ -1513,17 +1566,21 @@ else
          target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@))
  endif
  
@@ -392,7 +421,7 @@ index ed78982..bcc432e 100644
  	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
  %.symtypes: %.c prepare scripts FORCE
  	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
-@@ -1533,11 +1588,15 @@ endif
+@@ -1533,11 +1590,15 @@ endif
  	$(cmd_crmodverdir)
  	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
  	$(build)=$(build-dir)
@@ -431,6 +460,33 @@ index 610dff4..f396854 100644
  #define smp_mb__before_atomic_dec()	smp_mb()
  #define smp_mb__after_atomic_dec()	smp_mb()
  #define smp_mb__before_atomic_inc()	smp_mb()
+diff --git a/arch/alpha/include/asm/cache.h b/arch/alpha/include/asm/cache.h
+index f199e69..af005f5 100644
+--- a/arch/alpha/include/asm/cache.h
++++ b/arch/alpha/include/asm/cache.h
+@@ -4,19 +4,20 @@
+ #ifndef __ARCH_ALPHA_CACHE_H
+ #define __ARCH_ALPHA_CACHE_H
+ 
++#include <linux/const.h>
+ 
+ /* Bytes per L1 (data) cache line. */
+ #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6)
+-# define L1_CACHE_BYTES     64
+ # define L1_CACHE_SHIFT     6
+ #else
+ /* Both EV4 and EV5 are write-through, read-allocate,
+    direct-mapped, physical.
+ */
+-# define L1_CACHE_BYTES     32
+ # define L1_CACHE_SHIFT     5
+ #endif
+ 
++#define L1_CACHE_BYTES     (_AC(1,UL) << L1_CACHE_SHIFT)
++
+ #define L1_CACHE_ALIGN(x)  (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
+ #define SMP_CACHE_BYTES    L1_CACHE_BYTES
+ 
 diff --git a/arch/alpha/include/asm/elf.h b/arch/alpha/include/asm/elf.h
 index 5c75c1b..c82f878 100644
 --- a/arch/alpha/include/asm/elf.h
@@ -692,7 +748,7 @@ index b68faef..6dd1496 100644
  	select HAVE_KRETPROBES if (HAVE_KPROBES)
  	select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
 diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
-index d0daeab..ff286a8 100644
+index d0daeab..ca7e10e 100644
 --- a/arch/arm/include/asm/atomic.h
 +++ b/arch/arm/include/asm/atomic.h
 @@ -15,6 +15,10 @@
@@ -706,6 +762,271 @@ index d0daeab..ff286a8 100644
  #define ATOMIC_INIT(i)	{ (i) }
  
  #ifdef __KERNEL__
+@@ -24,8 +28,16 @@
+  * strex/ldrex monitor on some implementations. The reason we can use it for
+  * atomic_set() is the clrex or dummy strex done on every exception return.
+  */
+-#define atomic_read(v)	((v)->counter)
++#define atomic_read(v)	(*(volatile int *)&(v)->counter)
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++	return v->counter;
++}
+ #define atomic_set(v,i)	(((v)->counter) = (i))
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++	v->counter = i;
++}
+ 
+ #if __LINUX_ARM_ARCH__ >= 6
+ 
+@@ -40,6 +52,35 @@ static inline void atomic_add(int i, atomic_t *v)
+ 	int result;
+ 
+ 	__asm__ __volatile__("@ atomic_add\n"
++"1:	ldrex	%1, [%2]\n"
++"	add	%0, %1, %3\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strex	%1, %0, [%2]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp)
++	: "r" (&v->counter), "Ir" (i)
++	: "cc");
++}
++
++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
++{
++	unsigned long tmp;
++	int result;
++
++	__asm__ __volatile__("@ atomic_add_unchecked\n"
+ "1:	ldrex	%0, [%2]\n"
+ "	add	%0, %0, %3\n"
+ "	strex	%1, %0, [%2]\n"
+@@ -58,6 +99,42 @@ static inline int atomic_add_return(int i, atomic_t *v)
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic_add_return\n"
++"1:	ldrex	%1, [%2]\n"
++"	add	%0, %1, %3\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"2:	bkpt 0xf103\n"
++"3:\n"
++#endif
++
++"	strex	%1, %0, [%2]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp)
++	: "r" (&v->counter), "Ir" (i)
++	: "cc");
++
++	smp_mb();
++
++	return result;
++}
++
++static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
++{
++	unsigned long tmp;
++	int result;
++
++	smp_mb();
++
++	__asm__ __volatile__("@ atomic_add_return_unchecked\n"
+ "1:	ldrex	%0, [%2]\n"
+ "	add	%0, %0, %3\n"
+ "	strex	%1, %0, [%2]\n"
+@@ -78,6 +155,35 @@ static inline void atomic_sub(int i, atomic_t *v)
+ 	int result;
+ 
+ 	__asm__ __volatile__("@ atomic_sub\n"
++"1:	ldrex	%1, [%2]\n"
++"	sub	%0, %1, %3\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strex	%1, %0, [%2]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp)
++	: "r" (&v->counter), "Ir" (i)
++	: "cc");
++}
++
++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
++{
++	unsigned long tmp;
++	int result;
++
++	__asm__ __volatile__("@ atomic_sub_unchecked\n"
+ "1:	ldrex	%0, [%2]\n"
+ "	sub	%0, %0, %3\n"
+ "	strex	%1, %0, [%2]\n"
+@@ -96,11 +202,25 @@ static inline int atomic_sub_return(int i, atomic_t *v)
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic_sub_return\n"
+-"1:	ldrex	%0, [%2]\n"
+-"	sub	%0, %0, %3\n"
++"1:	ldrex	%1, [%2]\n"
++"	sub	%0, %1, %3\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
+ "	strex	%1, %0, [%2]\n"
+ "	teq	%1, #0\n"
+ "	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
+ 	: "=&r" (result), "=&r" (tmp)
+ 	: "r" (&v->counter), "Ir" (i)
+ 	: "cc");
+@@ -132,6 +252,28 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
+ 	return oldval;
+ }
+ 
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *ptr, int old, int new)
++{
++	unsigned long oldval, res;
++
++	smp_mb();
++
++	do {
++		__asm__ __volatile__("@ atomic_cmpxchg_unchecked\n"
++		"ldrex	%1, [%2]\n"
++		"mov	%0, #0\n"
++		"teq	%1, %3\n"
++		"strexeq %0, %4, [%2]\n"
++		    : "=&r" (res), "=&r" (oldval)
++		    : "r" (&ptr->counter), "Ir" (old), "r" (new)
++		    : "cc");
++	} while (res);
++
++	smp_mb();
++
++	return oldval;
++}
++
+ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+ {
+ 	unsigned long tmp, tmp2;
+@@ -207,6 +349,10 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+ #endif /* __LINUX_ARM_ARCH__ */
+ 
+ #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
++static inline int atomic_xchg_unchecked(atomic_unchecked_t *v, int new)
++{
++	return xchg(&v->counter, new);
++}
+ 
+ static inline int atomic_add_unless(atomic_t *v, int a, int u)
+ {
+@@ -220,11 +366,27 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
+ #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+ 
+ #define atomic_inc(v)		atomic_add(1, v)
++static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
++{
++	atomic_add_unchecked(1, v);
++}
+ #define atomic_dec(v)		atomic_sub(1, v)
++static inline void atomic_dec_unchecked(atomic_unchecked_t *v)
++{
++	atomic_sub_unchecked(1, v);
++}
+ 
+ #define atomic_inc_and_test(v)	(atomic_add_return(1, v) == 0)
++static inline int atomic_inc_and_test_unchecked(atomic_unchecked_t *v)
++{
++	return atomic_add_return_unchecked(1, v) == 0;
++}
+ #define atomic_dec_and_test(v)	(atomic_sub_return(1, v) == 0)
+ #define atomic_inc_return(v)    (atomic_add_return(1, v))
++static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
++{
++	return atomic_add_return_unchecked(1, v);
++}
+ #define atomic_dec_return(v)    (atomic_sub_return(1, v))
+ #define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+ 
+diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
+index 66c160b..bca1449 100644
+--- a/arch/arm/include/asm/cache.h
++++ b/arch/arm/include/asm/cache.h
+@@ -4,8 +4,10 @@
+ #ifndef __ASMARM_CACHE_H
+ #define __ASMARM_CACHE_H
+ 
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT		CONFIG_ARM_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ /*
+  * Memory returned by kmalloc() may be used for DMA, so we must make
+diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
+index 3d0cdd2..19957c5 100644
+--- a/arch/arm/include/asm/cacheflush.h
++++ b/arch/arm/include/asm/cacheflush.h
+@@ -216,13 +216,13 @@ struct cpu_cache_fns {
+ 	void (*dma_inv_range)(const void *, const void *);
+ 	void (*dma_clean_range)(const void *, const void *);
+ 	void (*dma_flush_range)(const void *, const void *);
+-};
++} __no_const;
+ 
+ struct outer_cache_fns {
+ 	void (*inv_range)(unsigned long, unsigned long);
+ 	void (*clean_range)(unsigned long, unsigned long);
+ 	void (*flush_range)(unsigned long, unsigned long);
+-};
++} __no_const;
+ 
+ /*
+  * Select the calling method
 diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
 index 6aac3f5..265536b 100644
 --- a/arch/arm/include/asm/elf.h
@@ -738,6 +1059,55 @@ index c019949..388fdd1 100644
  	KM_TYPE_NR
  };
  
+diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
+index 3a32af4..c8def8a 100644
+--- a/arch/arm/include/asm/page.h
++++ b/arch/arm/include/asm/page.h
+@@ -122,7 +122,7 @@ struct cpu_user_fns {
+ 	void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr);
+ 	void (*cpu_copy_user_highpage)(struct page *to, struct page *from,
+ 			unsigned long vaddr);
+-};
++} __no_const;
+ 
+ #ifdef MULTI_USER
+ extern struct cpu_user_fns cpu_user;
+diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
+index d65b2f5..9d87555 100644
+--- a/arch/arm/include/asm/system.h
++++ b/arch/arm/include/asm/system.h
+@@ -86,6 +86,8 @@ void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
+ 
+ #define xchg(ptr,x) \
+ 	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
++#define xchg_unchecked(ptr,x) \
++	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+ 
+ extern asmlinkage void __backtrace(void);
+ extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
+@@ -98,7 +100,7 @@ extern int cpu_architecture(void);
+ extern void cpu_init(void);
+ 
+ void arm_machine_restart(char mode, const char *cmd);
+-extern void (*arm_pm_restart)(char str, const char *cmd);
++extern void (*arm_pm_restart)(char str, const char *cmd) __noreturn;
+ 
+ #define UDBG_UNDEFINED	(1 << 0)
+ #define UDBG_SYSCALL	(1 << 1)
+@@ -505,6 +507,13 @@ static inline unsigned long long __cmpxchg64_mb(volatile void *ptr,
+ 
+ #endif	/* __LINUX_ARM_ARCH__ >= 6 */
+ 
++#define _ASM_EXTABLE(from, to)		\
++"	.pushsection __ex_table,\"a\"\n"\
++"	.align	3\n"			\
++"	.long	" #from ", " #to"\n"	\
++"	.popsection"
++
++
+ #endif /* __ASSEMBLY__ */
+ 
+ #define arch_align_stack(x) (x)
 diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
 index 1d6bd40..fba0cb9 100644
 --- a/arch/arm/include/asm/uaccess.h
@@ -825,6 +1195,69 @@ index ba8ccfe..2dc34dc 100644
  #ifndef __ARMEB__
  	.gdb_bpt_instr		= {0xfe, 0xde, 0xff, 0xe7}
  #else /* ! __ARMEB__ */
+diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
+index 61f90d3..771ab27 100644
+--- a/arch/arm/kernel/process.c
++++ b/arch/arm/kernel/process.c
+@@ -83,7 +83,7 @@ static int __init hlt_setup(char *__unused)
+ __setup("nohlt", nohlt_setup);
+ __setup("hlt", hlt_setup);
+ 
+-void arm_machine_restart(char mode, const char *cmd)
++__noreturn void arm_machine_restart(char mode, const char *cmd)
+ {
+ 	/*
+ 	 * Clean and disable cache, and turn off interrupts
+@@ -117,7 +117,7 @@ void arm_machine_restart(char mode, const char *cmd)
+ void (*pm_power_off)(void);
+ EXPORT_SYMBOL(pm_power_off);
+ 
+-void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
++void (*arm_pm_restart)(char str, const char *cmd) __noreturn = arm_machine_restart;
+ EXPORT_SYMBOL_GPL(arm_pm_restart);
+ 
+ 
+@@ -195,6 +195,7 @@ __setup("reboot=", reboot_setup);
+ 
+ void machine_halt(void)
+ {
++	BUG();
+ }
+ 
+ 
+@@ -202,6 +203,7 @@ void machine_power_off(void)
+ {
+ 	if (pm_power_off)
+ 		pm_power_off();
++	BUG();
+ }
+ 
+ void machine_restart(char *cmd)
+diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
+index c6c57b6..0c3b29e 100644
+--- a/arch/arm/kernel/setup.c
++++ b/arch/arm/kernel/setup.c
+@@ -92,16 +92,16 @@ EXPORT_SYMBOL(elf_hwcap);
+ struct processor processor;
+ #endif
+ #ifdef MULTI_TLB
+-struct cpu_tlb_fns cpu_tlb;
++struct cpu_tlb_fns cpu_tlb __read_only;
+ #endif
+ #ifdef MULTI_USER
+-struct cpu_user_fns cpu_user;
++struct cpu_user_fns cpu_user __read_only;
+ #endif
+ #ifdef MULTI_CACHE
+-struct cpu_cache_fns cpu_cache;
++struct cpu_cache_fns cpu_cache __read_only;
+ #endif
+ #ifdef CONFIG_OUTER_CACHE
+-struct outer_cache_fns outer_cache;
++struct outer_cache_fns outer_cache __read_only;
+ #endif
+ 
+ struct stack {
 diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
 index 3f361a7..6e806e1 100644
 --- a/arch/arm/kernel/traps.c
@@ -847,6 +1280,29 @@ index 3f361a7..6e806e1 100644
  	do_exit(SIGSEGV);
  }
  
+diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
+index aecf87df..bed731b 100644
+--- a/arch/arm/kernel/vmlinux.lds.S
++++ b/arch/arm/kernel/vmlinux.lds.S
+@@ -74,14 +74,18 @@ SECTIONS
+ #ifndef CONFIG_XIP_KERNEL
+ 		__init_begin = _stext;
+ 		INIT_DATA
++		EXIT_TEXT
++		EXIT_DATA
+ 		. = ALIGN(PAGE_SIZE);
+ 		__init_end = .;
+ #endif
+ 	}
+ 
+ 	/DISCARD/ : {			/* Exit code and data		*/
++#ifdef CONFIG_XIP_KERNEL
+ 		EXIT_TEXT
+ 		EXIT_DATA
++#endif
+ 		*(.exitcall.exit)
+ 		*(.discard)
+ 		*(.ARM.exidx.exit.text)
 diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
 index e4fe124..0fc246b 100644
 --- a/arch/arm/lib/copy_from_user.S
@@ -874,6 +1330,18 @@ index e4fe124..0fc246b 100644
  
  	.section .fixup,"ax"
  	.align 0
+diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
+index 6ee2f67..d1cce76 100644
+--- a/arch/arm/lib/copy_page.S
++++ b/arch/arm/lib/copy_page.S
+@@ -10,6 +10,7 @@
+  *  ASM optimised string functions
+  */
+ #include <linux/linkage.h>
++#include <linux/const.h>
+ #include <asm/assembler.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/cache.h>
 diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
 index 1a71e15..ac7b258 100644
 --- a/arch/arm/lib/copy_to_user.S
@@ -1076,7 +1544,7 @@ index c83fdc8..ab9fc44 100644
  	.valid		= suspend_valid_only_mem,
  };
 diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
-index 3191cd6..c0739db 100644
+index 3191cd6..c322981 100644
 --- a/arch/arm/mm/fault.c
 +++ b/arch/arm/mm/fault.c
 @@ -166,6 +166,13 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
@@ -1127,6 +1595,27 @@ index 3191cd6..c0739db 100644
  /*
   * First Level Translation Fault Handler
   *
+@@ -569,6 +603,20 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
+ 	const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
+ 	struct siginfo info;
+ 
++#ifdef CONFIG_PAX_REFCOUNT
++	if (fsr_fs(ifsr) == 2) {
++		unsigned int bkpt;
++
++		if (!probe_kernel_address((unsigned int *)addr, bkpt) && bkpt == 0xe12f1073) {
++			current->thread.error_code = ifsr;
++			current->thread.trap_no = 0;
++			pax_report_refcount_overflow(regs);
++			fixup_exception(regs);
++			return;
++		}
++	}
++#endif
++
+ 	if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
+ 		return;
+ 
 diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
 index f5abc51..7ec524c 100644
 --- a/arch/arm/mm/mmap.c
@@ -1193,6 +1682,22 @@ index 8d97db2..b66cfa5 100644
  	.enter		= s3c_pm_enter,
  	.prepare	= s3c_pm_prepare,
  	.finish		= s3c_pm_finish,
+diff --git a/arch/avr32/include/asm/cache.h b/arch/avr32/include/asm/cache.h
+index d3cf35a..0ba6053 100644
+--- a/arch/avr32/include/asm/cache.h
++++ b/arch/avr32/include/asm/cache.h
+@@ -1,8 +1,10 @@
+ #ifndef __ASM_AVR32_CACHE_H
+ #define __ASM_AVR32_CACHE_H
+ 
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT 5
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ /*
+  * Memory returned by kmalloc() may be used for DMA, so we must make
 diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h
 index d5d1d41..856e2ed 100644
 --- a/arch/avr32/include/asm/elf.h
@@ -1285,6 +1790,26 @@ index b61d86d..e292c7f 100644
  		if (exception_trace && printk_ratelimit())
  			printk("%s%s[%d]: segfault at %08lx pc %08lx "
  			       "sp %08lx ecr %lu\n",
+diff --git a/arch/blackfin/include/asm/cache.h b/arch/blackfin/include/asm/cache.h
+index 93f6c63..d144953 100644
+--- a/arch/blackfin/include/asm/cache.h
++++ b/arch/blackfin/include/asm/cache.h
+@@ -7,12 +7,14 @@
+ #ifndef __ARCH_BLACKFIN_CACHE_H
+ #define __ARCH_BLACKFIN_CACHE_H
+ 
++#include <linux/const.h>
++
+ /*
+  * Bytes per L1 cache line
+  * Blackfin loads 32 bytes for cache
+  */
+ #define L1_CACHE_SHIFT	5
+-#define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES	(_AC(1,UL) << L1_CACHE_SHIFT)
+ #define SMP_CACHE_BYTES	L1_CACHE_BYTES
+ 
+ #define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
 diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
 index cce79d0..c406c85 100644
 --- a/arch/blackfin/kernel/kgdb.c
@@ -1311,6 +1836,39 @@ index 8837be4..b2fb413 100644
  	.enter = bfin_pm_enter,
  	.valid	= bfin_pm_valid,
  };
+diff --git a/arch/cris/include/arch-v10/arch/cache.h b/arch/cris/include/arch-v10/arch/cache.h
+index aea2718..3639a60 100644
+--- a/arch/cris/include/arch-v10/arch/cache.h
++++ b/arch/cris/include/arch-v10/arch/cache.h
+@@ -1,8 +1,9 @@
+ #ifndef _ASM_ARCH_CACHE_H
+ #define _ASM_ARCH_CACHE_H
+ 
++#include <linux/const.h>
+ /* Etrax 100LX have 32-byte cache-lines. */
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #endif /* _ASM_ARCH_CACHE_H */
+diff --git a/arch/cris/include/arch-v32/arch/cache.h b/arch/cris/include/arch-v32/arch/cache.h
+index dfc7305..417f5b3 100644
+--- a/arch/cris/include/arch-v32/arch/cache.h
++++ b/arch/cris/include/arch-v32/arch/cache.h
+@@ -1,11 +1,12 @@
+ #ifndef _ASM_CRIS_ARCH_CACHE_H
+ #define _ASM_CRIS_ARCH_CACHE_H
+ 
++#include <linux/const.h>
+ #include <arch/hwregs/dma.h>
+ 
+ /* A cache-line is 32 bytes. */
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ void flush_dma_list(dma_descr_data *descr);
+ void flush_dma_descr(dma_descr_data *descr, int flush_buf);
 diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h
 index 00a57af..c3ef0cd 100644
 --- a/arch/frv/include/asm/atomic.h
@@ -1332,6 +1890,23 @@ index 00a57af..c3ef0cd 100644
  static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
  {
  	int c, old;
+diff --git a/arch/frv/include/asm/cache.h b/arch/frv/include/asm/cache.h
+index 7dc0f0f..1e6a620 100644
+--- a/arch/frv/include/asm/cache.h
++++ b/arch/frv/include/asm/cache.h
+@@ -12,10 +12,11 @@
+ #ifndef __ASM_CACHE_H
+ #define __ASM_CACHE_H
+ 
++#include <linux/const.h>
+ 
+ /* bytes per L1 cache line */
+ #define L1_CACHE_SHIFT		(CONFIG_FRV_L1_CACHE_SHIFT)
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
+ 
 diff --git a/arch/frv/include/asm/kmap_types.h b/arch/frv/include/asm/kmap_types.h
 index f8e16b2..c73ff79 100644
 --- a/arch/frv/include/asm/kmap_types.h
@@ -1376,6 +1951,22 @@ index 385fd30..6c3d97e 100644
  				goto success;
  			addr = vma->vm_end;
  		}
+diff --git a/arch/h8300/include/asm/cache.h b/arch/h8300/include/asm/cache.h
+index c635028..6d9445a 100644
+--- a/arch/h8300/include/asm/cache.h
++++ b/arch/h8300/include/asm/cache.h
+@@ -1,8 +1,10 @@
+ #ifndef __ARCH_H8300_CACHE_H
+ #define __ARCH_H8300_CACHE_H
+ 
++#include <linux/const.h>
++
+ /* bytes per L1 cache line */
+-#define        L1_CACHE_BYTES  4
++#define        L1_CACHE_BYTES  _AC(4,UL)
+ 
+ /* m68k-elf-gcc  2.95.2 doesn't like these */
+ 
 diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
 index e4a80d8..11a7ea1 100644
 --- a/arch/ia64/hp/common/hwsw_iommu.c
@@ -1479,6 +2070,27 @@ index 88405cb..de5ca5d 100644
  /* Atomic operations are already serializing */
  #define smp_mb__before_atomic_dec()	barrier()
  #define smp_mb__after_atomic_dec()	barrier()
+diff --git a/arch/ia64/include/asm/cache.h b/arch/ia64/include/asm/cache.h
+index e7482bd..d1c9b8e 100644
+--- a/arch/ia64/include/asm/cache.h
++++ b/arch/ia64/include/asm/cache.h
+@@ -1,6 +1,7 @@
+ #ifndef _ASM_IA64_CACHE_H
+ #define _ASM_IA64_CACHE_H
+ 
++#include <linux/const.h>
+ 
+ /*
+  * Copyright (C) 1998-2000 Hewlett-Packard Co
+@@ -9,7 +10,7 @@
+ 
+ /* Bytes per L1 (data) cache line.  */
+ #define L1_CACHE_SHIFT		CONFIG_IA64_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #ifdef CONFIG_SMP
+ # define SMP_CACHE_SHIFT	L1_CACHE_SHIFT
 diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
 index 8d3c79c..71b3af6 100644
 --- a/arch/ia64/include/asm/dma-mapping.h
@@ -1979,6 +2591,22 @@ index 98b6849..8046766 100644
  	.alloc_coherent		= sn_dma_alloc_coherent,
  	.free_coherent		= sn_dma_free_coherent,
  	.map_page		= sn_dma_map_page,
+diff --git a/arch/m32r/include/asm/cache.h b/arch/m32r/include/asm/cache.h
+index 40b3ee9..8c2c112 100644
+--- a/arch/m32r/include/asm/cache.h
++++ b/arch/m32r/include/asm/cache.h
+@@ -1,8 +1,10 @@
+ #ifndef _ASM_M32R_CACHE_H
+ #define _ASM_M32R_CACHE_H
+ 
++#include <linux/const.h>
++
+ /* L1 cache line size */
+ #define L1_CACHE_SHIFT		4
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #endif  /* _ASM_M32R_CACHE_H */
 diff --git a/arch/m32r/lib/usercopy.c b/arch/m32r/lib/usercopy.c
 index 82abd15..d95ae5d 100644
 --- a/arch/m32r/lib/usercopy.c
@@ -2003,6 +2631,41 @@ index 82abd15..d95ae5d 100644
  	prefetchw(to);
  	if (access_ok(VERIFY_READ, from, n))
  		__copy_user_zeroing(to,from,n);
+diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h
+index ecafbe1..432c3e4 100644
+--- a/arch/m68k/include/asm/cache.h
++++ b/arch/m68k/include/asm/cache.h
+@@ -4,9 +4,11 @@
+ #ifndef __ARCH_M68K_CACHE_H
+ #define __ARCH_M68K_CACHE_H
+ 
++#include <linux/const.h>
++
+ /* bytes per L1 cache line */
+ #define        L1_CACHE_SHIFT  4
+-#define        L1_CACHE_BYTES  (1<< L1_CACHE_SHIFT)
++#define        L1_CACHE_BYTES  (_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
+ 
+diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h
+index c209c47..2ba96e2 100644
+--- a/arch/microblaze/include/asm/cache.h
++++ b/arch/microblaze/include/asm/cache.h
+@@ -13,11 +13,12 @@
+ #ifndef _ASM_MICROBLAZE_CACHE_H
+ #define _ASM_MICROBLAZE_CACHE_H
+ 
++#include <linux/const.h>
+ #include <asm/registers.h>
+ 
+ #define L1_CACHE_SHIFT	2
+ /* word-granular cache in microblaze */
+-#define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES	(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define SMP_CACHE_BYTES	L1_CACHE_BYTES
+ 
 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
 index fd7620f..63d73a6 100644
 --- a/arch/mips/Kconfig
@@ -2073,6 +2736,23 @@ index 09e7128..111035b 100644
  #endif /* CONFIG_64BIT */
  
  /*
+diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h
+index 37f175c..c7a3065 100644
+--- a/arch/mips/include/asm/cache.h
++++ b/arch/mips/include/asm/cache.h
+@@ -9,10 +9,11 @@
+ #ifndef _ASM_CACHE_H
+ #define _ASM_CACHE_H
+ 
++#include <linux/const.h>
+ #include <kmalloc.h>
+ 
+ #define L1_CACHE_SHIFT		CONFIG_MIPS_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define SMP_CACHE_SHIFT		L1_CACHE_SHIFT
+ #define SMP_CACHE_BYTES		L1_CACHE_BYTES
 diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
 index 7990694..4e93acf 100644
 --- a/arch/mips/include/asm/elf.h
@@ -2297,6 +2977,26 @@ index e97a7a2..f18f5b0 100644
  /*
   * This routine handles page faults.  It determines the address,
   * and the problem, and then passes it off to one of the appropriate
+diff --git a/arch/mn10300/proc-mn103e010/include/proc/cache.h b/arch/mn10300/proc-mn103e010/include/proc/cache.h
+index bdc1f9a..e8de5c5 100644
+--- a/arch/mn10300/proc-mn103e010/include/proc/cache.h
++++ b/arch/mn10300/proc-mn103e010/include/proc/cache.h
+@@ -11,12 +11,14 @@
+ #ifndef _ASM_PROC_CACHE_H
+ #define _ASM_PROC_CACHE_H
+ 
++#include <linux/const.h>
++
+ /* L1 cache */
+ 
+ #define L1_CACHE_NWAYS		4	/* number of ways in caches */
+ #define L1_CACHE_NENTRIES	256	/* number of entries in each way */
+-#define L1_CACHE_BYTES		16	/* bytes per entry */
+ #define L1_CACHE_SHIFT		4	/* shift for bytes per entry */
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)	/* bytes per entry */
+ #define L1_CACHE_WAYDISP	0x1000	/* displacement of one way from the next */
+ 
+ #define L1_CACHE_TAG_VALID	0x00000001	/* cache tag valid bit */
 diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
 index 8bc9e96..26554f8 100644
 --- a/arch/parisc/include/asm/atomic.h
@@ -2318,6 +3018,34 @@ index 8bc9e96..26554f8 100644
  #else /* CONFIG_64BIT */
  
  #include <asm-generic/atomic64.h>
+diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
+index 32c2cca..a7b3a64 100644
+--- a/arch/parisc/include/asm/cache.h
++++ b/arch/parisc/include/asm/cache.h
+@@ -5,6 +5,7 @@
+ #ifndef __ARCH_PARISC_CACHE_H
+ #define __ARCH_PARISC_CACHE_H
+ 
++#include <linux/const.h>
+ 
+ /*
+  * PA 2.0 processors have 64-byte cachelines; PA 1.1 processors have
+@@ -15,13 +16,13 @@
+  * just ruin performance.
+  */
+ #ifdef CONFIG_PA20
+-#define L1_CACHE_BYTES 64
+ #define L1_CACHE_SHIFT 6
+ #else
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
+ #endif
+ 
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
++
+ #ifndef __ASSEMBLY__
+ 
+ #define L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
 diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
 index 9c802eb..0592e41 100644
 --- a/arch/parisc/include/asm/elf.h
@@ -2693,6 +3421,27 @@ index c107b74..409dc0f 100644
  CHECKFLAGS	+= -m$(CONFIG_WORD_SIZE) -D__powerpc__ -D__powerpc$(CONFIG_WORD_SIZE)__
  
  ifeq ($(CONFIG_PPC64),y)
+diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
+index 81de6eb..d5d0e24 100644
+--- a/arch/powerpc/include/asm/cache.h
++++ b/arch/powerpc/include/asm/cache.h
+@@ -3,6 +3,7 @@
+ 
+ #ifdef __KERNEL__
+ 
++#include <linux/const.h>
+ 
+ /* bytes per L1 cache line */
+ #if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
+@@ -18,7 +19,7 @@
+ #define L1_CACHE_SHIFT		7
+ #endif
+ 
+-#define	L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define	L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define	SMP_CACHE_BYTES		L1_CACHE_BYTES
+ 
 diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
 index 6d94d27..50d4cad 100644
 --- a/arch/powerpc/include/asm/device.h
@@ -3263,6 +4012,34 @@ index a4c8b38..1b09ad9 100644
  	.alloc_coherent = ibmebus_alloc_coherent,
  	.free_coherent  = ibmebus_free_coherent,
  	.map_sg         = ibmebus_map_sg,
+diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
+index 8564a41..67f3471 100644
+--- a/arch/powerpc/kernel/irq.c
++++ b/arch/powerpc/kernel/irq.c
+@@ -490,9 +490,6 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
+ 	host->ops = ops;
+ 	host->of_node = of_node_get(of_node);
+ 
+-	if (host->ops->match == NULL)
+-		host->ops->match = default_irq_host_match;
+-
+ 	spin_lock_irqsave(&irq_big_lock, flags);
+ 
+ 	/* If it's a legacy controller, check for duplicates and
+@@ -567,7 +564,12 @@ struct irq_host *irq_find_host(struct device_node *node)
+ 	 */
+ 	spin_lock_irqsave(&irq_big_lock, flags);
+ 	list_for_each_entry(h, &irq_hosts, link)
+-		if (h->ops->match(h, node)) {
++		if (h->ops->match) {
++			if (h->ops->match(h, node)) {
++				found = h;
++				break;
++			}
++		} else if (default_irq_host_match(h, node)) {
+ 			found = h;
+ 			break;
+ 		}
 diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
 index 641c74b..8339ad7 100644
 --- a/arch/powerpc/kernel/kgdb.c
@@ -4024,6 +4801,22 @@ index ae7c8f9..3f01a0c 100644
  #define smp_mb__before_atomic_dec()	smp_mb()
  #define smp_mb__after_atomic_dec()	smp_mb()
  #define smp_mb__before_atomic_inc()	smp_mb()
+diff --git a/arch/s390/include/asm/cache.h b/arch/s390/include/asm/cache.h
+index 9b86681..c5140db 100644
+--- a/arch/s390/include/asm/cache.h
++++ b/arch/s390/include/asm/cache.h
+@@ -11,8 +11,10 @@
+ #ifndef __ARCH_S390_CACHE_H
+ #define __ARCH_S390_CACHE_H
+ 
+-#define L1_CACHE_BYTES     256
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT     8
++#define L1_CACHE_BYTES     (_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define __read_mostly __attribute__((__section__(".data.read_mostly")))
+ 
 diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
 index e885442..e3a2817 100644
 --- a/arch/s390/include/asm/elf.h
@@ -4280,6 +5073,21 @@ index 0ab74ae..c8b68f9 100644
  		mm->get_unmapped_area = s390_get_unmapped_area_topdown;
  		mm->unmap_area = arch_unmap_area_topdown;
  	}
+diff --git a/arch/score/include/asm/cache.h b/arch/score/include/asm/cache.h
+index ae3d59f..f65f075 100644
+--- a/arch/score/include/asm/cache.h
++++ b/arch/score/include/asm/cache.h
+@@ -1,7 +1,9 @@
+ #ifndef _ASM_SCORE_CACHE_H
+ #define _ASM_SCORE_CACHE_H
+ 
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT		4
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #endif /* _ASM_SCORE_CACHE_H */
 diff --git a/arch/score/include/asm/system.h b/arch/score/include/asm/system.h
 index 589d5c7..669e274 100644
 --- a/arch/score/include/asm/system.h
@@ -4319,6 +5127,23 @@ index d936c1a..304a252 100644
  	.enter		= hp6x0_pm_enter,
  	.valid		= suspend_valid_only_mem,
  };
+diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h
+index 02df18e..ae3a793 100644
+--- a/arch/sh/include/asm/cache.h
++++ b/arch/sh/include/asm/cache.h
+@@ -9,10 +9,11 @@
+ #define __ASM_SH_CACHE_H
+ #ifdef __KERNEL__
+ 
++#include <linux/const.h>
+ #include <linux/init.h>
+ #include <cpu/cache.h>
+ 
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define __read_mostly __attribute__((__section__(".data.read_mostly")))
+ 
 diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
 index 8a8a993..7b3079b 100644
 --- a/arch/sh/kernel/cpu/sh4/sq.c
@@ -4461,17 +5286,19 @@ index 113225b..7fd04e7 100644
  VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
  VMLINUX_MAIN += $(drivers-y) $(net-y)
  
-diff --git a/arch/sparc/include/asm/atomic.h b/arch/sparc/include/asm/atomic.h
-index 8ff83d8..4a459c2 100644
---- a/arch/sparc/include/asm/atomic.h
-+++ b/arch/sparc/include/asm/atomic.h
-@@ -4,5 +4,6 @@
- #include <asm/atomic_64.h>
- #else
- #include <asm/atomic_32.h>
+diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h
+index f0d343c..cf36e68 100644
+--- a/arch/sparc/include/asm/atomic_32.h
++++ b/arch/sparc/include/asm/atomic_32.h
+@@ -13,6 +13,8 @@
+ 
+ #include <linux/types.h>
+ 
 +#include <asm-generic/atomic64.h>
- #endif
- #endif
++
+ #ifdef __KERNEL__
+ 
+ #include <asm/system.h>
 diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
 index f5cc06f..f858d47 100644
 --- a/arch/sparc/include/asm/atomic_64.h
@@ -4669,15 +5496,18 @@ index f5cc06f..f858d47 100644
  
  #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
 diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h
-index 41f85ae..fb54d5e 100644
+index 41f85ae..73b80b5 100644
 --- a/arch/sparc/include/asm/cache.h
 +++ b/arch/sparc/include/asm/cache.h
-@@ -8,7 +8,7 @@
+@@ -7,8 +7,10 @@
+ #ifndef _SPARC_CACHE_H
  #define _SPARC_CACHE_H
  
++#include <linux/const.h>
++
  #define L1_CACHE_SHIFT 5
 -#define L1_CACHE_BYTES 32
-+#define L1_CACHE_BYTES 32UL
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
  #define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)))
  
  #ifdef CONFIG_SPARC32
@@ -6965,6 +7795,26 @@ index fc633db..5e1a1c2 100644
  include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
  
  #This will adjust *FLAGS accordingly to the platform.
+diff --git a/arch/um/include/asm/cache.h b/arch/um/include/asm/cache.h
+index 19e1bdd..3665b77 100644
+--- a/arch/um/include/asm/cache.h
++++ b/arch/um/include/asm/cache.h
+@@ -1,6 +1,7 @@
+ #ifndef __UM_CACHE_H
+ #define __UM_CACHE_H
+ 
++#include <linux/const.h>
+ 
+ #if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
+ # define L1_CACHE_SHIFT		(CONFIG_X86_L1_CACHE_SHIFT)
+@@ -12,6 +13,6 @@
+ # define L1_CACHE_SHIFT		5
+ #endif
+ 
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #endif
 diff --git a/arch/um/include/asm/kmap_types.h b/arch/um/include/asm/kmap_types.h
 index 6c03acd..a5e0215 100644
 --- a/arch/um/include/asm/kmap_types.h
@@ -15884,7 +16734,7 @@ index c097e7d..c689cf4 100644
  /*
   * End of kprobes section
 diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
-index 34a56a9..87790b4 100644
+index 34a56a9..74613c5 100644
 --- a/arch/x86/kernel/entry_64.S
 +++ b/arch/x86/kernel/entry_64.S
 @@ -53,6 +53,8 @@
@@ -16267,7 +17117,7 @@ index 34a56a9..87790b4 100644
  	 * We entered an interrupt context - irqs are off:
  	 */
  2:	TRACE_IRQS_OFF
-+	pax_force_retaddr
++	pax_force_retaddr_bts
  	ret
  	CFI_ENDPROC
 -END(save_args)
@@ -27403,6 +28253,67 @@ index f9153a3..51eab3d 100644
  struct trap_info;
  void xen_copy_trap_info(struct trap_info *traps);
  
+diff --git a/arch/xtensa/variants/dc232b/include/variant/core.h b/arch/xtensa/variants/dc232b/include/variant/core.h
+index 525bd3d..ef888b1 100644
+--- a/arch/xtensa/variants/dc232b/include/variant/core.h
++++ b/arch/xtensa/variants/dc232b/include/variant/core.h
+@@ -119,9 +119,9 @@
+   ----------------------------------------------------------------------*/
+ 
+ #define XCHAL_ICACHE_LINESIZE		32	/* I-cache line size in bytes */
+-#define XCHAL_DCACHE_LINESIZE		32	/* D-cache line size in bytes */
+ #define XCHAL_ICACHE_LINEWIDTH		5	/* log2(I line size in bytes) */
+ #define XCHAL_DCACHE_LINEWIDTH		5	/* log2(D line size in bytes) */
++#define XCHAL_DCACHE_LINESIZE		(_AC(1,UL) << XCHAL_DCACHE_LINEWIDTH)	/* D-cache line size in bytes */
+ 
+ #define XCHAL_ICACHE_SIZE		16384	/* I-cache size in bytes or 0 */
+ #define XCHAL_DCACHE_SIZE		16384	/* D-cache size in bytes or 0 */
+diff --git a/arch/xtensa/variants/fsf/include/variant/core.h b/arch/xtensa/variants/fsf/include/variant/core.h
+index 2f33760..835e50a 100644
+--- a/arch/xtensa/variants/fsf/include/variant/core.h
++++ b/arch/xtensa/variants/fsf/include/variant/core.h
+@@ -11,6 +11,7 @@
+ #ifndef _XTENSA_CORE_H
+ #define _XTENSA_CORE_H
+ 
++#include <linux/const.h>
+ 
+ /****************************************************************************
+ 	    Parameters Useful for Any Code, USER or PRIVILEGED
+@@ -112,9 +113,9 @@
+   ----------------------------------------------------------------------*/
+ 
+ #define XCHAL_ICACHE_LINESIZE		16	/* I-cache line size in bytes */
+-#define XCHAL_DCACHE_LINESIZE		16	/* D-cache line size in bytes */
+ #define XCHAL_ICACHE_LINEWIDTH		4	/* log2(I line size in bytes) */
+ #define XCHAL_DCACHE_LINEWIDTH		4	/* log2(D line size in bytes) */
++#define XCHAL_DCACHE_LINESIZE		(_AC(1,UL) << XCHAL_DCACHE_LINEWIDTH) /* D-cache line size in bytes */
+ 
+ #define XCHAL_ICACHE_SIZE		8192	/* I-cache size in bytes or 0 */
+ #define XCHAL_DCACHE_SIZE		8192	/* D-cache size in bytes or 0 */
+diff --git a/arch/xtensa/variants/s6000/include/variant/core.h b/arch/xtensa/variants/s6000/include/variant/core.h
+index af00795..2bb8105 100644
+--- a/arch/xtensa/variants/s6000/include/variant/core.h
++++ b/arch/xtensa/variants/s6000/include/variant/core.h
+@@ -11,6 +11,7 @@
+ #ifndef _XTENSA_CORE_CONFIGURATION_H
+ #define _XTENSA_CORE_CONFIGURATION_H
+ 
++#include <linux/const.h>
+ 
+ /****************************************************************************
+ 	    Parameters Useful for Any Code, USER or PRIVILEGED
+@@ -118,9 +119,9 @@
+   ----------------------------------------------------------------------*/
+ 
+ #define XCHAL_ICACHE_LINESIZE		16	/* I-cache line size in bytes */
+-#define XCHAL_DCACHE_LINESIZE		16	/* D-cache line size in bytes */
+ #define XCHAL_ICACHE_LINEWIDTH		4	/* log2(I line size in bytes) */
+ #define XCHAL_DCACHE_LINEWIDTH		4	/* log2(D line size in bytes) */
++#define XCHAL_DCACHE_LINESIZE		(_AC(1,UL) << XCHAL_DCACHE_LINEWIDTH)	/* D-cache line size in bytes */
+ 
+ #define XCHAL_ICACHE_SIZE		32768	/* I-cache size in bytes or 0 */
+ #define XCHAL_DCACHE_SIZE		32768	/* D-cache size in bytes or 0 */
 diff --git a/block/blk-integrity.c b/block/blk-integrity.c
 index 15c6308..96e83c2 100644
 --- a/block/blk-integrity.c
@@ -36715,7 +37626,7 @@ index 968cb14..f0ad2e4 100644
  					       "raid1:%s: read error corrected "
  					       "(%d sectors at %llu on %s)\n",
 diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
-index 1b4e232..cf0f534 100644
+index 1b4e232..cf0f534b 100644
 --- a/drivers/md/raid10.c
 +++ b/drivers/md/raid10.c
 @@ -1255,7 +1255,7 @@ static void end_sync_read(struct bio *bio, int error)
@@ -38118,3742 +39029,20572 @@ index ab68886..ca405e8 100644
      MODULE_PARM(X, "1-" __MODULE_STRING(ATL2_MAX_NIC) "i"); \
      MODULE_PARM_DESC(X, desc);
  #else
-diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
-index 4874b2b..67f8526 100644
---- a/drivers/net/bnx2.c
-+++ b/drivers/net/bnx2.c
-@@ -5809,6 +5809,8 @@ bnx2_test_nvram(struct bnx2 *bp)
- 	int rc = 0;
- 	u32 magic, csum;
+diff --git a/drivers/net/benet/Makefile b/drivers/net/benet/Makefile
+index a60cd80..0ed11ef 100644
+--- a/drivers/net/benet/Makefile
++++ b/drivers/net/benet/Makefile
+@@ -1,7 +1,9 @@
+ #
+-# Makefile to build the network driver for ServerEngine's BladeEngine.
++# Makefile to build the be2net network driver
+ #
  
-+	pax_track_stack();
++EXTRA_CFLAGS += -DCONFIG_PALAU
 +
- 	if ((rc = bnx2_nvram_read(bp, 0, data, 4)) != 0)
- 		goto test_nvram_done;
+ obj-$(CONFIG_BE2NET) += be2net.o
  
-diff --git a/drivers/net/cxgb3/l2t.h b/drivers/net/cxgb3/l2t.h
-index fd3eb07..8a6978d 100644
---- a/drivers/net/cxgb3/l2t.h
-+++ b/drivers/net/cxgb3/l2t.h
-@@ -86,7 +86,7 @@ typedef void (*arp_failure_handler_func)(struct t3cdev * dev,
+-be2net-y :=  be_main.o be_cmds.o be_ethtool.o
++be2net-y :=  be_main.o be_cmds.o be_ethtool.o be_compat.o be_misc.o
+diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
+index 5c74ff0..7382603 100644
+--- a/drivers/net/benet/be.h
++++ b/drivers/net/benet/be.h
+@@ -1,18 +1,18 @@
+ /*
+- * Copyright (C) 2005 - 2009 ServerEngines
++ * Copyright (C) 2005 - 2011 Emulex
+  * All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation.  The full GNU General
++ * as published by the Free Software Foundation. The full GNU General
+  * Public License is included in this distribution in the file called COPYING.
+  *
+  * Contact Information:
+- * linux-drivers@serverengines.com
++ * linux-drivers@emulex.com
+  *
+- * ServerEngines
+- * 209 N. Fair Oaks Ave
+- * Sunnyvale, CA 94085
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
   */
- struct l2t_skb_cb {
- 	arp_failure_handler_func arp_failure_handler;
--};
-+} __no_const;
  
- #define L2T_SKB_CB(skb) ((struct l2t_skb_cb *)(skb)->cb)
+ #ifndef BE_H
+@@ -29,32 +29,53 @@
+ #include <linux/workqueue.h>
+ #include <linux/interrupt.h>
+ #include <linux/firmware.h>
++#include <linux/jhash.h>
++#ifndef CONFIG_PALAU
++#include <linux/inet_lro.h>
++#endif
  
-diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
-index 032cfe0..411af379 100644
---- a/drivers/net/cxgb3/t3_hw.c
-+++ b/drivers/net/cxgb3/t3_hw.c
-@@ -699,6 +699,8 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
- 	int i, addr, ret;
- 	struct t3_vpd vpd;
++#ifdef CONFIG_PALAU
++#include "be_compat.h"
++#endif
+ #include "be_hw.h"
  
-+	pax_track_stack();
-+
- 	/*
- 	 * Card information is normally at VPD_BASE but some early cards had
- 	 * it at 0.
-diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
-index d1e0563..b9e129c 100644
---- a/drivers/net/e1000e/82571.c
-+++ b/drivers/net/e1000e/82571.c
-@@ -212,7 +212,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
- {
- 	struct e1000_hw *hw = &adapter->hw;
- 	struct e1000_mac_info *mac = &hw->mac;
--	struct e1000_mac_operations *func = &mac->ops;
-+	e1000_mac_operations_no_const *func = &mac->ops;
- 	u32 swsm = 0;
- 	u32 swsm2 = 0;
- 	bool force_clear_smbi = false;
-@@ -1656,7 +1656,7 @@ static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw)
- 	temp = er32(ICRXDMTC);
+-#define DRV_VER			"2.101.205"
++#ifdef CONFIG_PALAU
++#include "version.h"
++#define	DRV_VER		STR_BE_MAJOR "." STR_BE_MINOR "."\
++				STR_BE_BUILD "." STR_BE_BRANCH
++#else
++#define DRV_VER			"2.0.348"
++#endif
+ #define DRV_NAME		"be2net"
+-#define BE_NAME			"ServerEngines BladeEngine2 10Gbps NIC"
+-#define BE3_NAME		"ServerEngines BladeEngine3 10Gbps NIC"
+-#define OC_NAME			"Emulex OneConnect 10Gbps NIC"
+-#define OC_NAME1		"Emulex OneConnect 10Gbps NIC (be3)"
+-#define DRV_DESC		BE_NAME "Driver"
++#define BE_NAME			"Emulex BladeEngine2"
++#define BE3_NAME		"Emulex BladeEngine3"
++#define OC_NAME			"Emulex OneConnect"
++#define OC_NAME_BE		OC_NAME "(be3)"
++#define OC_NAME_LANCER		OC_NAME "(Lancer)"
++#define DRV_DESC		"Emulex OneConnect 10Gbps NIC Driver"
+ 
+-#define BE_VENDOR_ID 		0x19a2
++#define	BE_VENDOR_ID		0x19a2
++#define EMULEX_VENDOR_ID	0x10df
+ #define BE_DEVICE_ID1		0x211
+ #define BE_DEVICE_ID2		0x221
+-#define OC_DEVICE_ID1		0x700
+-#define OC_DEVICE_ID2		0x701
+-#define OC_DEVICE_ID3		0x710
++#define OC_DEVICE_ID1		0x700	/* Device Id for BE2 cards */
++#define OC_DEVICE_ID2		0x710	/* Device Id for BE3 cards */
++#define OC_DEVICE_ID3		0xe220	/* Device id for Lancer cards */
++
++#define OC_SUBSYS_DEVICE_ID1	0xE602
++#define OC_SUBSYS_DEVICE_ID2	0xE642
++#define OC_SUBSYS_DEVICE_ID3	0xE612
++#define OC_SUBSYS_DEVICE_ID4	0xE652
+ 
+ static inline char *nic_name(struct pci_dev *pdev)
+ {
+ 	switch (pdev->device) {
+ 	case OC_DEVICE_ID1:
+-	case OC_DEVICE_ID2:
+ 		return OC_NAME;
++	case OC_DEVICE_ID2:
++		return OC_NAME_BE;
+ 	case OC_DEVICE_ID3:
+-		return OC_NAME1;
++		return OC_NAME_LANCER;
+ 	case BE_DEVICE_ID2:
+ 		return BE3_NAME;
+ 	default:
+@@ -63,7 +84,7 @@ static inline char *nic_name(struct pci_dev *pdev)
  }
  
--static struct e1000_mac_operations e82571_mac_ops = {
-+static const struct e1000_mac_operations e82571_mac_ops = {
- 	/* .check_mng_mode: mac type dependent */
- 	/* .check_for_link: media type dependent */
- 	.id_led_init		= e1000e_id_led_init,
-@@ -1674,7 +1674,7 @@ static struct e1000_mac_operations e82571_mac_ops = {
- 	.setup_led		= e1000e_setup_led_generic,
- };
+ /* Number of bytes of an RX frame that are copied to skb->data */
+-#define BE_HDR_LEN 		64
++#define BE_HDR_LEN		((u16) 64)
+ #define BE_MAX_JUMBO_FRAME_SIZE	9018
+ #define BE_MIN_MTU		256
  
--static struct e1000_phy_operations e82_phy_ops_igp = {
-+static const struct e1000_phy_operations e82_phy_ops_igp = {
- 	.acquire_phy		= e1000_get_hw_semaphore_82571,
- 	.check_reset_block	= e1000e_check_reset_block_generic,
- 	.commit_phy		= NULL,
-@@ -1691,7 +1691,7 @@ static struct e1000_phy_operations e82_phy_ops_igp = {
- 	.cfg_on_link_up      	= NULL,
- };
+@@ -79,10 +100,24 @@ static inline char *nic_name(struct pci_dev *pdev)
+ #define MCC_Q_LEN		128	/* total size not to exceed 8 pages */
+ #define MCC_CQ_LEN		256
  
--static struct e1000_phy_operations e82_phy_ops_m88 = {
-+static const struct e1000_phy_operations e82_phy_ops_m88 = {
- 	.acquire_phy		= e1000_get_hw_semaphore_82571,
- 	.check_reset_block	= e1000e_check_reset_block_generic,
- 	.commit_phy		= e1000e_phy_sw_reset,
-@@ -1708,7 +1708,7 @@ static struct e1000_phy_operations e82_phy_ops_m88 = {
- 	.cfg_on_link_up      	= NULL,
- };
++#define MAX_RSS_QS		4	/* BE limit is 4 queues/port */
++
++#define MAX_RX_QS		(MAX_RSS_QS + 1)
++
++#ifdef MQ_TX
++#define MAX_TX_QS		8
++#else
++#define MAX_TX_QS		1
++#endif
++
++#define BE_MAX_MSIX_VECTORS	(MAX_RX_QS + 1)/* RSS qs + 1 def Rx + Tx */
+ #define BE_NAPI_WEIGHT		64
+-#define MAX_RX_POST 		BE_NAPI_WEIGHT /* Frags posted at a time */
++#define MAX_RX_POST		BE_NAPI_WEIGHT /* Frags posted at a time */
+ #define RX_FRAGS_REFILL_WM	(RX_Q_LEN - MAX_RX_POST)
  
--static struct e1000_phy_operations e82_phy_ops_bm = {
-+static const struct e1000_phy_operations e82_phy_ops_bm = {
- 	.acquire_phy		= e1000_get_hw_semaphore_82571,
- 	.check_reset_block	= e1000e_check_reset_block_generic,
- 	.commit_phy		= e1000e_phy_sw_reset,
-@@ -1725,7 +1725,7 @@ static struct e1000_phy_operations e82_phy_ops_bm = {
- 	.cfg_on_link_up      	= NULL,
- };
++#define BE_MAX_LRO_DESCRIPTORS  16
++#define BE_MAX_FRAGS_PER_FRAME  (min((u32) 16, (u32) MAX_SKB_FRAGS))
++
+ #define FW_VER_LEN		32
  
--static struct e1000_nvm_operations e82571_nvm_ops = {
-+static const struct e1000_nvm_operations e82571_nvm_ops = {
- 	.acquire_nvm		= e1000_acquire_nvm_82571,
- 	.read_nvm		= e1000e_read_nvm_eerd,
- 	.release_nvm		= e1000_release_nvm_82571,
-diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
-index 47db9bd..fa58ccd 100644
---- a/drivers/net/e1000e/e1000.h
-+++ b/drivers/net/e1000e/e1000.h
-@@ -375,9 +375,9 @@ struct e1000_info {
- 	u32			pba;
- 	u32			max_hw_frame_size;
- 	s32			(*get_variants)(struct e1000_adapter *);
--	struct e1000_mac_operations *mac_ops;
--	struct e1000_phy_operations *phy_ops;
--	struct e1000_nvm_operations *nvm_ops;
-+	const struct e1000_mac_operations *mac_ops;
-+	const struct e1000_phy_operations *phy_ops;
-+	const struct e1000_nvm_operations *nvm_ops;
- };
+ struct be_dma_mem {
+@@ -127,6 +162,11 @@ static inline void *queue_tail_node(struct be_queue_info *q)
+ 	return q->dma_mem.va + q->tail * q->entry_size;
+ }
  
- /* hardware capability, feature, and workaround flags */
-diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
-index ae5d736..e9a93a1 100644
---- a/drivers/net/e1000e/es2lan.c
-+++ b/drivers/net/e1000e/es2lan.c
-@@ -207,7 +207,7 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter)
++static inline void *queue_index_node(struct be_queue_info *q, u16 index)
++{
++	return q->dma_mem.va + index * q->entry_size;
++}
++
+ static inline void queue_head_inc(struct be_queue_info *q)
  {
- 	struct e1000_hw *hw = &adapter->hw;
- 	struct e1000_mac_info *mac = &hw->mac;
--	struct e1000_mac_operations *func = &mac->ops;
-+	e1000_mac_operations_no_const *func = &mac->ops;
- 
- 	/* Set media type */
- 	switch (adapter->pdev->device) {
-@@ -1365,7 +1365,7 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
- 	temp = er32(ICRXDMTC);
+ 	index_inc(&q->head, q->len);
+@@ -137,6 +177,7 @@ static inline void queue_tail_inc(struct be_queue_info *q)
+ 	index_inc(&q->tail, q->len);
  }
  
--static struct e1000_mac_operations es2_mac_ops = {
-+static const struct e1000_mac_operations es2_mac_ops = {
- 	.id_led_init		= e1000e_id_led_init,
- 	.check_mng_mode		= e1000e_check_mng_mode_generic,
- 	/* check_for_link dependent on media type */
-@@ -1383,7 +1383,7 @@ static struct e1000_mac_operations es2_mac_ops = {
- 	.setup_led		= e1000e_setup_led_generic,
- };
++
+ struct be_eq_obj {
+ 	struct be_queue_info q;
+ 	char desc[32];
+@@ -146,6 +187,7 @@ struct be_eq_obj {
+ 	u16 min_eqd;		/* in usecs */
+ 	u16 max_eqd;		/* in usecs */
+ 	u16 cur_eqd;		/* in usecs */
++	u8  eq_idx;
  
--static struct e1000_phy_operations es2_phy_ops = {
-+static const struct e1000_phy_operations es2_phy_ops = {
- 	.acquire_phy		= e1000_acquire_phy_80003es2lan,
- 	.check_reset_block	= e1000e_check_reset_block_generic,
- 	.commit_phy	 	= e1000e_phy_sw_reset,
-@@ -1400,7 +1400,7 @@ static struct e1000_phy_operations es2_phy_ops = {
- 	.cfg_on_link_up      	= e1000_cfg_on_link_up_80003es2lan,
+ 	struct napi_struct napi;
  };
- 
--static struct e1000_nvm_operations es2_nvm_ops = {
-+static const struct e1000_nvm_operations es2_nvm_ops = {
- 	.acquire_nvm		= e1000_acquire_nvm_80003es2lan,
- 	.read_nvm		= e1000e_read_nvm_eerd,
- 	.release_nvm		= e1000_release_nvm_80003es2lan,
-diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
-index 11f3b7c..6381887 100644
---- a/drivers/net/e1000e/hw.h
-+++ b/drivers/net/e1000e/hw.h
-@@ -753,6 +753,7 @@ struct e1000_mac_operations {
- 	s32  (*setup_physical_interface)(struct e1000_hw *);
- 	s32  (*setup_led)(struct e1000_hw *);
+@@ -153,49 +195,20 @@ struct be_eq_obj {
+ struct be_mcc_obj {
+ 	struct be_queue_info q;
+ 	struct be_queue_info cq;
++	bool rearm_cq;
  };
-+typedef struct e1000_mac_operations __no_const e1000_mac_operations_no_const;
  
- /* Function pointers for the PHY. */
- struct e1000_phy_operations {
-@@ -774,6 +775,7 @@ struct e1000_phy_operations {
- 	s32  (*write_phy_reg_locked)(struct e1000_hw *, u32, u16);
- 	s32  (*cfg_on_link_up)(struct e1000_hw *);
+-struct be_drvr_stats {
++struct be_tx_stats {
+ 	u32 be_tx_reqs;		/* number of TX requests initiated */
+ 	u32 be_tx_stops;	/* number of times TX Q was stopped */
+-	u32 be_fwd_reqs;	/* number of send reqs through forwarding i/f */
+ 	u32 be_tx_wrbs;		/* number of tx WRBs used */
+-	u32 be_tx_events;	/* number of tx completion events  */
+ 	u32 be_tx_compl;	/* number of tx completion entries processed */
+ 	ulong be_tx_jiffies;
+ 	u64 be_tx_bytes;
+ 	u64 be_tx_bytes_prev;
+ 	u64 be_tx_pkts;
+ 	u32 be_tx_rate;
+-
+-	u32 cache_barrier[16];
+-
+-	u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */
+-	u32 be_polls;		/* number of times NAPI called poll function */
+-	u32 be_rx_events;	/* number of ucast rx completion events  */
+-	u32 be_rx_compl;	/* number of rx completion entries processed */
+-	ulong be_rx_jiffies;
+-	u64 be_rx_bytes;
+-	u64 be_rx_bytes_prev;
+-	u64 be_rx_pkts;
+-	u32 be_rx_rate;
+-	/* number of non ether type II frames dropped where
+-	 * frame len > length field of Mac Hdr */
+-	u32 be_802_3_dropped_frames;
+-	/* number of non ether type II frames malformed where
+-	 * in frame len < length field of Mac Hdr */
+-	u32 be_802_3_malformed_frames;
+-	u32 be_rxcp_err;	/* Num rx completion entries w/ err set. */
+-	ulong rx_fps_jiffies;	/* jiffies at last FPS calc */
+-	u32 be_rx_frags;
+-	u32 be_prev_rx_frags;
+-	u32 be_rx_fps;		/* Rx frags per second */
+-};
+-
+-struct be_stats_obj {
+-	struct be_drvr_stats drvr_stats;
+-	struct net_device_stats net_stats;
+-	struct be_dma_mem cmd;
++	u32 be_ipv6_ext_hdr_tx_drop;
  };
-+typedef struct e1000_phy_operations __no_const e1000_phy_operations_no_const;
  
- /* Function pointers for the NVM. */
- struct e1000_nvm_operations {
-@@ -785,9 +787,10 @@ struct e1000_nvm_operations {
- 	s32  (*validate_nvm)(struct e1000_hw *);
- 	s32  (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
+ struct be_tx_obj {
+@@ -203,23 +216,124 @@ struct be_tx_obj {
+ 	struct be_queue_info cq;
+ 	/* Remember the skbs that were transmitted */
+ 	struct sk_buff *sent_skb_list[TX_Q_LEN];
++	struct be_tx_stats stats;
  };
-+typedef struct e1000_nvm_operations __no_const e1000_nvm_operations_no_const;
  
- struct e1000_mac_info {
--	struct e1000_mac_operations ops;
-+	e1000_mac_operations_no_const ops;
+ /* Struct to remember the pages posted for rx frags */
+ struct be_rx_page_info {
+ 	struct page *page;
+-	dma_addr_t bus;
++	DEFINE_DMA_UNMAP_ADDR(bus);
+ 	u16 page_offset;
+ 	bool last_page_user;
+ };
+ 
++struct be_rx_stats {
++	u32 rx_post_fail;/* number of ethrx buffer alloc failures */
++	u32 rx_polls;	/* number of times NAPI called poll function */
++	u32 rx_events;	/* number of ucast rx completion events  */
++	u32 rx_compl;	/* number of rx completion entries processed */
++	ulong rx_jiffies;
++	u64 rx_bytes;
++	u64 rx_bytes_prev;
++	u64 rx_pkts;
++	u32 rx_rate;
++	u32 rx_mcast_pkts;
++	u32 rxcp_err;	/* Num rx completion entries w/ err set. */
++	ulong rx_fps_jiffies;	/* jiffies at last FPS calc */
++	u32 rx_frags;
++	u32 prev_rx_frags;
++	u32 rx_fps;		/* Rx frags per second */
++	u32 rx_drops_no_frags;
++};
++
++struct be_rx_compl_info {
++	u32 rss_hash;
++	u16 vlan_tag;
++	u16 pkt_size;
++	u16 rxq_idx;
++	u16 port;
++	u8 vlanf;
++	u8 num_rcvd;
++	u8 err;
++	u8 ipf;
++	u8 tcpf;
++	u8 udpf;
++	u8 ip_csum;
++	u8 l4_csum;
++	u8 ipv6;
++	u8 vtm;
++	u8 pkt_type;
++};
++
+ struct be_rx_obj {
++	struct be_adapter *adapter;
+ 	struct be_queue_info q;
+ 	struct be_queue_info cq;
+-	struct be_rx_page_info page_info_tbl[RX_Q_LEN];
++	struct be_rx_compl_info rxcp;
++	struct be_rx_page_info *page_info_tbl;
++	struct net_lro_mgr lro_mgr;
++	struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS];
++	struct be_eq_obj rx_eq;
++	struct be_rx_stats stats;
++	u8 rss_id;
++	bool rx_post_starved;	/* Zero rx frags have been posted to BE */
++	u16 prev_frag_idx;
++	u32 cache_line_barrier[16];
+ };
+ 
+-#define BE_NUM_MSIX_VECTORS		2	/* 1 each for Tx and Rx */
++struct be_drv_stats {
++	u32 be_on_die_temperature;
++	u32 be_tx_events;
++	u32 eth_red_drops;
++	u32 rx_drops_no_pbuf;
++	u32 rx_drops_no_txpb;
++	u32 rx_drops_no_erx_descr;
++	u32 rx_drops_no_tpre_descr;
++	u32 rx_drops_too_many_frags;
++	u32 rx_drops_invalid_ring;
++	u32 forwarded_packets;
++	u32 rx_drops_mtu;
++	u32 rx_crc_errors;
++	u32 rx_alignment_symbol_errors;
++	u32 rx_pause_frames;
++	u32 rx_priority_pause_frames;
++	u32 rx_control_frames;
++	u32 rx_in_range_errors;
++	u32 rx_out_range_errors;
++	u32 rx_frame_too_long;
++	u32 rx_address_match_errors;
++	u32 rx_dropped_too_small;
++	u32 rx_dropped_too_short;
++	u32 rx_dropped_header_too_small;
++	u32 rx_dropped_tcp_length;
++	u32 rx_dropped_runt;
++	u32 rx_ip_checksum_errs;
++	u32 rx_tcp_checksum_errs;
++	u32 rx_udp_checksum_errs;
++	u32 rx_switched_unicast_packets;
++	u32 rx_switched_multicast_packets;
++	u32 rx_switched_broadcast_packets;
++	u32 tx_pauseframes;
++	u32 tx_priority_pauseframes;
++	u32 tx_controlframes;
++	u32 rxpp_fifo_overflow_drop;
++	u32 rx_input_fifo_overflow_drop;
++	u32 pmem_fifo_overflow_drop;
++	u32 jabber_events;
++};
++
++struct be_vf_cfg {
++	unsigned char vf_mac_addr[ETH_ALEN];
++	u32 vf_if_handle;
++	u32 vf_pmac_id;
++	u16 vf_def_vid;
++	u16 vf_vlan_tag;
++	u32 vf_tx_rate;
++};
++
++#define BE_INVALID_PMAC_ID		0xffffffff
++#define BE_FLAGS_DCBX			(1 << 16)
++
+ struct be_adapter {
+ 	struct pci_dev *pdev;
+ 	struct net_device *netdev;
+@@ -228,7 +342,7 @@ struct be_adapter {
+ 	u8 __iomem *db;		/* Door Bell */
+ 	u8 __iomem *pcicfg;	/* PCI config space */
+ 
+-	spinlock_t mbox_lock;	/* For serializing mbox cmds to BE card */
++	struct mutex mbox_lock;	/* For serializing mbox cmds to BE card */
+ 	struct be_dma_mem mbox_mem;
+ 	/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
+ 	 * is stored for freeing purpose */
+@@ -238,66 +352,121 @@ struct be_adapter {
+ 	spinlock_t mcc_lock;	/* For serializing mcc cmds to BE card */
+ 	spinlock_t mcc_cq_lock;
+ 
+-	struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS];
+-	bool msix_enabled;
++	struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
++	u32 num_msix_vec;
+ 	bool isr_registered;
+ 
+ 	/* TX Rings */
+ 	struct be_eq_obj tx_eq;
+-	struct be_tx_obj tx_obj;
++	struct be_tx_obj tx_obj[MAX_TX_QS];
++	u8 num_tx_qs;
++	u8 prio_tc_map[MAX_TX_QS];	/* prio_tc_map[prio] => tc-id */
++	u8 tc_txq_map[MAX_TX_QS];	/* tc_txq_map[tc-id] => txq index */
+ 
+ 	u32 cache_line_break[8];
+ 
+ 	/* Rx rings */
+-	struct be_eq_obj rx_eq;
+-	struct be_rx_obj rx_obj;
++	struct be_rx_obj rx_obj[MAX_RX_QS]; /* one default non-rss Q */
++	u32 num_rx_qs;
++
++	struct be_dma_mem stats_cmd;
++	struct net_device_stats net_stats;
++	struct be_drv_stats drv_stats;
+ 	u32 big_page_size;	/* Compounded page size shared by rx wrbs */
+-	bool rx_post_starved;	/* Zero rx frags have been posted to BE */
+ 
+ 	struct vlan_group *vlan_grp;
+-	u16 num_vlans;
++	u16 vlans_added;
++	u16 max_vlans;	/* Number of vlans supported */
+ 	u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
++	u8 vlan_prio_bmap;		/* Available priority BitMap */
++	u16 recommended_prio;	/* Recommended Priority */
++	struct be_dma_mem rx_filter;
+ 
+-	struct be_stats_obj stats;
+ 	/* Work queue used to perform periodic tasks like getting statistics */
+ 	struct delayed_work work;
++	u16 work_counter;
+ 
+-	/* Ethtool knobs and info */
+-	bool rx_csum; 		/* BE card must perform rx-checksumming */
++	u32 flags;
++	bool rx_csum;		/* BE card must perform rx-checksumming */
++	u32 max_rx_coal;
+ 	char fw_ver[FW_VER_LEN];
+ 	u32 if_handle;		/* Used to configure filtering */
+ 	u32 pmac_id;		/* MAC addr handle used by BE card */
++	u32 beacon_state;       /* for set_phys_id */
+ 
+-	bool link_up;
++	bool eeh_err;
++	int link_status;
+ 	u32 port_num;
++	u32 hba_port_num;
+ 	bool promiscuous;
+-	u32 cap;
++	bool wol;
++	u32 function_mode;
++	u32 function_caps;
+ 	u32 rx_fc;		/* Rx flow control */
+ 	u32 tx_fc;		/* Tx flow control */
++	bool ue_detected;
++	bool stats_cmd_sent;
++	bool gro_supported;
++	int link_speed;
++	u8 port_type;
++	u8 transceiver;
++	u8 autoneg;
+ 	u8 generation;		/* BladeEngine ASIC generation */
++	u32 flash_status;
++	struct completion flash_compl;
++
++	u8 eq_next_idx;
++	bool be3_native;
++	u16 num_vfs;
++	struct be_vf_cfg *vf_cfg;
++	u8 is_virtfn;
++	u16 pvid;
++	u32 sli_family;
++	u8 port_name[4];
++	char model_number[32];
+ };
+ 
+ /* BladeEngine Generation numbers */
+ #define BE_GEN2 2
+ #define BE_GEN3 3
+ 
+-extern const struct ethtool_ops be_ethtool_ops;
++#define ON     1
++#define OFF    0
++#define lancer_chip(adapter)		(adapter->pdev->device == OC_DEVICE_ID3)
++#define lancer_A0_chip(adapter)						\
++		(adapter->sli_family == LANCER_A0_SLI_FAMILY)
+ 
+-#define drvr_stats(adapter)		(&adapter->stats.drvr_stats)
++extern struct ethtool_ops be_ethtool_ops;
+ 
+-static inline unsigned int be_pci_func(struct be_adapter *adapter)
+-{
+-	return PCI_FUNC(adapter->pdev->devfn);
+-}
++#define msix_enabled(adapter)		(adapter->num_msix_vec > 0)
++#define tx_stats(txo)			(&txo->stats)
++#define rx_stats(rxo)			(&rxo->stats)
  
- 	u8 addr[6];
- 	u8 perm_addr[6];
-@@ -823,7 +826,7 @@ struct e1000_mac_info {
- };
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
++#define BE_SET_NETDEV_OPS(netdev, ops)	be_netdev_ops_init(netdev, ops)
++#else
+ #define BE_SET_NETDEV_OPS(netdev, ops)	(netdev->netdev_ops = ops)
++#endif
++
++#define for_all_rx_queues(adapter, rxo, i)				\
++	for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs;	\
++		i++, rxo++)
++
++/* Just skip the first default non-rss queue */
++#define for_all_rss_queues(adapter, rxo, i)				\
++	for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\
++		i++, rxo++)
++
++#define for_all_tx_queues(adapter, txo, i)				\
++	for (i = 0, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs;	\
++		i++, txo++)
  
- struct e1000_phy_info {
--	struct e1000_phy_operations ops;
-+	e1000_phy_operations_no_const ops;
+ #define PAGE_SHIFT_4K		12
+ #define PAGE_SIZE_4K		(1 << PAGE_SHIFT_4K)
  
- 	enum e1000_phy_type type;
+ /* Returns number of pages spanned by the data starting at the given addr */
+-#define PAGES_4K_SPANNED(_address, size) 				\
+-		((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + 	\
++#define PAGES_4K_SPANNED(_address, size)				\
++	((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) +	\
+ 			(size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
  
-@@ -857,7 +860,7 @@ struct e1000_phy_info {
- };
+ /* Byte offset into the page corresponding to given address */
+@@ -305,7 +474,7 @@ static inline unsigned int be_pci_func(struct be_adapter *adapter)
+ 		 ((size_t)(addr) & (PAGE_SIZE_4K-1))
  
- struct e1000_nvm_info {
--	struct e1000_nvm_operations ops;
-+	e1000_nvm_operations_no_const ops;
+ /* Returns bit offset within a DWORD of a bitfield */
+-#define AMAP_BIT_OFFSET(_struct, field)  				\
++#define AMAP_BIT_OFFSET(_struct, field)					\
+ 		(((size_t)&(((_struct *)0)->field))%32)
  
- 	enum e1000_nvm_type type;
- 	enum e1000_nvm_override override;
-diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
-index de39f9a..e28d3e0 100644
---- a/drivers/net/e1000e/ich8lan.c
-+++ b/drivers/net/e1000e/ich8lan.c
-@@ -3463,7 +3463,7 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
- 	}
+ /* Returns the bit mask of the field that is NOT shifted into location. */
+@@ -356,6 +525,11 @@ static inline void swap_dws(void *wrb, int len)
+ #endif				/* __BIG_ENDIAN */
  }
  
--static struct e1000_mac_operations ich8_mac_ops = {
-+static const struct e1000_mac_operations ich8_mac_ops = {
- 	.id_led_init		= e1000e_id_led_init,
- 	.check_mng_mode		= e1000_check_mng_mode_ich8lan,
- 	.check_for_link		= e1000_check_for_copper_link_ich8lan,
-@@ -3481,7 +3481,7 @@ static struct e1000_mac_operations ich8_mac_ops = {
- 	/* id_led_init dependent on mac type */
- };
++static inline bool vlan_configured(struct be_adapter *adapter)
++{
++	return adapter->vlan_grp && adapter->vlans_added;
++}
++
+ static inline u8 is_tcp_pkt(struct sk_buff *skb)
+ {
+ 	u8 val = 0;
+@@ -380,9 +554,65 @@ static inline u8 is_udp_pkt(struct sk_buff *skb)
+ 	return val;
+ }
  
--static struct e1000_phy_operations ich8_phy_ops = {
-+static const struct e1000_phy_operations ich8_phy_ops = {
- 	.acquire_phy		= e1000_acquire_swflag_ich8lan,
- 	.check_reset_block	= e1000_check_reset_block_ich8lan,
- 	.commit_phy		= NULL,
-@@ -3497,7 +3497,7 @@ static struct e1000_phy_operations ich8_phy_ops = {
- 	.write_phy_reg		= e1000e_write_phy_reg_igp,
- };
++static inline u8 is_ipv6_ext_hdr(struct sk_buff *skb)
++{
++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
++	if (ip_hdr(skb)->version == 6)
++		return ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr);
++	else
++#endif
++		return 0;
++}
++
++static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
++{
++	u32 sli_intf;
++
++	pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
++	adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
++}
++
++static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
++{
++	u32 addr;
++
++	addr = jhash(adapter->netdev->dev_addr, ETH_ALEN, 0);
++
++	mac[5] = (u8)(addr & 0xFF);
++	mac[4] = (u8)((addr >> 8) & 0xFF);
++	mac[3] = (u8)((addr >> 16) & 0xFF);
++	/* Use the OUI programmed in hardware */
++	memcpy(mac, adapter->netdev->dev_addr, 3);
++}
++
++static inline u16 be_get_tx_vlan_tag(struct be_adapter *adapter,
++					struct sk_buff *skb)
++{
++	u8 vlan_prio = 0;
++	u16 vlan_tag = 0;
++
++	vlan_tag = vlan_tx_tag_get(skb);
++	vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
++	/* If vlan priority provided by OS is NOT in available bmap */
++	if (!(adapter->vlan_prio_bmap & (1 << vlan_prio)))
++		vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) |
++				adapter->recommended_prio;
++
++	return vlan_tag;
++}
++
++#define be_physfn(adapter) (!adapter->is_virtfn)
++
+ extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
+ 		u16 num_popped);
+-extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
++extern void be_link_status_update(struct be_adapter *adapter, int link_status);
+ extern void netdev_stats_update(struct be_adapter *adapter);
++extern void be_parse_stats(struct be_adapter *adapter);
+ extern int be_load_fw(struct be_adapter *adapter, u8 *func);
++
++#ifdef CONFIG_PALAU
++extern void be_sysfs_create_group(struct be_adapter *adapter);
++extern void be_sysfs_remove_group(struct be_adapter *adapter);
++#endif
++
+ #endif				/* BE_H */
+diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
+index 28a0eda..b4ca89c 100644
+--- a/drivers/net/benet/be_cmds.c
++++ b/drivers/net/benet/be_cmds.c
+@@ -1,30 +1,45 @@
+ /*
+- * Copyright (C) 2005 - 2009 ServerEngines
++ * Copyright (C) 2005 - 2011 Emulex
+  * All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation.  The full GNU General
++ * as published by the Free Software Foundation. The full GNU General
+  * Public License is included in this distribution in the file called COPYING.
+  *
+  * Contact Information:
+- * linux-drivers@serverengines.com
++ * linux-drivers@emulex.com
+  *
+- * ServerEngines
+- * 209 N. Fair Oaks Ave
+- * Sunnyvale, CA 94085
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
+  */
  
--static struct e1000_nvm_operations ich8_nvm_ops = {
-+static const struct e1000_nvm_operations ich8_nvm_ops = {
- 	.acquire_nvm		= e1000_acquire_nvm_ich8lan,
- 	.read_nvm	 	= e1000_read_nvm_ich8lan,
- 	.release_nvm		= e1000_release_nvm_ich8lan,
-diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
-index 18d5fbb..542d96d 100644
---- a/drivers/net/fealnx.c
-+++ b/drivers/net/fealnx.c
-@@ -151,7 +151,7 @@ struct chip_info {
- 	int flags;
- };
+ #include "be.h"
+ #include "be_cmds.h"
  
--static const struct chip_info skel_netdrv_tbl[] __devinitdata = {
-+static const struct chip_info skel_netdrv_tbl[] __devinitconst = {
-  	{ "100/10M Ethernet PCI Adapter",	HAS_MII_XCVR },
- 	{ "100/10M Ethernet PCI Adapter",	HAS_CHIP_XCVR },
- 	{ "1000/100/10M Ethernet PCI Adapter",	HAS_MII_XCVR },
-diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
-index 0e5b54b..b503f82 100644
---- a/drivers/net/hamradio/6pack.c
-+++ b/drivers/net/hamradio/6pack.c
-@@ -461,6 +461,8 @@ static void sixpack_receive_buf(struct tty_struct *tty,
- 	unsigned char buf[512];
- 	int count1;
++/* Must be a power of 2 or else MODULO will BUG_ON */
++static int be_get_temp_freq = 64;
++
++static inline void *embedded_payload(struct be_mcc_wrb *wrb)
++{
++	return wrb->payload.embedded_payload;
++}
++
+ static void be_mcc_notify(struct be_adapter *adapter)
+ {
+ 	struct be_queue_info *mccq = &adapter->mcc_obj.q;
+ 	u32 val = 0;
  
-+	pax_track_stack();
++	if (adapter->eeh_err) {
++		dev_info(&adapter->pdev->dev, "Error in Card Detected! Cannot issue commands\n");
++		return;
++	}
 +
- 	if (!count)
- 		return;
+ 	val |= mccq->id & DB_MCCQ_RING_ID_MASK;
+ 	val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
++
++	wmb();
+ 	iowrite32(val, adapter->db + DB_MCCQ_OFFSET);
+ }
  
-diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
-index 5862282..7cce8cb 100644
---- a/drivers/net/ibmveth.c
-+++ b/drivers/net/ibmveth.c
-@@ -1577,7 +1577,7 @@ static struct attribute * veth_pool_attrs[] = {
- 	NULL,
- };
+@@ -59,21 +74,67 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
  
--static struct sysfs_ops veth_pool_ops = {
-+static const struct sysfs_ops veth_pool_ops = {
- 	.show   = veth_pool_show,
- 	.store  = veth_pool_store,
- };
-diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
-index d617f2d..57b5309 100644
---- a/drivers/net/igb/e1000_82575.c
-+++ b/drivers/net/igb/e1000_82575.c
-@@ -1411,7 +1411,7 @@ void igb_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
- 	wr32(E1000_VT_CTL, vt_ctl);
+ 	compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
+ 				CQE_STATUS_COMPL_MASK;
++
++	if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) &&
++		(compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
++		adapter->flash_status = compl_status;
++		complete(&adapter->flash_compl);
++	}
++
+ 	if (compl_status == MCC_STATUS_SUCCESS) {
+-		if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
+-			struct be_cmd_resp_get_stats *resp =
+-						adapter->stats.cmd.va;
+-			be_dws_le_to_cpu(&resp->hw_stats,
+-						sizeof(resp->hw_stats));
++		if ((compl->tag0 == OPCODE_ETH_GET_STATISTICS) &&
++			(compl->tag1 == CMD_SUBSYSTEM_ETH)) {
++			if (adapter->generation == BE_GEN3) {
++				struct be_cmd_resp_get_stats_v1 *resp =
++							adapter->stats_cmd.va;
++
++				be_dws_le_to_cpu(&resp->hw_stats,
++							sizeof(resp->hw_stats));
++			} else {
++				struct be_cmd_resp_get_stats_v0 *resp =
++							adapter->stats_cmd.va;
++
++				be_dws_le_to_cpu(&resp->hw_stats,
++							sizeof(resp->hw_stats));
++			}
++			be_parse_stats(adapter);
+ 			netdev_stats_update(adapter);
++			adapter->stats_cmd_sent = false;
++		}
++		if (compl->tag0 ==
++				OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES) {
++			struct be_mcc_wrb *mcc_wrb =
++				queue_index_node(&adapter->mcc_obj.q,
++						compl->tag1);
++			struct be_cmd_resp_get_cntl_addnl_attribs *resp =
++				embedded_payload(mcc_wrb);
++			adapter->drv_stats.be_on_die_temperature =
++				resp->on_die_temperature;
++		}
++	} else {
++		if (compl->tag0 == OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES)
++			be_get_temp_freq = 0;
++
++		if (compl->tag1 == MCC_WRB_PASS_THRU)
++			goto done;
++
++	 	if (compl_status == MCC_STATUS_NOT_SUPPORTED ||
++			compl_status == MCC_STATUS_ILLEGAL_REQUEST)
++			goto done;
++
++		if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
++			dev_warn(&adapter->pdev->dev, "This domain(VM) is not "
++				"permitted to execute this cmd (opcode %d)\n",
++				compl->tag0);
++		} else {
++			extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
++					CQE_STATUS_EXTD_MASK;
++			dev_err(&adapter->pdev->dev, "Cmd (opcode %d) failed:"
++				"status %d, extd-status %d\n",
++				compl->tag0, compl_status, extd_status);
+ 		}
+-	} else if (compl_status != MCC_STATUS_NOT_SUPPORTED) {
+-		extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
+-				CQE_STATUS_EXTD_MASK;
+-		dev_warn(&adapter->pdev->dev,
+-			"Error in cmd completion: status(compl/extd)=%d/%d\n",
+-			compl_status, extd_status);
+ 	}
++done:
+ 	return compl_status;
  }
  
--static struct e1000_mac_operations e1000_mac_ops_82575 = {
-+static const struct e1000_mac_operations e1000_mac_ops_82575 = {
- 	.reset_hw             = igb_reset_hw_82575,
- 	.init_hw              = igb_init_hw_82575,
- 	.check_for_link       = igb_check_for_link_82575,
-@@ -1420,13 +1420,13 @@ static struct e1000_mac_operations e1000_mac_ops_82575 = {
- 	.get_speed_and_duplex = igb_get_speed_and_duplex_copper,
- };
+@@ -82,7 +143,70 @@ static void be_async_link_state_process(struct be_adapter *adapter,
+ 		struct be_async_event_link_state *evt)
+ {
+ 	be_link_status_update(adapter,
+-		evt->port_link_status == ASYNC_EVENT_LINK_UP);
++		((evt->port_link_status & ~ASYNC_EVENT_LOGICAL) ==
++			ASYNC_EVENT_LINK_UP  ? LINK_UP : LINK_DOWN));
++}
++
++/* Grp5 CoS Priority evt */
++static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
++		struct be_async_event_grp5_cos_priority *evt)
++{
++	if (evt->valid) {
++		adapter->vlan_prio_bmap = evt->available_priority_bmap;
++		adapter->recommended_prio &= ~VLAN_PRIO_MASK;
++		adapter->recommended_prio =
++			evt->reco_default_priority << VLAN_PRIO_SHIFT;
++	}
++}
++
++/* Grp5 QOS Speed evt */
++static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
++		struct be_async_event_grp5_qos_link_speed *evt)
++{
++	if (evt->physical_port == adapter->hba_port_num) {
++		/* qos_link_speed is in units of 10 Mbps */
++		adapter->link_speed = evt->qos_link_speed * 10;
++	}
++}
++
++/*Grp5 PVID evt*/
++static void be_async_grp5_pvid_state_process(struct be_adapter *adapter,
++		struct be_async_event_grp5_pvid_state *evt)
++{
++	if (evt->enabled)
++		adapter->pvid = le16_to_cpu(evt->tag) & VLAN_VID_MASK ;
++	else
++		adapter->pvid = 0;
++}
++
++static void be_async_grp5_evt_process(struct be_adapter *adapter,
++		u32 trailer, struct be_mcc_compl *evt)
++{
++	u8 event_type = 0;
++
++	event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
++		ASYNC_TRAILER_EVENT_TYPE_MASK;
++
++	switch (event_type) {
++	case ASYNC_EVENT_COS_PRIORITY:
++		be_async_grp5_cos_priority_process(adapter,
++		(struct be_async_event_grp5_cos_priority *)evt);
++	break;
++	case ASYNC_EVENT_QOS_SPEED:
++		be_async_grp5_qos_speed_process(adapter,
++		(struct be_async_event_grp5_qos_link_speed *)evt);
++	break;
++	case ASYNC_EVENT_PVID_STATE:
++		be_async_grp5_pvid_state_process(adapter,
++		(struct be_async_event_grp5_pvid_state *)evt);
++	break;
++	case GRP5_TYPE_PRIO_TC_MAP:
++		memcpy(adapter->prio_tc_map, evt, MAX_TX_QS);			
++	break;
++	default:
++		printk(KERN_WARNING "Unknown grp5 event!\n");
++	break;
++	}
+ }
  
--static struct e1000_phy_operations e1000_phy_ops_82575 = {
-+static const struct e1000_phy_operations e1000_phy_ops_82575 = {
- 	.acquire              = igb_acquire_phy_82575,
- 	.get_cfg_done         = igb_get_cfg_done_82575,
- 	.release              = igb_release_phy_82575,
- };
+ static inline bool is_link_state_evt(u32 trailer)
+@@ -92,6 +216,13 @@ static inline bool is_link_state_evt(u32 trailer)
+ 				ASYNC_EVENT_CODE_LINK_STATE);
+ }
  
--static struct e1000_nvm_operations e1000_nvm_ops_82575 = {
-+static const struct e1000_nvm_operations e1000_nvm_ops_82575 = {
- 	.acquire              = igb_acquire_nvm_82575,
- 	.read                 = igb_read_nvm_eerd,
- 	.release              = igb_release_nvm_82575,
-diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
-index 72081df..d855cf5 100644
---- a/drivers/net/igb/e1000_hw.h
-+++ b/drivers/net/igb/e1000_hw.h
-@@ -288,6 +288,7 @@ struct e1000_mac_operations {
- 	s32  (*read_mac_addr)(struct e1000_hw *);
- 	s32  (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
- };
-+typedef struct e1000_mac_operations __no_const e1000_mac_operations_no_const;
++static inline bool is_grp5_evt(u32 trailer)
++{
++	return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
++		ASYNC_TRAILER_EVENT_CODE_MASK) ==
++				ASYNC_EVENT_CODE_GRP_5);
++}
++
+ static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
+ {
+ 	struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
+@@ -104,46 +235,67 @@ static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
+ 	return NULL;
+ }
  
- struct e1000_phy_operations {
- 	s32  (*acquire)(struct e1000_hw *);
-@@ -303,6 +304,7 @@ struct e1000_phy_operations {
- 	s32  (*set_d3_lplu_state)(struct e1000_hw *, bool);
- 	s32  (*write_reg)(struct e1000_hw *, u32, u16);
- };
-+typedef struct e1000_phy_operations __no_const e1000_phy_operations_no_const;
+-int be_process_mcc(struct be_adapter *adapter)
++void be_async_mcc_enable(struct be_adapter *adapter)
++{
++	spin_lock_bh(&adapter->mcc_cq_lock);
++
++	be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, 0);
++	adapter->mcc_obj.rearm_cq = true;
++
++	spin_unlock_bh(&adapter->mcc_cq_lock);
++}
++
++void be_async_mcc_disable(struct be_adapter *adapter)
++{
++	adapter->mcc_obj.rearm_cq = false;
++}
++
++int be_process_mcc(struct be_adapter *adapter, int *status)
+ {
+ 	struct be_mcc_compl *compl;
+-	int num = 0, status = 0;
++	int num = 0;
++	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
  
- struct e1000_nvm_operations {
- 	s32  (*acquire)(struct e1000_hw *);
-@@ -310,6 +312,7 @@ struct e1000_nvm_operations {
- 	void (*release)(struct e1000_hw *);
- 	s32  (*write)(struct e1000_hw *, u16, u16, u16 *);
- };
-+typedef struct e1000_nvm_operations __no_const e1000_nvm_operations_no_const;
+ 	spin_lock_bh(&adapter->mcc_cq_lock);
+ 	while ((compl = be_mcc_compl_get(adapter))) {
+ 		if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
+ 			/* Interpret flags as an async trailer */
+-			BUG_ON(!is_link_state_evt(compl->flags));
+-
+-			/* Interpret compl as a async link evt */
+-			be_async_link_state_process(adapter,
++			if (is_link_state_evt(compl->flags))
++				be_async_link_state_process(adapter,
+ 				(struct be_async_event_link_state *) compl);
++			else if (is_grp5_evt(compl->flags))
++				be_async_grp5_evt_process(adapter,
++				compl->flags, compl);
++
+ 		} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
+-				status = be_mcc_compl_process(adapter, compl);
+-				atomic_dec(&adapter->mcc_obj.q.used);
++				*status = be_mcc_compl_process(adapter, compl);
++				atomic_dec(&mcc_obj->q.used);
+ 		}
+ 		be_mcc_compl_use(compl);
+ 		num++;
+ 	}
  
- struct e1000_info {
- 	s32 (*get_invariants)(struct e1000_hw *);
-@@ -321,7 +324,7 @@ struct e1000_info {
- extern const struct e1000_info e1000_82575_info;
+-	if (num)
+-		be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, num);
+-
+ 	spin_unlock_bh(&adapter->mcc_cq_lock);
+-	return status;
++	return num;
+ }
  
- struct e1000_mac_info {
--	struct e1000_mac_operations ops;
-+	e1000_mac_operations_no_const ops;
+ /* Wait till no more pending mcc requests are present */
+ static int be_mcc_wait_compl(struct be_adapter *adapter)
+ {
+ #define mcc_timeout		120000 /* 12s timeout */
+-	int i, status;
++	int i, num, status = 0;
++	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
++
++	if (adapter->eeh_err)
++		return -EIO;
++
+ 	for (i = 0; i < mcc_timeout; i++) {
+-		status = be_process_mcc(adapter);
+-		if (status)
+-			return status;
++		num = be_process_mcc(adapter, &status);
++		if (num)
++			be_cq_notify(adapter, mcc_obj->cq.id,
++				mcc_obj->rearm_cq, num);
  
- 	u8 addr[6];
- 	u8 perm_addr[6];
-@@ -365,7 +368,7 @@ struct e1000_mac_info {
- };
+-		if (atomic_read(&adapter->mcc_obj.q.used) == 0)
++		if (atomic_read(&mcc_obj->q.used) == 0)
+ 			break;
+ 		udelay(100);
+ 	}
+@@ -151,7 +303,7 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
+ 		dev_err(&adapter->pdev->dev, "mccq poll timed out\n");
+ 		return -1;
+ 	}
+-	return 0;
++	return status;
+ }
  
- struct e1000_phy_info {
--	struct e1000_phy_operations ops;
-+	e1000_phy_operations_no_const ops;
+ /* Notify MCC requests and wait for completion */
+@@ -163,23 +315,34 @@ static int be_mcc_notify_wait(struct be_adapter *adapter)
  
- 	enum e1000_phy_type type;
+ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
+ {
+-	int cnt = 0, wait = 5;
++	int msecs = 0;
+ 	u32 ready;
  
-@@ -400,7 +403,7 @@ struct e1000_phy_info {
- };
++	if (adapter->eeh_err) {
++		dev_err(&adapter->pdev->dev, "Error detected in card.Cannot issue commands\n");
++		return -EIO;
++	}
+ 	do {
+-		ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
++		ready = ioread32(db);
++		if (ready == 0xffffffff) {
++			dev_err(&adapter->pdev->dev,
++				"pci slot disconnected\n");
++			return -1;
++		}
++
++		ready &= MPU_MAILBOX_DB_RDY_MASK;
+ 		if (ready)
+ 			break;
  
- struct e1000_nvm_info {
--	struct e1000_nvm_operations ops;
-+	e1000_nvm_operations_no_const ops;
+-		if (cnt > 4000000) {
++		if (msecs > 4000) {
+ 			dev_err(&adapter->pdev->dev, "mbox poll timed out\n");
++			be_detect_dump_ue(adapter);
+ 			return -1;
+ 		}
  
- 	enum e1000_nvm_type type;
- 	enum e1000_nvm_override override;
-@@ -446,6 +449,7 @@ struct e1000_mbx_operations {
- 	s32 (*check_for_ack)(struct e1000_hw *, u16);
- 	s32 (*check_for_rst)(struct e1000_hw *, u16);
- };
-+typedef struct e1000_mbx_operations __no_const e1000_mbx_operations_no_const;
+-		if (cnt > 50)
+-			wait = 200;
+-		cnt += wait;
+-		udelay(wait);
++		set_current_state(TASK_UNINTERRUPTIBLE);
++		schedule_timeout(msecs_to_jiffies(1));
++		msecs++;
+ 	} while (true);
  
- struct e1000_mbx_stats {
- 	u32 msgs_tx;
-@@ -457,7 +461,7 @@ struct e1000_mbx_stats {
- };
+ 	return 0;
+@@ -198,6 +361,11 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
+ 	struct be_mcc_mailbox *mbox = mbox_mem->va;
+ 	struct be_mcc_compl *compl = &mbox->compl;
  
- struct e1000_mbx_info {
--	struct e1000_mbx_operations ops;
-+	e1000_mbx_operations_no_const ops;
- 	struct e1000_mbx_stats stats;
- 	u32 timeout;
- 	u32 usec_delay;
-diff --git a/drivers/net/igbvf/vf.h b/drivers/net/igbvf/vf.h
-index 1e8ce37..549c453 100644
---- a/drivers/net/igbvf/vf.h
-+++ b/drivers/net/igbvf/vf.h
-@@ -187,9 +187,10 @@ struct e1000_mac_operations {
- 	s32  (*read_mac_addr)(struct e1000_hw *);
- 	s32  (*set_vfta)(struct e1000_hw *, u16, bool);
- };
-+typedef struct e1000_mac_operations __no_const e1000_mac_operations_no_const;
++	/* wait for ready to be set */
++	status = be_mbox_db_ready_wait(adapter, db);
++	if (status != 0)
++		return status;
++
+ 	val |= MPU_MAILBOX_DB_HI_MASK;
+ 	/* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
+ 	val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
+@@ -232,7 +400,12 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
  
- struct e1000_mac_info {
--	struct e1000_mac_operations ops;
-+	e1000_mac_operations_no_const ops;
- 	u8 addr[6];
- 	u8 perm_addr[6];
+ static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
+ {
+-	u32 sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET);
++	u32 sem;
++
++	if (lancer_chip(adapter))
++		sem  = ioread32(adapter->db + MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET);
++	else
++		sem  = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET);
  
-@@ -211,6 +212,7 @@ struct e1000_mbx_operations {
- 	s32 (*check_for_ack)(struct e1000_hw *);
- 	s32 (*check_for_rst)(struct e1000_hw *);
- };
-+typedef struct e1000_mbx_operations __no_const e1000_mbx_operations_no_const;
+ 	*stage = sem & EP_SEMAPHORE_POST_STAGE_MASK;
+ 	if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK)
+@@ -245,30 +418,29 @@ int be_cmd_POST(struct be_adapter *adapter)
+ {
+ 	u16 stage;
+ 	int status, timeout = 0;
++	struct device *dev = &adapter->pdev->dev;
  
- struct e1000_mbx_stats {
- 	u32 msgs_tx;
-@@ -222,7 +224,7 @@ struct e1000_mbx_stats {
- };
+ 	do {
+ 		status = be_POST_stage_get(adapter, &stage);
+ 		if (status) {
+-			dev_err(&adapter->pdev->dev, "POST error; stage=0x%x\n",
+-				stage);
++			dev_err(dev, "POST error; stage=0x%x\n", stage);
+ 			return -1;
+ 		} else if (stage != POST_STAGE_ARMFW_RDY) {
+ 			set_current_state(TASK_INTERRUPTIBLE);
+-			schedule_timeout(2 * HZ);
++			if (schedule_timeout(2 * HZ)) {
++				dev_err(dev, "POST cmd aborted\n");
++				return -EINTR;
++			}
+ 			timeout += 2;
+ 		} else {
+ 			return 0;
+ 		}
+-	} while (timeout < 20);
++	} while (timeout < 40);
  
- struct e1000_mbx_info {
--	struct e1000_mbx_operations ops;
-+	e1000_mbx_operations_no_const ops;
- 	struct e1000_mbx_stats stats;
- 	u32 timeout;
- 	u32 usec_delay;
-diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
-index aa7286b..a61394f 100644
---- a/drivers/net/iseries_veth.c
-+++ b/drivers/net/iseries_veth.c
-@@ -384,7 +384,7 @@ static struct attribute *veth_cnx_default_attrs[] = {
- 	NULL
- };
+-	dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage);
++	dev_err(dev, "POST timeout; stage=0x%x\n", stage);
+ 	return -1;
+ }
  
--static struct sysfs_ops veth_cnx_sysfs_ops = {
-+static const struct sysfs_ops veth_cnx_sysfs_ops = {
- 		.show = veth_cnx_attribute_show
- };
+-static inline void *embedded_payload(struct be_mcc_wrb *wrb)
+-{
+-	return wrb->payload.embedded_payload;
+-}
  
-@@ -441,7 +441,7 @@ static struct attribute *veth_port_default_attrs[] = {
- 	NULL
- };
+ static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb)
+ {
+@@ -277,7 +449,7 @@ static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb)
  
--static struct sysfs_ops veth_port_sysfs_ops = {
-+static const struct sysfs_ops veth_port_sysfs_ops = {
- 	.show = veth_port_attribute_show
- };
+ /* Don't touch the hdr after it's prepared */
+ static void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
+-				bool embedded, u8 sge_cnt)
++				bool embedded, u8 sge_cnt, u32 opcode)
+ {
+ 	if (embedded)
+ 		wrb->embedded |= MCC_WRB_EMBEDDED_MASK;
+@@ -285,7 +457,8 @@ static void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
+ 		wrb->embedded |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) <<
+ 				MCC_WRB_SGE_CNT_SHIFT;
+ 	wrb->payload_length = payload_len;
+-	be_dws_cpu_to_le(wrb, 20);
++	wrb->tag0 = opcode;
++	be_dws_cpu_to_le(wrb, 8);
+ }
  
-diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
-index 8aa44dc..fa1e797 100644
---- a/drivers/net/ixgb/ixgb_main.c
-+++ b/drivers/net/ixgb/ixgb_main.c
-@@ -1052,6 +1052,8 @@ ixgb_set_multi(struct net_device *netdev)
- 	u32 rctl;
- 	int i;
+ /* Don't touch the hdr after it's prepared */
+@@ -295,6 +468,7 @@ static void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
+ 	req_hdr->opcode = opcode;
+ 	req_hdr->subsystem = subsystem;
+ 	req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
++	req_hdr->version = 0;
+ }
  
-+	pax_track_stack();
+ static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
+@@ -349,7 +523,11 @@ static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter)
+ 	struct be_queue_info *mccq = &adapter->mcc_obj.q;
+ 	struct be_mcc_wrb *wrb;
+ 
+-	BUG_ON(atomic_read(&mccq->used) >= mccq->len);
++	if (atomic_read(&mccq->used) >= mccq->len) {
++		dev_err(&adapter->pdev->dev, "Out of MCCQ wrbs\n");
++		return NULL;
++	}
 +
- 	/* Check for Promiscuous and All Multicast modes */
+ 	wrb = queue_head_node(mccq);
+ 	queue_head_inc(mccq);
+ 	atomic_inc(&mccq->used);
+@@ -357,6 +535,59 @@ static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter)
+ 	return wrb;
+ }
  
- 	rctl = IXGB_READ_REG(hw, RCTL);
-diff --git a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
-index af35e1d..8781785 100644
---- a/drivers/net/ixgb/ixgb_param.c
-+++ b/drivers/net/ixgb/ixgb_param.c
-@@ -260,6 +260,9 @@ void __devinit
- ixgb_check_options(struct ixgb_adapter *adapter)
- {
- 	int bd = adapter->bd_number;
++/* Tell fw we're about to start firing cmds by writing a
++ * special pattern across the wrb hdr; uses mbox
++ */
++int be_cmd_fw_init(struct be_adapter *adapter)
++{
++	u8 *wrb;
++	int status;
 +
-+	pax_track_stack();
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
 +
- 	if (bd >= IXGB_MAX_NIC) {
- 		printk(KERN_NOTICE
- 			   "Warning: no configuration for board #%i\n", bd);
-diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
-index b17aa73..ed74540 100644
---- a/drivers/net/ixgbe/ixgbe_type.h
-+++ b/drivers/net/ixgbe/ixgbe_type.h
-@@ -2327,6 +2327,7 @@ struct ixgbe_eeprom_operations {
- 	s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
- 	s32 (*update_checksum)(struct ixgbe_hw *);
- };
-+typedef struct ixgbe_eeprom_operations __no_const ixgbe_eeprom_operations_no_const;
++	wrb = (u8 *)wrb_from_mbox(adapter);
++	*wrb++ = 0xFF;
++	*wrb++ = 0x12;
++	*wrb++ = 0x34;
++	*wrb++ = 0xFF;
++	*wrb++ = 0xFF;
++	*wrb++ = 0x56;
++	*wrb++ = 0x78;
++	*wrb = 0xFF;
++
++	status = be_mbox_notify_wait(adapter);
++
++	mutex_unlock(&adapter->mbox_lock);
++	return status;
++}
++
++/* Tell fw we're done with firing cmds by writing a
++ * special pattern across the wrb hdr; uses mbox
++ */
++int be_cmd_fw_clean(struct be_adapter *adapter)
++{
++	u8 *wrb;
++	int status;
++
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
++
++	wrb = (u8 *)wrb_from_mbox(adapter);
++	*wrb++ = 0xFF;
++	*wrb++ = 0xAA;
++	*wrb++ = 0xBB;
++	*wrb++ = 0xFF;
++	*wrb++ = 0xFF;
++	*wrb++ = 0xCC;
++	*wrb++ = 0xDD;
++	*wrb = 0xFF;
++
++	status = be_mbox_notify_wait(adapter);
++
++	mutex_unlock(&adapter->mbox_lock);
++	return status;
++}
+ int be_cmd_eq_create(struct be_adapter *adapter,
+ 		struct be_queue_info *eq, int eq_delay)
+ {
+@@ -365,20 +596,19 @@ int be_cmd_eq_create(struct be_adapter *adapter,
+ 	struct be_dma_mem *q_mem = &eq->dma_mem;
+ 	int status;
  
- struct ixgbe_mac_operations {
- 	s32 (*init_hw)(struct ixgbe_hw *);
-@@ -2376,6 +2377,7 @@ struct ixgbe_mac_operations {
- 	/* Flow Control */
- 	s32 (*fc_enable)(struct ixgbe_hw *, s32);
- };
-+typedef struct ixgbe_mac_operations __no_const ixgbe_mac_operations_no_const;
+-	spin_lock(&adapter->mbox_lock);
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
  
- struct ixgbe_phy_operations {
- 	s32 (*identify)(struct ixgbe_hw *);
-@@ -2394,9 +2396,10 @@ struct ixgbe_phy_operations {
- 	s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
- 	s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
- };
-+typedef struct ixgbe_phy_operations __no_const ixgbe_phy_operations_no_const;
+ 	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
  
- struct ixgbe_eeprom_info {
--	struct ixgbe_eeprom_operations  ops;
-+	ixgbe_eeprom_operations_no_const ops;
- 	enum ixgbe_eeprom_type          type;
- 	u32                             semaphore_delay;
- 	u16                             word_size;
-@@ -2404,7 +2407,7 @@ struct ixgbe_eeprom_info {
- };
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, OPCODE_COMMON_EQ_CREATE);
  
- struct ixgbe_mac_info {
--	struct ixgbe_mac_operations     ops;
-+	ixgbe_mac_operations_no_const   ops;
- 	enum ixgbe_mac_type             type;
- 	u8                              addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
- 	u8                              perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
-@@ -2423,7 +2426,7 @@ struct ixgbe_mac_info {
- };
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_EQ_CREATE, sizeof(*req));
  
- struct ixgbe_phy_info {
--	struct ixgbe_phy_operations     ops;
-+	ixgbe_phy_operations_no_const   ops;
- 	struct mdio_if_info		mdio;
- 	enum ixgbe_phy_type             type;
- 	u32                             id;
-diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
-index 291a505..2543756 100644
---- a/drivers/net/mlx4/main.c
-+++ b/drivers/net/mlx4/main.c
-@@ -38,6 +38,7 @@
- #include <linux/errno.h>
- #include <linux/pci.h>
- #include <linux/dma-mapping.h>
-+#include <linux/sched.h>
+ 	req->num_pages =  cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
  
- #include <linux/mlx4/device.h>
- #include <linux/mlx4/doorbell.h>
-@@ -730,6 +731,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
- 	u64 icm_size;
- 	int err;
+-	AMAP_SET_BITS(struct amap_eq_context, func, req->context,
+-			be_pci_func(adapter));
+ 	AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
+ 	/* 4byte eqe*/
+ 	AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
+@@ -397,7 +627,7 @@ int be_cmd_eq_create(struct be_adapter *adapter,
+ 		eq->created = true;
+ 	}
  
-+	pax_track_stack();
-+
- 	err = mlx4_QUERY_FW(dev);
- 	if (err) {
- 		if (err == -EACCES)
-diff --git a/drivers/net/niu.c b/drivers/net/niu.c
-index 2dce134..fa5ce75 100644
---- a/drivers/net/niu.c
-+++ b/drivers/net/niu.c
-@@ -9128,6 +9128,8 @@ static void __devinit niu_try_msix(struct niu *np, u8 *ldg_num_map)
- 	int i, num_irqs, err;
- 	u8 first_ldg;
+-	spin_unlock(&adapter->mbox_lock);
++	mutex_unlock(&adapter->mbox_lock);
+ 	return status;
+ }
  
-+	pax_track_stack();
-+
- 	first_ldg = (NIU_NUM_LDG / parent->num_ports) * np->port;
- 	for (i = 0; i < (NIU_NUM_LDG / parent->num_ports); i++)
- 		ldg_num_map[i] = first_ldg + i;
-diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
-index c1b3f09..97cd8c4 100644
---- a/drivers/net/pcnet32.c
-+++ b/drivers/net/pcnet32.c
-@@ -79,7 +79,7 @@ static int cards_found;
- /*
-  * VLB I/O addresses
-  */
--static unsigned int pcnet32_portlist[] __initdata =
-+static unsigned int pcnet32_portlist[] __devinitdata =
-     { 0x300, 0x320, 0x340, 0x360, 0 };
+@@ -409,12 +639,14 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
+ 	struct be_cmd_req_mac_query *req;
+ 	int status;
  
- static int pcnet32_debug = 0;
-@@ -267,7 +267,7 @@ struct pcnet32_private {
- 	struct sk_buff		**rx_skbuff;
- 	dma_addr_t		*tx_dma_addr;
- 	dma_addr_t		*rx_dma_addr;
--	struct pcnet32_access	a;
-+	struct pcnet32_access	*a;
- 	spinlock_t		lock;		/* Guard lock */
- 	unsigned int		cur_rx, cur_tx;	/* The next free ring entry */
- 	unsigned int		rx_ring_size;	/* current rx ring size */
-@@ -457,9 +457,9 @@ static void pcnet32_netif_start(struct net_device *dev)
- 	u16 val;
+-	spin_lock(&adapter->mbox_lock);
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
  
- 	netif_wake_queue(dev);
--	val = lp->a.read_csr(ioaddr, CSR3);
-+	val = lp->a->read_csr(ioaddr, CSR3);
- 	val &= 0x00ff;
--	lp->a.write_csr(ioaddr, CSR3, val);
-+	lp->a->write_csr(ioaddr, CSR3, val);
- 	napi_enable(&lp->napi);
- }
+ 	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
  
-@@ -744,7 +744,7 @@ static u32 pcnet32_get_link(struct net_device *dev)
- 		r = mii_link_ok(&lp->mii_if);
- 	} else if (lp->chip_version >= PCNET32_79C970A) {
- 		ulong ioaddr = dev->base_addr;	/* card base I/O address */
--		r = (lp->a.read_bcr(ioaddr, 4) != 0xc0);
-+		r = (lp->a->read_bcr(ioaddr, 4) != 0xc0);
- 	} else {	/* can not detect link on really old chips */
- 		r = 1;
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_NTWK_MAC_QUERY);
+ 
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_NTWK_MAC_QUERY, sizeof(*req));
+@@ -433,13 +665,13 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
+ 		memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
  	}
-@@ -806,7 +806,7 @@ static int pcnet32_set_ringparam(struct net_device *dev,
- 		pcnet32_netif_stop(dev);
  
- 	spin_lock_irqsave(&lp->lock, flags);
--	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* stop the chip */
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);	/* stop the chip */
+-	spin_unlock(&adapter->mbox_lock);
++	mutex_unlock(&adapter->mbox_lock);
+ 	return status;
+ }
  
- 	size = min(ering->tx_pending, (unsigned int)TX_MAX_RING_SIZE);
+ /* Uses synchronous MCCQ */
+ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
+-		u32 if_id, u32 *pmac_id)
++		u32 if_id, u32 *pmac_id, u32 domain)
+ {
+ 	struct be_mcc_wrb *wrb;
+ 	struct be_cmd_req_pmac_add *req;
+@@ -448,13 +680,19 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
+ 	spin_lock_bh(&adapter->mcc_lock);
  
-@@ -886,7 +886,7 @@ static void pcnet32_ethtool_test(struct net_device *dev,
- static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
+ 	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
+ 	req = embedded_payload(wrb);
+ 
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_NTWK_PMAC_ADD);
+ 
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req));
+ 
++	req->hdr.domain = domain;
+ 	req->if_id = cpu_to_le32(if_id);
+ 	memcpy(req->mac_address, mac_addr, ETH_ALEN);
+ 
+@@ -464,12 +702,13 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
+ 		*pmac_id = le32_to_cpu(resp->pmac_id);
+ 	}
+ 
++err:
+ 	spin_unlock_bh(&adapter->mcc_lock);
+ 	return status;
+ }
+ 
+ /* Uses synchronous MCCQ */
+-int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id)
++int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id, u32 dom)
  {
- 	struct pcnet32_private *lp = netdev_priv(dev);
--	struct pcnet32_access *a = &lp->a;	/* access to registers */
-+	struct pcnet32_access *a = lp->a;	/* access to registers */
- 	ulong ioaddr = dev->base_addr;	/* card base I/O address */
- 	struct sk_buff *skb;	/* sk buff */
- 	int x, i;		/* counters */
-@@ -906,21 +906,21 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
- 		pcnet32_netif_stop(dev);
+ 	struct be_mcc_wrb *wrb;
+ 	struct be_cmd_req_pmac_del *req;
+@@ -478,20 +717,26 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id)
+ 	spin_lock_bh(&adapter->mcc_lock);
  
- 	spin_lock_irqsave(&lp->lock, flags);
--	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* stop the chip */
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);	/* stop the chip */
+ 	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
+ 	req = embedded_payload(wrb);
  
- 	numbuffs = min(numbuffs, (int)min(lp->rx_ring_size, lp->tx_ring_size));
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_NTWK_PMAC_DEL);
  
- 	/* Reset the PCNET32 */
--	lp->a.reset(ioaddr);
--	lp->a.write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
-+	lp->a->reset(ioaddr);
-+	lp->a->write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req));
  
- 	/* switch pcnet32 to 32bit mode */
--	lp->a.write_bcr(ioaddr, 20, 2);
-+	lp->a->write_bcr(ioaddr, 20, 2);
++	req->hdr.domain = dom;
+ 	req->if_id = cpu_to_le32(if_id);
+ 	req->pmac_id = cpu_to_le32(pmac_id);
  
- 	/* purge & init rings but don't actually restart */
- 	pcnet32_restart(dev, 0x0000);
+ 	status = be_mcc_notify_wait(adapter);
  
--	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* Set STOP bit */
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);	/* Set STOP bit */
++err:
+ 	spin_unlock_bh(&adapter->mcc_lock);
+-
+ 	return status;
+ }
  
- 	/* Initialize Transmit buffers. */
- 	size = data_len + 15;
-@@ -966,10 +966,10 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
+@@ -506,29 +751,51 @@ int be_cmd_cq_create(struct be_adapter *adapter,
+ 	void *ctxt;
+ 	int status;
  
- 	/* set int loopback in CSR15 */
- 	x = a->read_csr(ioaddr, CSR15) & 0xfffc;
--	lp->a.write_csr(ioaddr, CSR15, x | 0x0044);
-+	lp->a->write_csr(ioaddr, CSR15, x | 0x0044);
+-	spin_lock(&adapter->mbox_lock);
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
  
- 	teststatus = cpu_to_le16(0x8000);
--	lp->a.write_csr(ioaddr, CSR0, CSR0_START);	/* Set STRT bit */
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_START);	/* Set STRT bit */
+ 	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
+ 	ctxt = &req->context;
+ 
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_CQ_CREATE);
+ 
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_CQ_CREATE, sizeof(*req));
+ 
+ 	req->num_pages =  cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
+ 
+-	AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm);
+-	AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay);
+-	AMAP_SET_BITS(struct amap_cq_context, count, ctxt,
+-			__ilog2_u32(cq->len/256));
+-	AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1);
+-	AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts);
+-	AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
+-	AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
+-	AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
+-	AMAP_SET_BITS(struct amap_cq_context, func, ctxt, be_pci_func(adapter));
++	if (lancer_chip(adapter)) {
++		req->hdr.version = 2;
++		req->page_size = 1; /* 1 for 4K */
++		AMAP_SET_BITS(struct amap_cq_context_lancer, coalescwm, ctxt,
++								coalesce_wm);
++		AMAP_SET_BITS(struct amap_cq_context_lancer, nodelay, ctxt,
++								no_delay);
++		AMAP_SET_BITS(struct amap_cq_context_lancer, count, ctxt,
++						__ilog2_u32(cq->len/256));
++		AMAP_SET_BITS(struct amap_cq_context_lancer, valid, ctxt, 1);
++		AMAP_SET_BITS(struct amap_cq_context_lancer, eventable,
++								ctxt, 1);
++		AMAP_SET_BITS(struct amap_cq_context_lancer, eqid,
++								ctxt, eq->id);
++		AMAP_SET_BITS(struct amap_cq_context_lancer, armed, ctxt, 1);
++	} else {
++		AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt,
++								coalesce_wm);
++		AMAP_SET_BITS(struct amap_cq_context_be, nodelay,
++								ctxt, no_delay);
++		AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt,
++						__ilog2_u32(cq->len/256));
++		AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1);
++		AMAP_SET_BITS(struct amap_cq_context_be, solevent,
++								ctxt, sol_evts);
++		AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1);
++		AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id);
++		AMAP_SET_BITS(struct amap_cq_context_be, armed, ctxt, 1);
++	}
++
+ 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
  
- 	/* Check status of descriptors */
- 	for (x = 0; x < numbuffs; x++) {
-@@ -990,7 +990,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
- 		}
+ 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+@@ -540,8 +807,7 @@ int be_cmd_cq_create(struct be_adapter *adapter,
+ 		cq->created = true;
  	}
  
--	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* Set STOP bit */
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);	/* Set STOP bit */
- 	wmb();
- 	if (netif_msg_hw(lp) && netif_msg_pktdata(lp)) {
- 		printk(KERN_DEBUG "%s: RX loopback packets:\n", dev->name);
-@@ -1039,7 +1039,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
- 		pcnet32_restart(dev, CSR0_NORMAL);
- 	} else {
- 		pcnet32_purge_rx_ring(dev);
--		lp->a.write_bcr(ioaddr, 20, 4);	/* return to 16bit mode */
-+		lp->a->write_bcr(ioaddr, 20, 4);	/* return to 16bit mode */
- 	}
- 	spin_unlock_irqrestore(&lp->lock, flags);
+-	spin_unlock(&adapter->mbox_lock);
+-
++	mutex_unlock(&adapter->mbox_lock);
+ 	return status;
+ }
  
-@@ -1049,7 +1049,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
- static void pcnet32_led_blink_callback(struct net_device *dev)
- {
- 	struct pcnet32_private *lp = netdev_priv(dev);
--	struct pcnet32_access *a = &lp->a;
-+	struct pcnet32_access *a = lp->a;
- 	ulong ioaddr = dev->base_addr;
- 	unsigned long flags;
- 	int i;
-@@ -1066,7 +1066,7 @@ static void pcnet32_led_blink_callback(struct net_device *dev)
- static int pcnet32_phys_id(struct net_device *dev, u32 data)
- {
- 	struct pcnet32_private *lp = netdev_priv(dev);
--	struct pcnet32_access *a = &lp->a;
-+	struct pcnet32_access *a = lp->a;
- 	ulong ioaddr = dev->base_addr;
- 	unsigned long flags;
- 	int i, regs[4];
-@@ -1112,7 +1112,7 @@ static int pcnet32_suspend(struct net_device *dev, unsigned long *flags,
+@@ -553,7 +819,68 @@ static u32 be_encoded_q_len(int q_len)
+ 	return len_encoded;
+ }
+ 
+-int be_cmd_mccq_create(struct be_adapter *adapter,
++int be_cmd_mccq_ext_create(struct be_adapter *adapter,
++			struct be_queue_info *mccq,
++			struct be_queue_info *cq)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_mcc_ext_create *req;
++	struct be_dma_mem *q_mem = &mccq->dma_mem;
++	void *ctxt;
++	int status;
++
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
++
++	wrb = wrb_from_mbox(adapter);
++	req = embedded_payload(wrb);
++	ctxt = &req->context;
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_MCC_CREATE_EXT);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req));
++
++	req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
++	if (lancer_chip(adapter)) {
++		req->hdr.version = 1;
++		req->cq_id = cpu_to_le16(cq->id);
++
++		AMAP_SET_BITS(struct amap_mcc_context_lancer, ring_size, ctxt,
++						be_encoded_q_len(mccq->len));
++		AMAP_SET_BITS(struct amap_mcc_context_lancer, valid, ctxt, 1);
++		AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_id,
++								ctxt, cq->id);
++		AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_valid,
++								 ctxt, 1);
++
++	} else {
++		AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
++		AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
++						be_encoded_q_len(mccq->len));
++		AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
++	}
++
++	/* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
++	req->async_event_bitmap[0] |= cpu_to_le32(0x00000022);
++
++	be_dws_cpu_to_le(ctxt, sizeof(req->context));
++
++	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
++
++	status = be_mbox_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
++		mccq->id = le16_to_cpu(resp->id);
++		mccq->created = true;
++	}
++
++	mutex_unlock(&adapter->mbox_lock);
++	return status;
++}
++
++int be_cmd_mccq_org_create(struct be_adapter *adapter,
+ 			struct be_queue_info *mccq,
+ 			struct be_queue_info *cq)
  {
- 	int csr5;
- 	struct pcnet32_private *lp = netdev_priv(dev);
--	struct pcnet32_access *a = &lp->a;
-+	struct pcnet32_access *a = lp->a;
- 	ulong ioaddr = dev->base_addr;
- 	int ticks;
+@@ -563,24 +890,25 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
+ 	void *ctxt;
+ 	int status;
  
-@@ -1388,8 +1388,8 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
- 	spin_lock_irqsave(&lp->lock, flags);
- 	if (pcnet32_tx(dev)) {
- 		/* reset the chip to clear the error condition, then restart */
--		lp->a.reset(ioaddr);
--		lp->a.write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
-+		lp->a->reset(ioaddr);
-+		lp->a->write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
- 		pcnet32_restart(dev, CSR0_START);
- 		netif_wake_queue(dev);
- 	}
-@@ -1401,12 +1401,12 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
- 		__napi_complete(napi);
+-	spin_lock(&adapter->mbox_lock);
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
  
- 		/* clear interrupt masks */
--		val = lp->a.read_csr(ioaddr, CSR3);
-+		val = lp->a->read_csr(ioaddr, CSR3);
- 		val &= 0x00ff;
--		lp->a.write_csr(ioaddr, CSR3, val);
-+		lp->a->write_csr(ioaddr, CSR3, val);
+ 	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
+ 	ctxt = &req->context;
  
- 		/* Set interrupt enable. */
--		lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN);
-+		lp->a->write_csr(ioaddr, CSR0, CSR0_INTEN);
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_MCC_CREATE);
  
- 		spin_unlock_irqrestore(&lp->lock, flags);
- 	}
-@@ -1429,7 +1429,7 @@ static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
- 	int i, csr0;
- 	u16 *buff = ptr;
- 	struct pcnet32_private *lp = netdev_priv(dev);
--	struct pcnet32_access *a = &lp->a;
-+	struct pcnet32_access *a = lp->a;
- 	ulong ioaddr = dev->base_addr;
- 	unsigned long flags;
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 			OPCODE_COMMON_MCC_CREATE, sizeof(*req));
  
-@@ -1466,9 +1466,9 @@ static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
- 		for (j = 0; j < PCNET32_MAX_PHYS; j++) {
- 			if (lp->phymask & (1 << j)) {
- 				for (i = 0; i < PCNET32_REGS_PER_PHY; i++) {
--					lp->a.write_bcr(ioaddr, 33,
-+					lp->a->write_bcr(ioaddr, 33,
- 							(j << 5) | i);
--					*buff++ = lp->a.read_bcr(ioaddr, 34);
-+					*buff++ = lp->a->read_bcr(ioaddr, 34);
- 				}
- 			}
- 		}
-@@ -1858,7 +1858,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
- 	    ((cards_found >= MAX_UNITS) || full_duplex[cards_found]))
- 		lp->options |= PCNET32_PORT_FD;
+-	req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
++	req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
  
--	lp->a = *a;
-+	lp->a = a;
+-	AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, be_pci_func(adapter));
+-	AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
+-	AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
+-		be_encoded_q_len(mccq->len));
+-	AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id);
++	AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
++	AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
++			be_encoded_q_len(mccq->len));
++	AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
  
- 	/* prior to register_netdev, dev->name is not yet correct */
- 	if (pcnet32_alloc_ring(dev, pci_name(lp->pci_dev))) {
-@@ -1917,7 +1917,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
- 	if (lp->mii) {
- 		/* lp->phycount and lp->phymask are set to 0 by memset above */
+ 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
  
--		lp->mii_if.phy_id = ((lp->a.read_bcr(ioaddr, 33)) >> 5) & 0x1f;
-+		lp->mii_if.phy_id = ((lp->a->read_bcr(ioaddr, 33)) >> 5) & 0x1f;
- 		/* scan for PHYs */
- 		for (i = 0; i < PCNET32_MAX_PHYS; i++) {
- 			unsigned short id1, id2;
-@@ -1938,7 +1938,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
- 				       "Found PHY %04x:%04x at address %d.\n",
- 				       id1, id2, i);
- 		}
--		lp->a.write_bcr(ioaddr, 33, (lp->mii_if.phy_id) << 5);
-+		lp->a->write_bcr(ioaddr, 33, (lp->mii_if.phy_id) << 5);
- 		if (lp->phycount > 1) {
- 			lp->options |= PCNET32_PORT_MII;
- 		}
-@@ -2109,10 +2109,10 @@ static int pcnet32_open(struct net_device *dev)
+@@ -592,75 +920,93 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
+ 		mccq->id = le16_to_cpu(resp->id);
+ 		mccq->created = true;
  	}
+-	spin_unlock(&adapter->mbox_lock);
  
- 	/* Reset the PCNET32 */
--	lp->a.reset(ioaddr);
-+	lp->a->reset(ioaddr);
++	mutex_unlock(&adapter->mbox_lock);
+ 	return status;
+ }
  
- 	/* switch pcnet32 to 32bit mode */
--	lp->a.write_bcr(ioaddr, 20, 2);
-+	lp->a->write_bcr(ioaddr, 20, 2);
+-int be_cmd_txq_create(struct be_adapter *adapter,
+-			struct be_queue_info *txq,
++int be_cmd_mccq_create(struct be_adapter *adapter,
++			struct be_queue_info *mccq,
+ 			struct be_queue_info *cq)
+ {
++	int status;
++
++	status = be_cmd_mccq_ext_create(adapter, mccq, cq);
++	if (status && !lancer_chip(adapter)) {
++		dev_warn(&adapter->pdev->dev, "Upgrade to F/W ver 2.102.235.0 "
++			"or newer to avoid conflicting priorities between NIC "
++			"and FCoE traffic");
++		status = be_cmd_mccq_org_create(adapter, mccq, cq);
++	}
++	return status;
++}
++
++int be_cmd_txq_create(struct be_adapter *adapter, struct be_queue_info *txq,
++			struct be_queue_info *cq, u8 *tc_id)
++{
+ 	struct be_mcc_wrb *wrb;
+ 	struct be_cmd_req_eth_tx_create *req;
+ 	struct be_dma_mem *q_mem = &txq->dma_mem;
+-	void *ctxt;
+ 	int status;
  
- 	if (netif_msg_ifup(lp))
- 		printk(KERN_DEBUG
-@@ -2122,14 +2122,14 @@ static int pcnet32_open(struct net_device *dev)
- 		       (u32) (lp->init_dma_addr));
+-	spin_lock(&adapter->mbox_lock);
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
  
- 	/* set/reset autoselect bit */
--	val = lp->a.read_bcr(ioaddr, 2) & ~2;
-+	val = lp->a->read_bcr(ioaddr, 2) & ~2;
- 	if (lp->options & PCNET32_PORT_ASEL)
- 		val |= 2;
--	lp->a.write_bcr(ioaddr, 2, val);
-+	lp->a->write_bcr(ioaddr, 2, val);
+ 	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
+-	ctxt = &req->context;
+-
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  
- 	/* handle full duplex setting */
- 	if (lp->mii_if.full_duplex) {
--		val = lp->a.read_bcr(ioaddr, 9) & ~3;
-+		val = lp->a->read_bcr(ioaddr, 9) & ~3;
- 		if (lp->options & PCNET32_PORT_FD) {
- 			val |= 1;
- 			if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI))
-@@ -2139,14 +2139,14 @@ static int pcnet32_open(struct net_device *dev)
- 			if (lp->chip_version == 0x2627)
- 				val |= 3;
- 		}
--		lp->a.write_bcr(ioaddr, 9, val);
-+		lp->a->write_bcr(ioaddr, 9, val);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, OPCODE_ETH_TX_CREATE);
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_TX_CREATE,
+ 		sizeof(*req));
+ 
+-	req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
++	if (adapter->flags & BE_FLAGS_DCBX || lancer_chip(adapter)) {
++		req->hdr.version = 1;
++		req->if_id = cpu_to_le16(adapter->if_handle);
++	}
++	if (adapter->flags & BE_FLAGS_DCBX)
++		req->type = cpu_to_le16(ETX_QUEUE_TYPE_PRIORITY);
++	else
++		req->type = cpu_to_le16(ETX_QUEUE_TYPE_STANDARD);
+ 	req->ulp_num = BE_ULP1_NUM;
+-	req->type = BE_ETH_TX_RING_TYPE_STANDARD;
+-
+-	AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt,
+-		be_encoded_q_len(txq->len));
+-	AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt,
+-			be_pci_func(adapter));
+-	AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
+-	AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id);
+-
+-	be_dws_cpu_to_le(ctxt, sizeof(req->context));
+-
++	req->cq_id = cpu_to_le16(cq->id);
++	req->queue_size = be_encoded_q_len(txq->len);
++	req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
+ 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
+ 
+ 	status = be_mbox_notify_wait(adapter);
+ 	if (!status) {
+ 		struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb);
+ 		txq->id = le16_to_cpu(resp->cid);
++		if (adapter->flags & BE_FLAGS_DCBX)
++			*tc_id = resp->tc_id;
+ 		txq->created = true;
  	}
  
- 	/* set/reset GPSI bit in test register */
--	val = lp->a.read_csr(ioaddr, 124) & ~0x10;
-+	val = lp->a->read_csr(ioaddr, 124) & ~0x10;
- 	if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI)
- 		val |= 0x10;
--	lp->a.write_csr(ioaddr, 124, val);
-+	lp->a->write_csr(ioaddr, 124, val);
+-	spin_unlock(&adapter->mbox_lock);
+-
++	mutex_unlock(&adapter->mbox_lock);
+ 	return status;
+ }
  
- 	/* Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not negotiate */
- 	if (pdev && pdev->subsystem_vendor == PCI_VENDOR_ID_AT &&
-@@ -2167,24 +2167,24 @@ static int pcnet32_open(struct net_device *dev)
- 		 * duplex, and/or enable auto negotiation, and clear DANAS
- 		 */
- 		if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) {
--			lp->a.write_bcr(ioaddr, 32,
--					lp->a.read_bcr(ioaddr, 32) | 0x0080);
-+			lp->a->write_bcr(ioaddr, 32,
-+					lp->a->read_bcr(ioaddr, 32) | 0x0080);
- 			/* disable Auto Negotiation, set 10Mpbs, HD */
--			val = lp->a.read_bcr(ioaddr, 32) & ~0xb8;
-+			val = lp->a->read_bcr(ioaddr, 32) & ~0xb8;
- 			if (lp->options & PCNET32_PORT_FD)
- 				val |= 0x10;
- 			if (lp->options & PCNET32_PORT_100)
- 				val |= 0x08;
--			lp->a.write_bcr(ioaddr, 32, val);
-+			lp->a->write_bcr(ioaddr, 32, val);
- 		} else {
- 			if (lp->options & PCNET32_PORT_ASEL) {
--				lp->a.write_bcr(ioaddr, 32,
--						lp->a.read_bcr(ioaddr,
-+				lp->a->write_bcr(ioaddr, 32,
-+						lp->a->read_bcr(ioaddr,
- 							       32) | 0x0080);
- 				/* enable auto negotiate, setup, disable fd */
--				val = lp->a.read_bcr(ioaddr, 32) & ~0x98;
-+				val = lp->a->read_bcr(ioaddr, 32) & ~0x98;
- 				val |= 0x20;
--				lp->a.write_bcr(ioaddr, 32, val);
-+				lp->a->write_bcr(ioaddr, 32, val);
- 			}
- 		}
- 	} else {
-@@ -2197,10 +2197,10 @@ static int pcnet32_open(struct net_device *dev)
- 		 * There is really no good other way to handle multiple PHYs
- 		 * other than turning off all automatics
- 		 */
--		val = lp->a.read_bcr(ioaddr, 2);
--		lp->a.write_bcr(ioaddr, 2, val & ~2);
--		val = lp->a.read_bcr(ioaddr, 32);
--		lp->a.write_bcr(ioaddr, 32, val & ~(1 << 7));	/* stop MII manager */
-+		val = lp->a->read_bcr(ioaddr, 2);
-+		lp->a->write_bcr(ioaddr, 2, val & ~2);
-+		val = lp->a->read_bcr(ioaddr, 32);
-+		lp->a->write_bcr(ioaddr, 32, val & ~(1 << 7));	/* stop MII manager */
+-/* Uses mbox */
++/* Uses MCC */
+ int be_cmd_rxq_create(struct be_adapter *adapter,
+ 		struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
+-		u16 max_frame_size, u32 if_id, u32 rss)
++		u16 max_frame_size, u32 if_id, u32 rss, u8 *rss_id)
+ {
+ 	struct be_mcc_wrb *wrb;
+ 	struct be_cmd_req_eth_rx_create *req;
+ 	struct be_dma_mem *q_mem = &rxq->dma_mem;
+ 	int status;
  
- 		if (!(lp->options & PCNET32_PORT_ASEL)) {
- 			/* setup ecmd */
-@@ -2210,7 +2210,7 @@ static int pcnet32_open(struct net_device *dev)
- 			ecmd.speed =
- 			    lp->
- 			    options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10;
--			bcr9 = lp->a.read_bcr(ioaddr, 9);
-+			bcr9 = lp->a->read_bcr(ioaddr, 9);
+-	spin_lock(&adapter->mbox_lock);
++	spin_lock_bh(&adapter->mcc_lock);
  
- 			if (lp->options & PCNET32_PORT_FD) {
- 				ecmd.duplex = DUPLEX_FULL;
-@@ -2219,7 +2219,7 @@ static int pcnet32_open(struct net_device *dev)
- 				ecmd.duplex = DUPLEX_HALF;
- 				bcr9 |= ~(1 << 0);
- 			}
--			lp->a.write_bcr(ioaddr, 9, bcr9);
-+			lp->a->write_bcr(ioaddr, 9, bcr9);
- 		}
+-	wrb = wrb_from_mbox(adapter);
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
+ 	req = embedded_payload(wrb);
  
- 		for (i = 0; i < PCNET32_MAX_PHYS; i++) {
-@@ -2252,9 +2252,9 @@ static int pcnet32_open(struct net_device *dev)
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_ETH_RX_CREATE);
  
- #ifdef DO_DXSUFLO
- 	if (lp->dxsuflo) {	/* Disable transmit stop on underflow */
--		val = lp->a.read_csr(ioaddr, CSR3);
-+		val = lp->a->read_csr(ioaddr, CSR3);
- 		val |= 0x40;
--		lp->a.write_csr(ioaddr, CSR3, val);
-+		lp->a->write_csr(ioaddr, CSR3, val);
- 	}
- #endif
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_RX_CREATE,
+ 		sizeof(*req));
+@@ -673,15 +1019,16 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
+ 	req->max_frame_size = cpu_to_le16(max_frame_size);
+ 	req->rss_queue = cpu_to_le32(rss);
  
-@@ -2270,11 +2270,11 @@ static int pcnet32_open(struct net_device *dev)
- 	napi_enable(&lp->napi);
+-	status = be_mbox_notify_wait(adapter);
++	status = be_mcc_notify_wait(adapter);
+ 	if (!status) {
+ 		struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb);
+ 		rxq->id = le16_to_cpu(resp->id);
+ 		rxq->created = true;
++		*rss_id = resp->rss_id;
+ 	}
  
- 	/* Re-initialize the PCNET32, and start it when done. */
--	lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
--	lp->a.write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
-+	lp->a->write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
-+	lp->a->write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
+-	spin_unlock(&adapter->mbox_lock);
+-
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
+ 	return status;
+ }
  
--	lp->a.write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
--	lp->a.write_csr(ioaddr, CSR0, CSR0_INIT);
-+	lp->a->write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_INIT);
+@@ -696,13 +1043,12 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
+ 	u8 subsys = 0, opcode = 0;
+ 	int status;
  
- 	netif_start_queue(dev);
+-	spin_lock(&adapter->mbox_lock);
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
  
-@@ -2286,20 +2286,20 @@ static int pcnet32_open(struct net_device *dev)
+ 	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
  
- 	i = 0;
- 	while (i++ < 100)
--		if (lp->a.read_csr(ioaddr, CSR0) & CSR0_IDON)
-+		if (lp->a->read_csr(ioaddr, CSR0) & CSR0_IDON)
- 			break;
- 	/*
- 	 * We used to clear the InitDone bit, 0x0100, here but Mark Stockton
- 	 * reports that doing so triggers a bug in the '974.
- 	 */
--	lp->a.write_csr(ioaddr, CSR0, CSR0_NORMAL);
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_NORMAL);
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+-
+ 	switch (queue_type) {
+ 	case QTYPE_EQ:
+ 		subsys = CMD_SUBSYSTEM_COMMON;
+@@ -727,13 +1073,47 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
+ 	default:
+ 		BUG();
+ 	}
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, opcode);
++
+ 	be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
+ 	req->id = cpu_to_le16(q->id);
  
- 	if (netif_msg_ifup(lp))
- 		printk(KERN_DEBUG
- 		       "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n",
- 		       dev->name, i,
- 		       (u32) (lp->init_dma_addr),
--		       lp->a.read_csr(ioaddr, CSR0));
-+		       lp->a->read_csr(ioaddr, CSR0));
+ 	status = be_mbox_notify_wait(adapter);
++	if (!status)
++		q->created = false;
  
- 	spin_unlock_irqrestore(&lp->lock, flags);
+-	spin_unlock(&adapter->mbox_lock);
++	mutex_unlock(&adapter->mbox_lock);
++	return status;
++}
  
-@@ -2313,7 +2313,7 @@ static int pcnet32_open(struct net_device *dev)
- 	 * Switch back to 16bit mode to avoid problems with dumb
- 	 * DOS packet driver after a warm reboot
- 	 */
--	lp->a.write_bcr(ioaddr, 20, 4);
-+	lp->a->write_bcr(ioaddr, 20, 4);
++/* Uses MCC */
++int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_q_destroy *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, OPCODE_ETH_RX_DESTROY);
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_RX_DESTROY,
++		sizeof(*req));
++	req->id = cpu_to_le16(q->id);
++
++	status = be_mcc_notify_wait(adapter);
++	if (!status)
++		q->created = false;
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
+ 	return status;
+ }
  
-       err_free_irq:
- 	spin_unlock_irqrestore(&lp->lock, flags);
-@@ -2420,7 +2420,7 @@ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits)
+@@ -741,22 +1121,26 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
+  * Uses mbox
+  */
+ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
+-		u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
++		u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id,
++		u32 domain)
+ {
+ 	struct be_mcc_wrb *wrb;
+ 	struct be_cmd_req_if_create *req;
+ 	int status;
  
- 	/* wait for stop */
- 	for (i = 0; i < 100; i++)
--		if (lp->a.read_csr(ioaddr, CSR0) & CSR0_STOP)
-+		if (lp->a->read_csr(ioaddr, CSR0) & CSR0_STOP)
- 			break;
+-	spin_lock(&adapter->mbox_lock);
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
  
- 	if (i >= 100 && netif_msg_drv(lp))
-@@ -2433,13 +2433,13 @@ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits)
- 		return;
+ 	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
  
- 	/* ReInit Ring */
--	lp->a.write_csr(ioaddr, CSR0, CSR0_INIT);
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_INIT);
- 	i = 0;
- 	while (i++ < 1000)
--		if (lp->a.read_csr(ioaddr, CSR0) & CSR0_IDON)
-+		if (lp->a->read_csr(ioaddr, CSR0) & CSR0_IDON)
- 			break;
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_NTWK_INTERFACE_CREATE);
  
--	lp->a.write_csr(ioaddr, CSR0, csr0_bits);
-+	lp->a->write_csr(ioaddr, CSR0, csr0_bits);
- }
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_NTWK_INTERFACE_CREATE, sizeof(*req));
  
- static void pcnet32_tx_timeout(struct net_device *dev)
-@@ -2452,8 +2452,8 @@ static void pcnet32_tx_timeout(struct net_device *dev)
- 	if (pcnet32_debug & NETIF_MSG_DRV)
- 		printk(KERN_ERR
- 		       "%s: transmit timed out, status %4.4x, resetting.\n",
--		       dev->name, lp->a.read_csr(ioaddr, CSR0));
--	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
-+		       dev->name, lp->a->read_csr(ioaddr, CSR0));
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
- 	dev->stats.tx_errors++;
- 	if (netif_msg_tx_err(lp)) {
- 		int i;
-@@ -2497,7 +2497,7 @@ static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb,
- 	if (netif_msg_tx_queued(lp)) {
- 		printk(KERN_DEBUG
- 		       "%s: pcnet32_start_xmit() called, csr0 %4.4x.\n",
--		       dev->name, lp->a.read_csr(ioaddr, CSR0));
-+		       dev->name, lp->a->read_csr(ioaddr, CSR0));
++	req->hdr.domain = domain;
+ 	req->capability_flags = cpu_to_le32(cap_flags);
+ 	req->enable_flags = cpu_to_le32(en_flags);
+ 	req->pmac_invalid = pmac_invalid;
+@@ -771,33 +1155,35 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
+ 			*pmac_id = le32_to_cpu(resp->pmac_id);
  	}
  
- 	/* Default status -- will not enable Successful-TxDone
-@@ -2528,7 +2528,7 @@ static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb,
- 	dev->stats.tx_bytes += skb->len;
+-	spin_unlock(&adapter->mbox_lock);
++	mutex_unlock(&adapter->mbox_lock);
+ 	return status;
+ }
  
- 	/* Trigger an immediate send poll. */
--	lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
+ /* Uses mbox */
+-int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
++int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain)
+ {
+ 	struct be_mcc_wrb *wrb;
+ 	struct be_cmd_req_if_destroy *req;
+ 	int status;
  
- 	dev->trans_start = jiffies;
+-	spin_lock(&adapter->mbox_lock);
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
  
-@@ -2555,18 +2555,18 @@ pcnet32_interrupt(int irq, void *dev_id)
+ 	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
  
- 	spin_lock(&lp->lock);
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_NTWK_INTERFACE_DESTROY);
  
--	csr0 = lp->a.read_csr(ioaddr, CSR0);
-+	csr0 = lp->a->read_csr(ioaddr, CSR0);
- 	while ((csr0 & 0x8f00) && --boguscnt >= 0) {
- 		if (csr0 == 0xffff) {
- 			break;	/* PCMCIA remove happened */
- 		}
- 		/* Acknowledge all of the current interrupt sources ASAP. */
--		lp->a.write_csr(ioaddr, CSR0, csr0 & ~0x004f);
-+		lp->a->write_csr(ioaddr, CSR0, csr0 & ~0x004f);
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req));
  
- 		if (netif_msg_intr(lp))
- 			printk(KERN_DEBUG
- 			       "%s: interrupt  csr0=%#2.2x new csr=%#2.2x.\n",
--			       dev->name, csr0, lp->a.read_csr(ioaddr, CSR0));
-+			       dev->name, csr0, lp->a->read_csr(ioaddr, CSR0));
++	req->hdr.domain = domain;
+ 	req->interface_id = cpu_to_le32(interface_id);
  
- 		/* Log misc errors. */
- 		if (csr0 & 0x4000)
-@@ -2595,19 +2595,19 @@ pcnet32_interrupt(int irq, void *dev_id)
- 		if (napi_schedule_prep(&lp->napi)) {
- 			u16 val;
- 			/* set interrupt masks */
--			val = lp->a.read_csr(ioaddr, CSR3);
-+			val = lp->a->read_csr(ioaddr, CSR3);
- 			val |= 0x5f00;
--			lp->a.write_csr(ioaddr, CSR3, val);
-+			lp->a->write_csr(ioaddr, CSR3, val);
+ 	status = be_mbox_notify_wait(adapter);
  
- 			__napi_schedule(&lp->napi);
- 			break;
- 		}
--		csr0 = lp->a.read_csr(ioaddr, CSR0);
-+		csr0 = lp->a->read_csr(ioaddr, CSR0);
- 	}
+-	spin_unlock(&adapter->mbox_lock);
+-
++	mutex_unlock(&adapter->mbox_lock);
+ 	return status;
+ }
  
- 	if (netif_msg_intr(lp))
- 		printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n",
--		       dev->name, lp->a.read_csr(ioaddr, CSR0));
-+		       dev->name, lp->a->read_csr(ioaddr, CSR0));
+@@ -808,33 +1194,48 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
+ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
+ {
+ 	struct be_mcc_wrb *wrb;
+-	struct be_cmd_req_get_stats *req;
++	struct be_cmd_req_hdr *hdr;
+ 	struct be_sge *sge;
++	int status = 0;
++
++	if (MODULO(adapter->work_counter, be_get_temp_freq) == 0)
++		be_cmd_get_die_temperature(adapter);
  
- 	spin_unlock(&lp->lock);
+ 	spin_lock_bh(&adapter->mcc_lock);
  
-@@ -2627,21 +2627,21 @@ static int pcnet32_close(struct net_device *dev)
+ 	wrb = wrb_from_mccq(adapter);
+-	req = nonemb_cmd->va;
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	hdr = nonemb_cmd->va;
+ 	sge = nonembedded_sgl(wrb);
  
- 	spin_lock_irqsave(&lp->lock, flags);
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
+-	wrb->tag0 = OPCODE_ETH_GET_STATISTICS;
++	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1,
++			OPCODE_ETH_GET_STATISTICS);
  
--	dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
-+	dev->stats.rx_missed_errors = lp->a->read_csr(ioaddr, 112);
+-	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
+-		OPCODE_ETH_GET_STATISTICS, sizeof(*req));
++	be_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH,
++		OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size);
++
++	if (adapter->generation == BE_GEN3)
++		hdr->version = 1;
++
++	wrb->tag1 = CMD_SUBSYSTEM_ETH;
+ 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
+ 	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
+ 	sge->len = cpu_to_le32(nonemb_cmd->size);
  
- 	if (netif_msg_ifdown(lp))
- 		printk(KERN_DEBUG
- 		       "%s: Shutting down ethercard, status was %2.2x.\n",
--		       dev->name, lp->a.read_csr(ioaddr, CSR0));
-+		       dev->name, lp->a->read_csr(ioaddr, CSR0));
+ 	be_mcc_notify(adapter);
++	adapter->stats_cmd_sent = true;
  
- 	/* We stop the PCNET32 here -- it occasionally polls memory if we don't. */
--	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
-+	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
++err:
+ 	spin_unlock_bh(&adapter->mcc_lock);
+-	return 0;
++	return status;
+ }
  
- 	/*
- 	 * Switch back to 16bit mode to avoid problems with dumb
- 	 * DOS packet driver after a warm reboot
- 	 */
--	lp->a.write_bcr(ioaddr, 20, 4);
-+	lp->a->write_bcr(ioaddr, 20, 4);
+ /* Uses synchronous mcc */
+ int be_cmd_link_status_query(struct be_adapter *adapter,
+-			bool *link_up)
++			int *link_status, u8 *mac_speed, u16 *link_speed, u32 dom)
+ {
+ 	struct be_mcc_wrb *wrb;
+ 	struct be_cmd_req_link_status *req;
+@@ -843,50 +1244,216 @@ int be_cmd_link_status_query(struct be_adapter *adapter,
+ 	spin_lock_bh(&adapter->mcc_lock);
  
- 	spin_unlock_irqrestore(&lp->lock, flags);
+ 	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
+ 	req = embedded_payload(wrb);
  
-@@ -2664,7 +2664,7 @@ static struct net_device_stats *pcnet32_get_stats(struct net_device *dev)
- 	unsigned long flags;
+-	*link_up = false;
++	*link_status = LINK_DOWN;
  
- 	spin_lock_irqsave(&lp->lock, flags);
--	dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
-+	dev->stats.rx_missed_errors = lp->a->read_csr(ioaddr, 112);
- 	spin_unlock_irqrestore(&lp->lock, flags);
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_NTWK_LINK_STATUS_QUERY);
  
- 	return &dev->stats;
-@@ -2686,10 +2686,10 @@ static void pcnet32_load_multicast(struct net_device *dev)
- 	if (dev->flags & IFF_ALLMULTI) {
- 		ib->filter[0] = cpu_to_le32(~0U);
- 		ib->filter[1] = cpu_to_le32(~0U);
--		lp->a.write_csr(ioaddr, PCNET32_MC_FILTER, 0xffff);
--		lp->a.write_csr(ioaddr, PCNET32_MC_FILTER+1, 0xffff);
--		lp->a.write_csr(ioaddr, PCNET32_MC_FILTER+2, 0xffff);
--		lp->a.write_csr(ioaddr, PCNET32_MC_FILTER+3, 0xffff);
-+		lp->a->write_csr(ioaddr, PCNET32_MC_FILTER, 0xffff);
-+		lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+1, 0xffff);
-+		lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+2, 0xffff);
-+		lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+3, 0xffff);
- 		return;
- 	}
- 	/* clear the multicast filter */
-@@ -2710,7 +2710,7 @@ static void pcnet32_load_multicast(struct net_device *dev)
- 		mcast_table[crc >> 4] |= cpu_to_le16(1 << (crc & 0xf));
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req));
+ 
++	req->hdr.domain = dom;
++
+ 	status = be_mcc_notify_wait(adapter);
+ 	if (!status) {
+ 		struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
+-		if (resp->mac_speed != PHY_LINK_SPEED_ZERO)
+-			*link_up = true;
++		if (resp->mac_speed != PHY_LINK_SPEED_ZERO) {
++			*link_status = LINK_UP;
++			*link_speed = le16_to_cpu(resp->link_speed);
++			*mac_speed = resp->mac_speed;
++		}
  	}
- 	for (i = 0; i < 4; i++)
--		lp->a.write_csr(ioaddr, PCNET32_MC_FILTER + i,
-+		lp->a->write_csr(ioaddr, PCNET32_MC_FILTER + i,
- 				le16_to_cpu(mcast_table[i]));
- 	return;
+ 
++err:
+ 	spin_unlock_bh(&adapter->mcc_lock);
+ 	return status;
  }
-@@ -2726,7 +2726,7 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
  
- 	spin_lock_irqsave(&lp->lock, flags);
- 	suspended = pcnet32_suspend(dev, &flags, 0);
--	csr15 = lp->a.read_csr(ioaddr, CSR15);
-+	csr15 = lp->a->read_csr(ioaddr, CSR15);
- 	if (dev->flags & IFF_PROMISC) {
- 		/* Log any net taps. */
- 		if (netif_msg_hw(lp))
-@@ -2735,21 +2735,21 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
- 		lp->init_block->mode =
- 		    cpu_to_le16(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) <<
- 				7);
--		lp->a.write_csr(ioaddr, CSR15, csr15 | 0x8000);
-+		lp->a->write_csr(ioaddr, CSR15, csr15 | 0x8000);
- 	} else {
- 		lp->init_block->mode =
- 		    cpu_to_le16((lp->options & PCNET32_PORT_PORTSEL) << 7);
--		lp->a.write_csr(ioaddr, CSR15, csr15 & 0x7fff);
-+		lp->a->write_csr(ioaddr, CSR15, csr15 & 0x7fff);
- 		pcnet32_load_multicast(dev);
- 	}
+-/* Uses Mbox */
+-int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
++/* Uses synchronous mcc */
++int be_cmd_get_die_temperature(struct be_adapter *adapter)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_get_cntl_addnl_attribs *req;
++	u16 mccq_index;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	mccq_index = adapter->mcc_obj.q.head;
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++		OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES, sizeof(*req));
++
++	wrb->tag1 = mccq_index;
++
++	be_mcc_notify(adapter);
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++
++/* Uses synchronous mcc */
++int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_get_fat *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_MANAGE_FAT);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++		OPCODE_COMMON_MANAGE_FAT, sizeof(*req));
++	req->fat_operation = cpu_to_le32(QUERY_FAT);
++	status = be_mcc_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_get_fat *resp = embedded_payload(wrb);
++		if (log_size && resp->log_size)
++			*log_size = le32_to_cpu(resp->log_size) -
++					sizeof(u32);
++	}
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
++{
++	struct be_dma_mem get_fat_cmd;
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_get_fat *req;
++	struct be_sge *sge;
++	u32 offset = 0, total_size, buf_size,
++				log_offset = sizeof(u32), payload_len;
++	int status;
++
++	if (buf_len == 0)
++		return;
++
++	total_size = buf_len;
++
++	get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024;
++	get_fat_cmd.va = pci_alloc_consistent(adapter->pdev,
++			get_fat_cmd.size,
++			&get_fat_cmd.dma);
++	if (!get_fat_cmd.va) {
++		status = -ENOMEM;
++		dev_err(&adapter->pdev->dev,
++		"Memory allocation failure while retrieving FAT data\n");
++		return;
++	}
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	while (total_size) {
++		buf_size = min(total_size, (u32)60*1024);
++		total_size -= buf_size;
++
++		wrb = wrb_from_mccq(adapter);
++		if (!wrb) {
++			status = -EBUSY;
++			goto err;
++		}
++		req = get_fat_cmd.va;
++		sge = nonembedded_sgl(wrb);
++
++		payload_len = sizeof(struct be_cmd_req_get_fat) + buf_size;
++		be_wrb_hdr_prepare(wrb, payload_len, false, 1,
++				OPCODE_COMMON_MANAGE_FAT);
++
++		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++				OPCODE_COMMON_MANAGE_FAT, payload_len);
++
++		sge->pa_hi = cpu_to_le32(upper_32_bits(get_fat_cmd.dma));
++		sge->pa_lo = cpu_to_le32(get_fat_cmd.dma & 0xFFFFFFFF);
++		sge->len = cpu_to_le32(get_fat_cmd.size);
++
++		req->fat_operation = cpu_to_le32(RETRIEVE_FAT);
++		req->read_log_offset = cpu_to_le32(log_offset);
++		req->read_log_length = cpu_to_le32(buf_size);
++		req->data_buffer_size = cpu_to_le32(buf_size);
++
++		status = be_mcc_notify_wait(adapter);
++		if (!status) {
++			struct be_cmd_resp_get_fat *resp = get_fat_cmd.va;
++			memcpy(buf + offset,
++				resp->data_buffer,
++				le32_to_cpu(resp->read_log_length));
++		} else {
++			dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n");
++			goto err;
++		}
++		offset += buf_size;
++		log_offset += buf_size;
++	}
++err:
++	pci_free_consistent(adapter->pdev, get_fat_cmd.size,
++			get_fat_cmd.va,
++			get_fat_cmd.dma);
++	spin_unlock_bh(&adapter->mcc_lock);
++}
++
++/* Uses synchronous mcc */
++int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver,
++		char *fw_on_flash)
+ {
+ 	struct be_mcc_wrb *wrb;
+ 	struct be_cmd_req_get_fw_version *req;
+ 	int status;
  
- 	if (suspended) {
- 		int csr5;
- 		/* clear SUSPEND (SPND) - CSR5 bit 0 */
--		csr5 = lp->a.read_csr(ioaddr, CSR5);
--		lp->a.write_csr(ioaddr, CSR5, csr5 & (~CSR5_SUSPEND));
-+		csr5 = lp->a->read_csr(ioaddr, CSR5);
-+		lp->a->write_csr(ioaddr, CSR5, csr5 & (~CSR5_SUSPEND));
- 	} else {
--		lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
-+		lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
- 		pcnet32_restart(dev, CSR0_NORMAL);
- 		netif_wake_queue(dev);
- 	}
-@@ -2767,8 +2767,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
- 	if (!lp->mii)
- 		return 0;
+-	spin_lock(&adapter->mbox_lock);
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
  
--	lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
--	val_out = lp->a.read_bcr(ioaddr, 34);
-+	lp->a->write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
-+	val_out = lp->a->read_bcr(ioaddr, 34);
+-	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
  
- 	return val_out;
- }
-@@ -2782,8 +2782,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
- 	if (!lp->mii)
- 		return;
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_GET_FW_VERSION);
  
--	lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
--	lp->a.write_bcr(ioaddr, 34, val);
-+	lp->a->write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
-+	lp->a->write_bcr(ioaddr, 34, val);
- }
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_GET_FW_VERSION, sizeof(*req));
  
- static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-@@ -2862,7 +2862,7 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
- 		curr_link = mii_link_ok(&lp->mii_if);
- 	} else {
- 		ulong ioaddr = dev->base_addr;	/* card base I/O address */
--		curr_link = (lp->a.read_bcr(ioaddr, 4) != 0xc0);
-+		curr_link = (lp->a->read_bcr(ioaddr, 4) != 0xc0);
+-	status = be_mbox_notify_wait(adapter);
++	status = be_mcc_notify_wait(adapter);
+ 	if (!status) {
+ 		struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
+-		strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN);
++		strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN-1);
++		if (fw_on_flash)
++			strncpy(fw_on_flash, resp->fw_on_flash_version_string,
++								FW_VER_LEN-1);
  	}
- 	if (!curr_link) {
- 		if (prev_link || verbose) {
-@@ -2887,13 +2887,13 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
- 				       (ecmd.duplex ==
- 					DUPLEX_FULL) ? "full" : "half");
- 			}
--			bcr9 = lp->a.read_bcr(dev->base_addr, 9);
-+			bcr9 = lp->a->read_bcr(dev->base_addr, 9);
- 			if ((bcr9 & (1 << 0)) != lp->mii_if.full_duplex) {
- 				if (lp->mii_if.full_duplex)
- 					bcr9 |= (1 << 0);
- 				else
- 					bcr9 &= ~(1 << 0);
--				lp->a.write_bcr(dev->base_addr, 9, bcr9);
-+				lp->a->write_bcr(dev->base_addr, 9, bcr9);
- 			}
- 		} else {
- 			if (netif_msg_link(lp))
-diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
-index 7cc9898..6eb50d3 100644
---- a/drivers/net/sis190.c
-+++ b/drivers/net/sis190.c
-@@ -1598,7 +1598,7 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
- static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
- 						  struct net_device *dev)
- {
--	static const u16 __devinitdata ids[] = { 0x0965, 0x0966, 0x0968 };
-+	static const u16 __devinitconst ids[] = { 0x0965, 0x0966, 0x0968 };
- 	struct sis190_private *tp = netdev_priv(dev);
- 	struct pci_dev *isa_bridge;
- 	u8 reg, tmp8;
-diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
-index e13685a..60c948c 100644
---- a/drivers/net/sundance.c
-+++ b/drivers/net/sundance.c
-@@ -225,7 +225,7 @@ enum {
- struct pci_id_info {
-         const char *name;
- };
--static const struct pci_id_info pci_id_tbl[] __devinitdata = {
-+static const struct pci_id_info pci_id_tbl[] __devinitconst = {
- 	{"D-Link DFE-550TX FAST Ethernet Adapter"},
- 	{"D-Link DFE-550FX 100Mbps Fiber-optics Adapter"},
- 	{"D-Link DFE-580TX 4 port Server Adapter"},
-diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
-index 529f55a..cccaa18 100644
---- a/drivers/net/tg3.h
-+++ b/drivers/net/tg3.h
-@@ -95,6 +95,7 @@
- #define  CHIPREV_ID_5750_A0		 0x4000
- #define  CHIPREV_ID_5750_A1		 0x4001
- #define  CHIPREV_ID_5750_A3		 0x4003
-+#define  CHIPREV_ID_5750_C1		 0x4201
- #define  CHIPREV_ID_5750_C2		 0x4202
- #define  CHIPREV_ID_5752_A0_HW		 0x5000
- #define  CHIPREV_ID_5752_A0		 0x6000
-diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
-index b9db1b5..720f9ce 100644
---- a/drivers/net/tokenring/abyss.c
-+++ b/drivers/net/tokenring/abyss.c
-@@ -451,10 +451,12 @@ static struct pci_driver abyss_driver = {
+-
+-	spin_unlock(&adapter->mbox_lock);
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
+ 	return status;
+ }
  
- static int __init abyss_init (void)
+@@ -897,13 +1464,19 @@ int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd)
  {
--	abyss_netdev_ops = tms380tr_netdev_ops;
-+	pax_open_kernel();
-+	memcpy((void *)&abyss_netdev_ops, &tms380tr_netdev_ops, sizeof(tms380tr_netdev_ops));
+ 	struct be_mcc_wrb *wrb;
+ 	struct be_cmd_req_modify_eq_delay *req;
++	int status = 0;
  
--	abyss_netdev_ops.ndo_open = abyss_open;
--	abyss_netdev_ops.ndo_stop = abyss_close;
-+	*(void **)&abyss_netdev_ops.ndo_open = abyss_open;
-+	*(void **)&abyss_netdev_ops.ndo_stop = abyss_close;
-+	pax_close_kernel();
+ 	spin_lock_bh(&adapter->mcc_lock);
  
- 	return pci_register_driver(&abyss_driver);
+ 	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
+ 	req = embedded_payload(wrb);
+ 
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_MODIFY_EQ_DELAY);
+ 
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
+@@ -915,8 +1488,9 @@ int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd)
+ 
+ 	be_mcc_notify(adapter);
+ 
++err:
+ 	spin_unlock_bh(&adapter->mcc_lock);
+-	return 0;
++	return status;
  }
-diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
-index 456f8bf..373e56d 100644
---- a/drivers/net/tokenring/madgemc.c
-+++ b/drivers/net/tokenring/madgemc.c
-@@ -755,9 +755,11 @@ static struct mca_driver madgemc_driver = {
- 
- static int __init madgemc_init (void)
- {
--	madgemc_netdev_ops = tms380tr_netdev_ops;
--	madgemc_netdev_ops.ndo_open = madgemc_open;
--	madgemc_netdev_ops.ndo_stop = madgemc_close;
-+	pax_open_kernel();
-+	memcpy((void *)&madgemc_netdev_ops, &tms380tr_netdev_ops, sizeof(tms380tr_netdev_ops));
-+	*(void **)&madgemc_netdev_ops.ndo_open = madgemc_open;
-+	*(void **)&madgemc_netdev_ops.ndo_stop = madgemc_close;
-+	pax_close_kernel();
  
- 	return mca_register_driver (&madgemc_driver);
- }
-diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
-index 16e8783..925bd49 100644
---- a/drivers/net/tokenring/proteon.c
-+++ b/drivers/net/tokenring/proteon.c
-@@ -353,9 +353,11 @@ static int __init proteon_init(void)
- 	struct platform_device *pdev;
- 	int i, num = 0, err = 0;
+ /* Uses sycnhronous mcc */
+@@ -930,9 +1504,14 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
+ 	spin_lock_bh(&adapter->mcc_lock);
  
--	proteon_netdev_ops = tms380tr_netdev_ops;
--	proteon_netdev_ops.ndo_open = proteon_open;
--	proteon_netdev_ops.ndo_stop = tms380tr_close;
-+	pax_open_kernel();
-+	memcpy((void *)&proteon_netdev_ops, &tms380tr_netdev_ops, sizeof(tms380tr_netdev_ops));
-+	*(void **)&proteon_netdev_ops.ndo_open = proteon_open;
-+	*(void **)&proteon_netdev_ops.ndo_stop = tms380tr_close;
-+	pax_close_kernel();
+ 	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
+ 	req = embedded_payload(wrb);
  
- 	err = platform_driver_register(&proteon_driver);
- 	if (err)
-diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
-index 46db5c5..37c1536 100644
---- a/drivers/net/tokenring/skisa.c
-+++ b/drivers/net/tokenring/skisa.c
-@@ -363,9 +363,11 @@ static int __init sk_isa_init(void)
- 	struct platform_device *pdev;
- 	int i, num = 0, err = 0;
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_NTWK_VLAN_CONFIG);
  
--	sk_isa_netdev_ops = tms380tr_netdev_ops;
--	sk_isa_netdev_ops.ndo_open = sk_isa_open;
--	sk_isa_netdev_ops.ndo_stop = tms380tr_close;
-+	pax_open_kernel();
-+	memcpy((void *)&sk_isa_netdev_ops, &tms380tr_netdev_ops, sizeof(tms380tr_netdev_ops));
-+	*(void **)&sk_isa_netdev_ops.ndo_open = sk_isa_open;
-+	*(void **)&sk_isa_netdev_ops.ndo_stop = tms380tr_close;
-+	pax_close_kernel();
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_NTWK_VLAN_CONFIG, sizeof(*req));
+@@ -948,79 +1527,63 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
  
- 	err = platform_driver_register(&sk_isa_driver);
- 	if (err)
-diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
-index 74e5ba4..5cf6bc9 100644
---- a/drivers/net/tulip/de2104x.c
-+++ b/drivers/net/tulip/de2104x.c
-@@ -1785,6 +1785,8 @@ static void __devinit de21041_get_srom_info (struct de_private *de)
- 	struct de_srom_info_leaf *il;
- 	void *bufp;
+ 	status = be_mcc_notify_wait(adapter);
  
-+	pax_track_stack();
-+
- 	/* download entire eeprom */
- 	for (i = 0; i < DE_EEPROM_WORDS; i++)
- 		((__le16 *)ee_data)[i] =
-diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
-index a8349b7..90f9dfe 100644
---- a/drivers/net/tulip/de4x5.c
-+++ b/drivers/net/tulip/de4x5.c
-@@ -5472,7 +5472,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
- 	for (i=0; i<ETH_ALEN; i++) {
- 	    tmp.addr[i] = dev->dev_addr[i];
- 	}
--	if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
-+	if (ioc->len > sizeof tmp.addr || copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
- 	break;
++err:
+ 	spin_unlock_bh(&adapter->mcc_lock);
+ 	return status;
+ }
  
-     case DE4X5_SET_HWADDR:           /* Set the hardware address */
-@@ -5512,7 +5512,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
- 	spin_lock_irqsave(&lp->lock, flags);
- 	memcpy(&statbuf, &lp->pktStats, ioc->len);
- 	spin_unlock_irqrestore(&lp->lock, flags);
--	if (copy_to_user(ioc->data, &statbuf, ioc->len))
-+	if (ioc->len > sizeof statbuf || copy_to_user(ioc->data, &statbuf, ioc->len))
- 		return -EFAULT;
- 	break;
-     }
-diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c
-index 391acd3..56d11cd 100644
---- a/drivers/net/tulip/eeprom.c
-+++ b/drivers/net/tulip/eeprom.c
-@@ -80,7 +80,7 @@ static struct eeprom_fixup eeprom_fixups[] __devinitdata = {
-   {NULL}};
+-/* Uses MCC for this command as it may be called in BH context
+- * Uses synchronous mcc
+- */
+-int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
++int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
+ {
+ 	struct be_mcc_wrb *wrb;
+-	struct be_cmd_req_promiscuous_config *req;
++	struct be_dma_mem *mem = &adapter->rx_filter;
++	struct be_cmd_req_rx_filter *req = mem->va;
++	struct be_sge *sge;
+ 	int status;
  
+ 	spin_lock_bh(&adapter->mcc_lock);
  
--static const char *block_name[] __devinitdata = {
-+static const char *block_name[] __devinitconst = {
- 	"21140 non-MII",
- 	"21140 MII PHY",
- 	"21142 Serial PHY",
-diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
-index b38d3b7..b1cff23 100644
---- a/drivers/net/tulip/winbond-840.c
-+++ b/drivers/net/tulip/winbond-840.c
-@@ -235,7 +235,7 @@ struct pci_id_info {
-         int drv_flags;		/* Driver use, intended as capability flags. */
- };
+ 	wrb = wrb_from_mccq(adapter);
+-	req = embedded_payload(wrb);
+-
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+-
+-	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
+-		OPCODE_ETH_PROMISCUOUS, sizeof(*req));
+-
+-	if (port_num)
+-		req->port1_promiscuous = en;
+-	else
+-		req->port0_promiscuous = en;
+-
+-	status = be_mcc_notify_wait(adapter);
+-
+-	spin_unlock_bh(&adapter->mcc_lock);
+-	return status;
+-}
+-
+-/*
+- * Uses MCC for this command as it may be called in BH context
+- * (mc == NULL) => multicast promiscous
+- */
+-int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
+-		struct dev_mc_list *mc_list, u32 mc_count)
+-{
+-#define BE_MAX_MC		32 /* set mcast promisc if > 32 */
+-	struct be_mcc_wrb *wrb;
+-	struct be_cmd_req_mcast_mac_config *req;
+-
+-	spin_lock_bh(&adapter->mcc_lock);
+-
+-	wrb = wrb_from_mccq(adapter);
+-	req = embedded_payload(wrb);
+-
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+-
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	sge = nonembedded_sgl(wrb);
++	sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma));
++	sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF);
++	sge->len = cpu_to_le32(mem->size);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
++				OPCODE_COMMON_NTWK_RX_FILTER);
++
++	memset(req, 0, sizeof(*req));
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+-		OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
++				OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req));
+ 
+-	req->interface_id = if_id;
+-	if (mc_list && mc_count <= BE_MAX_MC) {
+-		int i;
+-		struct dev_mc_list *mc;
+-
+-		req->num_mac = cpu_to_le16(mc_count);
+-
+-		for (mc = mc_list, i = 0; mc; mc = mc->next, i++)
+-			memcpy(req->mac[i].byte, mc->dmi_addr, ETH_ALEN);
++	req->if_id = cpu_to_le32(adapter->if_handle);
++	if (flags & IFF_PROMISC) {
++		req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
++				BE_IF_FLAGS_VLAN_PROMISCUOUS);
++		if (value == ON)
++			req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
++					BE_IF_FLAGS_VLAN_PROMISCUOUS);
++	} else if (flags & IFF_ALLMULTI) {
++		req->if_flags_mask = req->if_flags =
++			cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS);
+ 	} else {
+-		req->promiscuous = 1;
+-	}
++		struct netdev_hw_addr *ha;
++		int i = 0;
+ 
+-	be_mcc_notify_wait(adapter);
++		req->if_flags_mask = req->if_flags =
++		cpu_to_le32(BE_IF_FLAGS_MULTICAST);
++		req->mcast_num = cpu_to_le16(netdev_mc_count(adapter->netdev));
++		netdev_for_each_mc_addr(ha, adapter->netdev)
++			memcpy(req->mcast_mac[i++].byte, ha->DMI_ADDR,
++								ETH_ALEN);
++		}
++		status = be_mcc_notify_wait(adapter);
  
--static const struct pci_id_info pci_id_tbl[] __devinitdata = {
-+static const struct pci_id_info pci_id_tbl[] __devinitconst = {
- 	{ 				/* Sometime a Level-One switch card. */
- 	  "Winbond W89c840",	CanHaveMII | HasBrokenTx | FDXOnNoMII},
- 	{ "Winbond W89c840",	CanHaveMII | HasBrokenTx},
-diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
-index f450bc9..2b747c8 100644
---- a/drivers/net/usb/hso.c
-+++ b/drivers/net/usb/hso.c
-@@ -71,7 +71,7 @@
- #include <asm/byteorder.h>
- #include <linux/serial_core.h>
- #include <linux/serial.h>
++err:
+ 	spin_unlock_bh(&adapter->mcc_lock);
 -
-+#include <asm/local.h>
+-	return 0;
++	return status;
+ }
  
- #define DRIVER_VERSION			"1.2"
- #define MOD_AUTHOR			"Option Wireless"
-@@ -258,7 +258,7 @@ struct hso_serial {
+ /* Uses synchrounous mcc */
+@@ -1033,9 +1596,14 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
+ 	spin_lock_bh(&adapter->mcc_lock);
  
- 	/* from usb_serial_port */
- 	struct tty_struct *tty;
--	int open_count;
-+	local_t open_count;
- 	spinlock_t serial_lock;
+ 	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
+ 	req = embedded_payload(wrb);
  
- 	int (*write_data) (struct hso_serial *serial);
-@@ -1180,7 +1180,7 @@ static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial)
- 	struct urb *urb;
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_SET_FLOW_CONTROL);
  
- 	urb = serial->rx_urb[0];
--	if (serial->open_count > 0) {
-+	if (local_read(&serial->open_count) > 0) {
- 		count = put_rxbuf_data(urb, serial);
- 		if (count == -1)
- 			return;
-@@ -1216,7 +1216,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb)
- 	DUMP1(urb->transfer_buffer, urb->actual_length);
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_SET_FLOW_CONTROL, sizeof(*req));
+@@ -1045,6 +1613,7 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
  
- 	/* Anyone listening? */
--	if (serial->open_count == 0)
-+	if (local_read(&serial->open_count) == 0)
- 		return;
+ 	status = be_mcc_notify_wait(adapter);
  
- 	if (status == 0) {
-@@ -1311,8 +1311,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
- 	spin_unlock_irq(&serial->serial_lock);
++err:
+ 	spin_unlock_bh(&adapter->mcc_lock);
+ 	return status;
+ }
+@@ -1059,9 +1628,14 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
+ 	spin_lock_bh(&adapter->mcc_lock);
  
- 	/* check for port already opened, if not set the termios */
--	serial->open_count++;
--	if (serial->open_count == 1) {
-+	if (local_inc_return(&serial->open_count) == 1) {
- 		tty->low_latency = 1;
- 		serial->rx_state = RX_IDLE;
- 		/* Force default termio settings */
-@@ -1325,7 +1324,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
- 		result = hso_start_serial_device(serial->parent, GFP_KERNEL);
- 		if (result) {
- 			hso_stop_serial_device(serial->parent);
--			serial->open_count--;
-+			local_dec(&serial->open_count);
- 			kref_put(&serial->parent->ref, hso_serial_ref_free);
- 		}
- 	} else {
-@@ -1362,10 +1361,10 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
+ 	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
+ 	req = embedded_payload(wrb);
  
- 	/* reset the rts and dtr */
- 	/* do the actual close */
--	serial->open_count--;
-+	local_dec(&serial->open_count);
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_GET_FLOW_CONTROL);
  
--	if (serial->open_count <= 0) {
--		serial->open_count = 0;
-+	if (local_read(&serial->open_count) <= 0) {
-+		local_set(&serial->open_count,  0);
- 		spin_lock_irq(&serial->serial_lock);
- 		if (serial->tty == tty) {
- 			serial->tty->driver_data = NULL;
-@@ -1447,7 +1446,7 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req));
+@@ -1074,23 +1648,27 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
+ 		*rx_fc = le16_to_cpu(resp->rx_flow_control);
+ 	}
  
- 	/* the actual setup */
- 	spin_lock_irqsave(&serial->serial_lock, flags);
--	if (serial->open_count)
-+	if (local_read(&serial->open_count))
- 		_hso_serial_set_termios(tty, old);
- 	else
- 		tty->termios = old;
-@@ -3097,7 +3096,7 @@ static int hso_resume(struct usb_interface *iface)
- 	/* Start all serial ports */
- 	for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
- 		if (serial_table[i] && (serial_table[i]->interface == iface)) {
--			if (dev2ser(serial_table[i])->open_count) {
-+			if (local_read(&dev2ser(serial_table[i])->open_count)) {
- 				result =
- 				    hso_start_serial_device(serial_table[i], GFP_NOIO);
- 				hso_kick_transmit(dev2ser(serial_table[i]));
-diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
-index 3e94f0c..ffdd926 100644
---- a/drivers/net/vxge/vxge-config.h
-+++ b/drivers/net/vxge/vxge-config.h
-@@ -474,7 +474,7 @@ struct vxge_hw_uld_cbs {
- 	void (*link_down)(struct __vxge_hw_device *devh);
- 	void (*crit_err)(struct __vxge_hw_device *devh,
- 			enum vxge_hw_event type, u64 ext_data);
--};
-+} __no_const;
++err:
+ 	spin_unlock_bh(&adapter->mcc_lock);
+ 	return status;
+ }
  
- /*
-  * struct __vxge_hw_blockpool_entry - Block private data structure
-diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
-index 068d7a9..35293de 100644
---- a/drivers/net/vxge/vxge-main.c
-+++ b/drivers/net/vxge/vxge-main.c
-@@ -93,6 +93,8 @@ static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo)
- 	struct sk_buff *completed[NR_SKB_COMPLETED];
- 	int more;
+ /* Uses mbox */
+-int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *cap)
++int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
++			u32 *mode, u32 *function_caps)
+ {
+ 	struct be_mcc_wrb *wrb;
+ 	struct be_cmd_req_query_fw_cfg *req;
+ 	int status;
  
-+	pax_track_stack();
-+
- 	do {
- 		more = 0;
- 		skb_ptr = completed;
-@@ -1779,6 +1781,8 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
- 	u8 mtable[256] = {0}; /* CPU to vpath mapping  */
- 	int index;
+-	spin_lock(&adapter->mbox_lock);
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
  
-+	pax_track_stack();
-+
- 	/*
- 	 * Filling
- 	 * 	- itable with bucket numbers
-diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h
-index 461742b..81be42e 100644
---- a/drivers/net/vxge/vxge-traffic.h
-+++ b/drivers/net/vxge/vxge-traffic.h
-@@ -2123,7 +2123,7 @@ struct vxge_hw_mempool_cbs {
- 			struct vxge_hw_mempool_dma	*dma_object,
- 			u32			index,
- 			u32			is_last);
--};
-+} __no_const;
+ 	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
  
- void
- __vxge_hw_mempool_destroy(
-diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
-index cd8cb95..4153b79 100644
---- a/drivers/net/wan/cycx_x25.c
-+++ b/drivers/net/wan/cycx_x25.c
-@@ -1017,6 +1017,8 @@ static void hex_dump(char *msg, unsigned char *p, int len)
- 	unsigned char hex[1024],
- 	    	* phex = hex;
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_QUERY_FIRMWARE_CONFIG);
  
-+	pax_track_stack();
-+
- 	if (len >= (sizeof(hex) / 2))
- 		len = (sizeof(hex) / 2) - 1;
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
+@@ -1099,10 +1677,11 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *cap)
+ 	if (!status) {
+ 		struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
+ 		*port_num = le32_to_cpu(resp->phys_port);
+-		*cap = le32_to_cpu(resp->function_cap);
++		*mode = le32_to_cpu(resp->function_mode);
++		*function_caps = le32_to_cpu(resp->function_caps);
+ 	}
  
-diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
-index aa9248f..a4e3c3b 100644
---- a/drivers/net/wan/hdlc_x25.c
-+++ b/drivers/net/wan/hdlc_x25.c
-@@ -136,16 +136,16 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev)
+-	spin_unlock(&adapter->mbox_lock);
++	mutex_unlock(&adapter->mbox_lock);
+ 	return status;
+ }
  
- static int x25_open(struct net_device *dev)
- {
--	struct lapb_register_struct cb;
-+	static struct lapb_register_struct cb = {
-+		.connect_confirmation = x25_connected,
-+		.connect_indication = x25_connected,
-+		.disconnect_confirmation = x25_disconnected,
-+		.disconnect_indication = x25_disconnected,
-+		.data_indication = x25_data_indication,
-+		.data_transmit = x25_data_transmit
-+	};
- 	int result;
+@@ -1113,19 +1692,161 @@ int be_cmd_reset_function(struct be_adapter *adapter)
+ 	struct be_cmd_req_hdr *req;
+ 	int status;
  
--	cb.connect_confirmation = x25_connected;
--	cb.connect_indication = x25_connected;
--	cb.disconnect_confirmation = x25_disconnected;
--	cb.disconnect_indication = x25_disconnected;
--	cb.data_indication = x25_data_indication;
--	cb.data_transmit = x25_data_transmit;
--
- 	result = lapb_register(dev, &cb);
- 	if (result != LAPB_OK)
- 		return result;
-diff --git a/drivers/net/wimax/i2400m/usb-fw.c b/drivers/net/wimax/i2400m/usb-fw.c
-index 5ad287c..783b020 100644
---- a/drivers/net/wimax/i2400m/usb-fw.c
-+++ b/drivers/net/wimax/i2400m/usb-fw.c
-@@ -263,6 +263,8 @@ ssize_t i2400mu_bus_bm_wait_for_ack(struct i2400m *i2400m,
- 	int do_autopm = 1;
- 	DECLARE_COMPLETION_ONSTACK(notif_completion);
+-	spin_lock(&adapter->mbox_lock);
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
  
-+	pax_track_stack();
-+
- 	d_fnstart(8, dev, "(i2400m %p ack %p size %zu)\n",
- 		  i2400m, ack, ack_size);
- 	BUG_ON(_ack == i2400m->bm_ack_buf);
-diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
-index 6c26840..62c97c3 100644
---- a/drivers/net/wireless/airo.c
-+++ b/drivers/net/wireless/airo.c
-@@ -3003,6 +3003,8 @@ static void airo_process_scan_results (struct airo_info *ai) {
- 	BSSListElement * loop_net;
- 	BSSListElement * tmp_net;
+ 	wrb = wrb_from_mbox(adapter);
+ 	req = embedded_payload(wrb);
  
-+	pax_track_stack();
-+
- 	/* Blow away current list of scan results */
- 	list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) {
- 		list_move_tail (&loop_net->list, &ai->network_free_list);
-@@ -3783,6 +3785,8 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
- 	WepKeyRid wkr;
- 	int rc;
+-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_FUNCTION_RESET);
  
-+	pax_track_stack();
-+
- 	memset( &mySsid, 0, sizeof( mySsid ) );
- 	kfree (ai->flash);
- 	ai->flash = NULL;
-@@ -4758,6 +4762,8 @@ static int proc_stats_rid_open( struct inode *inode,
- 	__le32 *vals = stats.vals;
- 	int len;
+ 	be_cmd_hdr_prepare(req, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_FUNCTION_RESET, sizeof(*req));
  
-+	pax_track_stack();
-+
- 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
- 		return -ENOMEM;
- 	data = (struct proc_data *)file->private_data;
-@@ -5487,6 +5493,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
- 	/* If doLoseSync is not 1, we won't do a Lose Sync */
- 	int doLoseSync = -1;
+ 	status = be_mbox_notify_wait(adapter);
  
-+	pax_track_stack();
+-	spin_unlock(&adapter->mbox_lock);
++	mutex_unlock(&adapter->mbox_lock);
++	return status;
++}
 +
- 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
- 		return -ENOMEM;
- 	data = (struct proc_data *)file->private_data;
-@@ -7193,6 +7201,8 @@ static int airo_get_aplist(struct net_device *dev,
- 	int i;
- 	int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
- 
-+	pax_track_stack();
++int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_rss_config *req;
++	u32 myhash[10] = {0x0123, 0x4567, 0x89AB, 0xCDEF, 0x01EF,
++			0x0123, 0x4567, 0x89AB, 0xCDEF, 0x01EF};
++	int status;
 +
- 	qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL);
- 	if (!qual)
- 		return -ENOMEM;
-@@ -7753,6 +7763,8 @@ static void airo_read_wireless_stats(struct airo_info *local)
- 	CapabilityRid cap_rid;
- 	__le32 *vals = stats_rid.vals;
- 
-+	pax_track_stack();
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
 +
- 	/* Get stats out of the card */
- 	clear_bit(JOB_WSTATS, &local->jobs);
- 	if (local->power.event) {
-diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
-index 747508c..82e965d 100644
---- a/drivers/net/wireless/ath/ath5k/debug.c
-+++ b/drivers/net/wireless/ath/ath5k/debug.c
-@@ -205,6 +205,8 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
- 	unsigned int v;
- 	u64 tsf;
- 
-+	pax_track_stack();
++	wrb = wrb_from_mbox(adapter);
++	req = embedded_payload(wrb);
 +
- 	v = ath5k_hw_reg_read(sc->ah, AR5K_BEACON);
- 	len += snprintf(buf+len, sizeof(buf)-len,
- 		"%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
-@@ -318,6 +320,8 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf,
- 	unsigned int len = 0;
- 	unsigned int i;
- 
-+	pax_track_stack();
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++		OPCODE_ETH_RSS_CONFIG);
 +
- 	len += snprintf(buf+len, sizeof(buf)-len,
- 		"DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
- 
-diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
-index 2be4c22..593b1eb 100644
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -220,6 +220,8 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
- 	char buf[512];
- 	unsigned int len = 0;
- 
-+	pax_track_stack();
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
++		OPCODE_ETH_RSS_CONFIG, sizeof(*req));
 +
- 	len += snprintf(buf + len, sizeof(buf) - len,
- 		"%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
- 	len += snprintf(buf + len, sizeof(buf) - len,
-@@ -360,6 +362,8 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
- 	int i;
- 	u8 addr[ETH_ALEN];
- 
-+	pax_track_stack();
++	req->if_id = cpu_to_le32(adapter->if_handle);
++	req->enable_rss = cpu_to_le16(RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4);
++	req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1);
++	memcpy(req->cpu_table, rsstable, table_size);
++	memcpy(req->hash, myhash, sizeof(myhash));
++	be_dws_cpu_to_le(req->hash, sizeof(req->hash));
 +
- 	len += snprintf(buf + len, sizeof(buf) - len,
- 			"primary: %s (%s chan=%d ht=%d)\n",
- 			wiphy_name(sc->pri_wiphy->hw->wiphy),
-diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
-index 80b19a4..dab3a45 100644
---- a/drivers/net/wireless/b43/debugfs.c
-+++ b/drivers/net/wireless/b43/debugfs.c
-@@ -43,7 +43,7 @@ static struct dentry *rootdir;
- struct b43_debugfs_fops {
- 	ssize_t (*read)(struct b43_wldev *dev, char *buf, size_t bufsize);
- 	int (*write)(struct b43_wldev *dev, const char *buf, size_t count);
--	struct file_operations fops;
-+	const struct file_operations fops;
- 	/* Offset of struct b43_dfs_file in struct b43_dfsentry */
- 	size_t file_struct_offset;
- };
-diff --git a/drivers/net/wireless/b43legacy/debugfs.c b/drivers/net/wireless/b43legacy/debugfs.c
-index 1f85ac5..c99b4b4 100644
---- a/drivers/net/wireless/b43legacy/debugfs.c
-+++ b/drivers/net/wireless/b43legacy/debugfs.c
-@@ -44,7 +44,7 @@ static struct dentry *rootdir;
- struct b43legacy_debugfs_fops {
- 	ssize_t (*read)(struct b43legacy_wldev *dev, char *buf, size_t bufsize);
- 	int (*write)(struct b43legacy_wldev *dev, const char *buf, size_t count);
--	struct file_operations fops;
-+	const struct file_operations fops;
- 	/* Offset of struct b43legacy_dfs_file in struct b43legacy_dfsentry */
- 	size_t file_struct_offset;
- 	/* Take wl->irq_lock before calling read/write? */
-diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
-index 43102bf..3b569c3 100644
---- a/drivers/net/wireless/ipw2x00/ipw2100.c
-+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
-@@ -2014,6 +2014,8 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
- 	int err;
- 	DECLARE_SSID_BUF(ssid);
- 
-+	pax_track_stack();
++	status = be_mbox_notify_wait(adapter);
 +
- 	IPW_DEBUG_HC("SSID: '%s'\n", print_ssid(ssid, essid, ssid_len));
- 
- 	if (ssid_len)
-@@ -5380,6 +5382,8 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
- 	struct ipw2100_wep_key *wep_key = (void *)cmd.host_command_parameters;
- 	int err;
- 
-+	pax_track_stack();
++	mutex_unlock(&adapter->mbox_lock);
++	return status;
++}
 +
- 	IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n",
- 		     idx, keylen, len);
++/* Uses sync mcc */
++int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num,
++			u8 bcn, u8 sts, u8 state)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_enable_disable_beacon *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_ENABLE_DISABLE_BEACON);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++		OPCODE_COMMON_ENABLE_DISABLE_BEACON, sizeof(*req));
++
++	req->port_num = port_num;
++	req->beacon_state = state;
++	req->beacon_duration = bcn;
++	req->status_duration = sts;
++
++	status = be_mcc_notify_wait(adapter);
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++/* Uses sync mcc */
++int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_get_beacon_state *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_GET_BEACON_STATE);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++		OPCODE_COMMON_GET_BEACON_STATE, sizeof(*req));
++
++	req->port_num = port_num;
++
++	status = be_mcc_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_get_beacon_state *resp =
++						embedded_payload(wrb);
++		*state = resp->beacon_state;
++	}
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++/* Uses sync mcc */
++int be_cmd_read_port_type(struct be_adapter *adapter, u32 port,
++				u8 *connector)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_port_type *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(struct be_cmd_resp_port_type), true, 0,
++			OPCODE_COMMON_READ_TRANSRECV_DATA);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++		OPCODE_COMMON_READ_TRANSRECV_DATA, sizeof(*req));
++
++	req->port = cpu_to_le32(port);
++	req->page_num = cpu_to_le32(TR_PAGE_A0);
++	status = be_mcc_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_port_type *resp = embedded_payload(wrb);
++			*connector = resp->data.connector;
++	}
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
+ 	return status;
+ }
  
-diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
-index 282b1f7..169f0cf 100644
---- a/drivers/net/wireless/ipw2x00/libipw_rx.c
-+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
-@@ -1566,6 +1566,8 @@ static void libipw_process_probe_response(struct libipw_device
- 	unsigned long flags;
- 	DECLARE_SSID_BUF(ssid);
+@@ -1133,16 +1854,24 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
+ 			u32 flash_type, u32 flash_opcode, u32 buf_size)
+ {
+ 	struct be_mcc_wrb *wrb;
+-	struct be_cmd_write_flashrom *req = cmd->va;
++	struct be_cmd_write_flashrom *req;
+ 	struct be_sge *sge;
+ 	int status;
  
-+	pax_track_stack();
-+
- 	LIBIPW_DEBUG_SCAN("'%s' (%pM"
- 		     "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
- 		     print_ssid(ssid, info_element->data, info_element->len),
-diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
-index 950267a..80d5fd2 100644
---- a/drivers/net/wireless/iwlwifi/iwl-1000.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
-@@ -137,7 +137,7 @@ static struct iwl_lib_ops iwl1000_lib = {
- 	 },
- };
+ 	spin_lock_bh(&adapter->mcc_lock);
++	adapter->flash_status = 0;
  
--static struct iwl_ops iwl1000_ops = {
-+static const struct iwl_ops iwl1000_ops = {
- 	.ucode = &iwl5000_ucode,
- 	.lib = &iwl1000_lib,
- 	.hcmd = &iwl5000_hcmd,
-diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
-index 56bfcc3..b348020 100644
---- a/drivers/net/wireless/iwlwifi/iwl-3945.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
-@@ -2874,7 +2874,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
- 	.build_addsta_hcmd = iwl3945_build_addsta_hcmd,
- };
+ 	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err_unlock;
++	}
++	req = cmd->va;
+ 	sge = nonembedded_sgl(wrb);
+ 
+-	be_wrb_hdr_prepare(wrb, cmd->size, false, 1);
++	be_wrb_hdr_prepare(wrb, cmd->size, false, 1,
++			OPCODE_COMMON_WRITE_FLASHROM);
++	wrb->tag1 = CMD_SUBSYSTEM_COMMON;
+ 
+ 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ 		OPCODE_COMMON_WRITE_FLASHROM, cmd->size);
+@@ -1154,8 +1883,852 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
+ 	req->params.op_code = cpu_to_le32(flash_opcode);
+ 	req->params.data_buf_size = cpu_to_le32(buf_size);
+ 
++	be_mcc_notify(adapter);
++	spin_unlock_bh(&adapter->mcc_lock);
++
++	if (!wait_for_completion_timeout(&adapter->flash_compl,
++			msecs_to_jiffies(40000)))
++		status = -1;
++	else
++		status = adapter->flash_status;
++
++	return status;
++
++err_unlock:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
++			 int offset)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_write_flashrom *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req)+4, true, 0,
++			OPCODE_COMMON_READ_FLASHROM);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++		OPCODE_COMMON_READ_FLASHROM, sizeof(*req)+4);
++
++	req->params.op_type = cpu_to_le32(IMG_TYPE_REDBOOT);
++	req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
++	req->params.offset = cpu_to_le32(offset);
++	req->params.data_buf_size = cpu_to_le32(0x4);
++
++	status = be_mcc_notify_wait(adapter);
++	if (!status)
++		memcpy(flashed_crc, req->params.data_buf, 4);
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
++				struct be_dma_mem *nonemb_cmd)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_acpi_wol_magic_config *req;
++	struct be_sge *sge;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = nonemb_cmd->va;
++	sge = nonembedded_sgl(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
++			OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
++		OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG, sizeof(*req));
++	memcpy(req->magic_mac, mac, ETH_ALEN);
++
++	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
++	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
++	sge->len = cpu_to_le32(nonemb_cmd->size);
++
++	status = be_mcc_notify_wait(adapter);
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
++			u8 loopback_type, u8 enable)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_set_lmode *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++				OPCODE_LOWLEVEL_SET_LOOPBACK_MODE);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
++			OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
++			sizeof(*req));
++
++	req->src_port = port_num;
++	req->dest_port = port_num;
++	req->loopback_type = loopback_type;
++	req->loopback_state = enable;
++
++	status = be_mcc_notify_wait(adapter);
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
++		u32 loopback_type, u32 pkt_size, u32 num_pkts, u64 pattern)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_loopback_test *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++				OPCODE_LOWLEVEL_LOOPBACK_TEST);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
++			OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req));
++	req->hdr.timeout = cpu_to_le32(4);
++
++	req->pattern = cpu_to_le64(pattern);
++	req->src_port = cpu_to_le32(port_num);
++	req->dest_port = cpu_to_le32(port_num);
++	req->pkt_size = cpu_to_le32(pkt_size);
++	req->num_pkts = cpu_to_le32(num_pkts);
++	req->loopback_type = cpu_to_le32(loopback_type);
++
++	status = be_mcc_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_loopback_test *resp = embedded_payload(wrb);
++		status = le32_to_cpu(resp->status);
++	}
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
++				u32 byte_cnt, struct be_dma_mem *cmd)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_ddrdma_test *req;
++	struct be_sge *sge;
++	int status;
++	int i, j = 0;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = cmd->va;
++	sge = nonembedded_sgl(wrb);
++	be_wrb_hdr_prepare(wrb, cmd->size, false, 1,
++				OPCODE_LOWLEVEL_HOST_DDR_DMA);
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
++			OPCODE_LOWLEVEL_HOST_DDR_DMA, cmd->size);
++
++	sge->pa_hi = cpu_to_le32(upper_32_bits(cmd->dma));
++	sge->pa_lo = cpu_to_le32(cmd->dma & 0xFFFFFFFF);
++	sge->len = cpu_to_le32(cmd->size);
++
++	req->pattern = cpu_to_le64(pattern);
++	req->byte_count = cpu_to_le32(byte_cnt);
++	for (i = 0; i < byte_cnt; i++) {
++		req->snd_buff[i] = (u8)(pattern >> (j*8));
++		j++;
++		if (j > 7)
++			j = 0;
++	}
++
++	status = be_mcc_notify_wait(adapter);
++
++	if (!status) {
++		struct be_cmd_resp_ddrdma_test *resp;
++		resp = cmd->va;
++		if ((memcmp(resp->rcv_buff, req->snd_buff, byte_cnt) != 0) ||
++				resp->snd_err) {
++			status = -1;
++		}
++	}
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_get_seeprom_data(struct be_adapter *adapter,
++				struct be_dma_mem *nonemb_cmd)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_seeprom_read *req;
++	struct be_sge *sge;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	req = nonemb_cmd->va;
++	sge = nonembedded_sgl(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
++			OPCODE_COMMON_SEEPROM_READ);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_SEEPROM_READ, sizeof(*req));
++
++	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
++	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
++	sge->len = cpu_to_le32(nonemb_cmd->size);
++
++	status = be_mcc_notify_wait(adapter);
++
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_get_phy_info(struct be_adapter *adapter,
++			 struct be_phy_info *phy_info)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_get_phy_info *req;
++	struct be_sge *sge;
++	struct be_dma_mem cmd;
++	struct be_phy_info *resp_phy_info;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	cmd.size = sizeof(struct be_cmd_req_get_phy_info);
++	cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size,
++					&cmd.dma);
++	if (!cmd.va) {
++		dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
++		status = -ENOMEM;
++		goto err;
++	}
++
++	req = cmd.va;
++	sge = nonembedded_sgl(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
++				OPCODE_COMMON_GET_PHY_DETAILS);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_GET_PHY_DETAILS,
++			sizeof(*req));
++
++	sge->pa_hi = cpu_to_le32(upper_32_bits(cmd.dma));
++	sge->pa_lo = cpu_to_le32(cmd.dma & 0xFFFFFFFF);
++	sge->len = cpu_to_le32(cmd.size);
++
++	status = be_mcc_notify_wait(adapter);
++	if (!status) {
++		resp_phy_info = cmd.va + sizeof(struct be_cmd_req_hdr);
++		phy_info->phy_type = le16_to_cpu(resp_phy_info->phy_type);
++		phy_info->interface_type =
++			le16_to_cpu(resp_phy_info->interface_type);
++		phy_info->auto_speeds_supported =
++			le16_to_cpu(resp_phy_info->auto_speeds_supported);
++		phy_info->fixed_speeds_supported =
++			le16_to_cpu(resp_phy_info->fixed_speeds_supported);
++		phy_info->misc_params =
++			le32_to_cpu(resp_phy_info->misc_params);
++	}
++	pci_free_consistent(adapter->pdev, cmd.size,
++				cmd.va, cmd.dma);
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_set_qos *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++				OPCODE_COMMON_SET_QOS);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_SET_QOS, sizeof(*req));
++
++	req->hdr.domain = domain;
++	req->valid_bits = cpu_to_le32(BE_QOS_BITS_NIC);
++	req->max_bps_nic = cpu_to_le32(bps);
++
++	status = be_mcc_notify_wait(adapter);
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_get_cntl_attributes(struct be_adapter *adapter)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_cntl_attribs *req;
++	struct be_cmd_resp_cntl_attribs *resp;
++	struct be_sge *sge;
++	int status;
++	int payload_len = max(sizeof(*req), sizeof(*resp));
++	struct mgmt_controller_attrib *attribs;
++	struct be_dma_mem attribs_cmd;
++
++	memset(&attribs_cmd, 0, sizeof(struct be_dma_mem));
++	attribs_cmd.size = sizeof(struct be_cmd_resp_cntl_attribs);
++	attribs_cmd.va = pci_alloc_consistent(adapter->pdev, attribs_cmd.size,
++						&attribs_cmd.dma);
++	if (!attribs_cmd.va) {
++		dev_err(&adapter->pdev->dev,
++				"Memory allocation failure\n");
++		return -ENOMEM;
++	}
++
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
++
++	wrb = wrb_from_mbox(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = attribs_cmd.va;
++	sge = nonembedded_sgl(wrb);
++
++	be_wrb_hdr_prepare(wrb, payload_len, false, 1,
++			OPCODE_COMMON_GET_CNTL_ATTRIBUTES);
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			 OPCODE_COMMON_GET_CNTL_ATTRIBUTES, payload_len);
++	sge->pa_hi = cpu_to_le32(upper_32_bits(attribs_cmd.dma));
++	sge->pa_lo = cpu_to_le32(attribs_cmd.dma & 0xFFFFFFFF);
++	sge->len = cpu_to_le32(attribs_cmd.size);
++
++	status = be_mbox_notify_wait(adapter);
++	if (!status) {
++		attribs = (struct mgmt_controller_attrib *)(attribs_cmd.va +
++					sizeof(struct be_cmd_resp_hdr));
++		adapter->hba_port_num = attribs->hba_attribs.phy_port;
++		strncpy(adapter->model_number,
++			attribs->hba_attribs.controller_model_number, 31);
++	}
++
++err:
++	mutex_unlock(&adapter->mbox_lock);
++	pci_free_consistent(adapter->pdev, attribs_cmd.size, attribs_cmd.va,
++					attribs_cmd.dma);
++	return status;
++}
++
++/* Uses mbox */
++int be_cmd_req_native_mode(struct be_adapter *adapter)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_set_func_cap *req;
++	int status;
++
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
++
++	wrb = wrb_from_mbox(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++		OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++		OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP, sizeof(*req));
++
++	req->valid_cap_flags = cpu_to_le32(CAPABILITY_SW_TIMESTAMPS |
++				CAPABILITY_BE3_NATIVE_ERX_API);
++	req->cap_flags = cpu_to_le32(CAPABILITY_BE3_NATIVE_ERX_API);
++
++	status = be_mbox_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_set_func_cap *resp = embedded_payload(wrb);
++		adapter->be3_native = le32_to_cpu(resp->cap_flags) &
++					CAPABILITY_BE3_NATIVE_ERX_API;
++	}
++err:
++	mutex_unlock(&adapter->mbox_lock);
++	return status;
++}
++
++static void encode_port_names(struct be_adapter *adapter)
++{
++	switch (adapter->port_name[adapter->hba_port_num]) {
++	case '0':
++		adapter->port_name[adapter->hba_port_num] = 0;
++		break;
++	case '1':
++		adapter->port_name[adapter->hba_port_num] = 1;
++		break;
++	case '2':
++		adapter->port_name[adapter->hba_port_num] = 2;
++		break;
++	case '3':
++		adapter->port_name[adapter->hba_port_num] = 3;
++		break;
++	case '4':
++		adapter->port_name[adapter->hba_port_num] = 4;
++		break;
++	case 'A':
++		adapter->port_name[adapter->hba_port_num] = 5;
++		break;
++	case 'B':
++		adapter->port_name[adapter->hba_port_num] = 6;
++		break;
++	case 'C':
++		adapter->port_name[adapter->hba_port_num] = 7;
++		break;
++	case 'D':
++		adapter->port_name[adapter->hba_port_num] = 8;
++		break;
++	}
++}
++
++int be_cmd_query_port_names_v0(struct be_adapter *adapter, u8 *port_name)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_get_port_name *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_GET_PORT_NAME);
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_GET_PORT_NAME, sizeof(*req));
++
++	status = be_mcc_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_get_port_name *resp = embedded_payload(wrb);
++		port_name[0] = resp->port0_name;
++		port_name[1] = resp->port1_name;
++	}
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++
++	if(!status)
++		encode_port_names(adapter);
++	return status;
++}
++
++int be_cmd_query_port_names_v1(struct be_adapter *adapter, u8 *port_name)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_get_port_name *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_GET_PORT_NAME);
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_GET_PORT_NAME, sizeof(*req));
++	req->hdr.version = 1;
++
+ 	status = be_mcc_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_get_port_name_v1 *resp = embedded_payload(wrb);
++		port_name[0] = resp->port0_name;
++		port_name[1] = resp->port1_name;
++		port_name[2] = resp->port2_name;
++		port_name[3] = resp->port3_name;
++	}
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++
++	if (!status)
++		encode_port_names(adapter);
++	return status;
++}
++
++int be_cmd_req_pg_pfc(struct be_adapter *adapter, int *fw_num_txqs)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_pg *req;
++	int status, num = 0;
++	bool query = true;
++
++	*fw_num_txqs = MAX_TX_QS;
++
++	if (mutex_lock_interruptible(&adapter->mbox_lock))
++		return -1;
++
++enable_pfc:
++	wrb = wrb_from_mbox(adapter);
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_ETH_PG_FEATURE_QUERY_REQUEST);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
++		OPCODE_ETH_PG_FEATURE_QUERY_REQUEST, sizeof(*req));
++
++	if (query)
++		req->query |= cpu_to_le32(REQ_PG_QUERY);
++	req->pfc_pg |= cpu_to_le32(REQ_PG_FEAT);
++
++	status = be_mbox_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_pg *resp = embedded_payload(wrb);
++		if (query) {
++			if (le32_to_cpu(resp->pfc_pg) & REQ_PG_FEAT) {
++				num = le32_to_cpu(resp->num_tx_rings);
++				query = false;
++				goto enable_pfc;
++			}
++		} else {
++			adapter->flags |= BE_FLAGS_DCBX;
++			*fw_num_txqs = num;
++		}
++	}
++
++	mutex_unlock(&adapter->mbox_lock);
++	return status;
++}
++
++/* Set privilege(s) for a function */
++int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 mask, u32 *prev,
++			u32 domain)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_set_fn_privileges *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++				OPCODE_COMMON_SET_FN_PRIVILEGES);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_SET_FN_PRIVILEGES, sizeof(*req));
++
++	req->hdr.domain = domain;
++	req->privilege_mask = cpu_to_le32(mask);
++
++	status = be_mcc_notify_wait(adapter);
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++/* Get privilege(s) for a function */
++int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
++			u32 domain)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_get_fn_privileges *req;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++
++	req = embedded_payload(wrb);
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++				OPCODE_COMMON_GET_FN_PRIVILEGES);
  
--static struct iwl_ops iwl3945_ops = {
-+static const struct iwl_ops iwl3945_ops = {
- 	.ucode = &iwl3945_ucode,
- 	.lib = &iwl3945_lib,
- 	.hcmd = &iwl3945_hcmd,
-diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
-index 585b8d4..e142963 100644
---- a/drivers/net/wireless/iwlwifi/iwl-4965.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
-@@ -2345,7 +2345,7 @@ static struct iwl_lib_ops iwl4965_lib = {
- 	},
- };
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_GET_FN_PRIVILEGES, sizeof(*req));
++
++	req->hdr.domain = domain;
++
++	status = be_mcc_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_get_fn_privileges *resp =
++						embedded_payload(wrb);
++		*privilege = le32_to_cpu(resp->privilege_mask);
++	} else
++		*privilege = 0;
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++/* Set Hyper switch config */
++int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
++			u32 domain, u16 intf_id)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_set_hsw_config *req;
++	void *ctxt;
++	int status;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++
++	req = embedded_payload(wrb);
++	ctxt = &req->context;
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++				OPCODE_COMMON_SET_HSW_CONFIG);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_SET_HSW_CONFIG, sizeof(*req));
++
++	req->hdr.domain = domain;
++	AMAP_SET_BITS(struct amap_set_hsw_context, interface_id, ctxt, intf_id);
++	if (pvid) {
++		AMAP_SET_BITS(struct amap_set_hsw_context, pvid_valid, ctxt, 1);
++		AMAP_SET_BITS(struct amap_set_hsw_context, pvid, ctxt, pvid);
++	}
++
++	be_dws_cpu_to_le(req->context, sizeof(req->context));
++	status = be_mcc_notify_wait(adapter);
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++/* Get Hyper switch config */
++int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
++			u32 domain, u16 intf_id)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_get_hsw_config *req;
++	void *ctxt;
++	int status;
++	u16 vid;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++
++	req = embedded_payload(wrb);
++	ctxt = &req->context;
++
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++				OPCODE_COMMON_GET_HSW_CONFIG);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_GET_HSW_CONFIG, sizeof(*req));
++
++	req->hdr.domain = domain;
++	AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id, ctxt,
++								intf_id);
++	AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
++	be_dws_cpu_to_le(req->context, sizeof(req->context));
++
++	status = be_mcc_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_get_hsw_config *resp =
++						embedded_payload(wrb);
++		be_dws_le_to_cpu(&resp->context,
++						sizeof(resp->context));
++		vid = AMAP_GET_BITS(struct amap_get_hsw_resp_context,
++							pvid, &resp->context);
++		*pvid = le16_to_cpu(vid);
++	}
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_get_port_speed(struct be_adapter *adapter,
++		u8 port_num, u16 *dac_cable_len, u16 *port_speed)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_get_port_speed *req;
++	int status = 0;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++
++	req = embedded_payload(wrb);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_NTWK_GET_LINK_SPEED);
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_NTWK_GET_LINK_SPEED,
++			sizeof(*req));
++	req->port_num = port_num;
++	status = be_mcc_notify_wait(adapter);
++	if (!status) {
++		struct be_cmd_resp_get_port_speed *resp =
++			embedded_payload(wrb);
++		*dac_cable_len = resp->dac_cable_length;
++		*port_speed = resp->mac_speed;
++	}
++
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++int be_cmd_set_port_speed_v1(struct be_adapter *adapter,
++				u8 port_num, u16 mac_speed,
++				u16 dac_cable_len)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_cmd_req_set_port_speed_v1 *req;
++	int status = 0;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	req = embedded_payload(wrb);
++	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
++			OPCODE_COMMON_NTWK_SET_LINK_SPEED);
++
++	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
++			OPCODE_COMMON_NTWK_SET_LINK_SPEED,
++			sizeof(*req));
++	req->hdr.version=1;
++
++	req->port_num = port_num;
++	req->virt_port = port_num;
++	req->mac_speed = mac_speed;
++	req->dac_cable_length = dac_cable_len;
++	status = be_mcc_notify_wait(adapter);
++err:
++	spin_unlock_bh(&adapter->mcc_lock);
++	return status;
++}
++
++
++/* Uses sync mcc */
++#ifdef CONFIG_PALAU
++int be_cmd_pass_ext_ioctl(struct be_adapter *adapter, dma_addr_t dma,
++			int req_size, void *va)
++{
++	struct be_mcc_wrb *wrb;
++	struct be_sge *sge;
++	int status;
++	struct be_cmd_req_hdr *hdr = (struct be_cmd_req_hdr *) va;
++
++	spin_lock_bh(&adapter->mcc_lock);
++
++	wrb = wrb_from_mccq(adapter);
++	if (!wrb) {
++		status = -EBUSY;
++		goto err;
++	}
++	sge = nonembedded_sgl(wrb);
++
++	be_wrb_hdr_prepare(wrb, req_size, false, 1, hdr->opcode);
++	wrb->tag1 = MCC_WRB_PASS_THRU;
++	sge->pa_hi = cpu_to_le32(upper_32_bits(dma));
++	sge->pa_lo = cpu_to_le32(dma & 0xFFFFFFFF);
++	sge->len = cpu_to_le32(req_size);
++
++	status = be_mcc_notify_wait(adapter);
++err:
+ 	spin_unlock_bh(&adapter->mcc_lock);
+ 	return status;
+ }
++#endif
+diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
+index ad33d55..35aa5c7 100644
+--- a/drivers/net/benet/be_cmds.h
++++ b/drivers/net/benet/be_cmds.h
+@@ -1,20 +1,23 @@
+ /*
+- * Copyright (C) 2005 - 2009 ServerEngines
++ * Copyright (C) 2005 - 2011 Emulex
+  * All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation.  The full GNU General
++ * as published by the Free Software Foundation. The full GNU General
+  * Public License is included in this distribution in the file called COPYING.
+  *
+  * Contact Information:
+- * linux-drivers@serverengines.com
++ * linux-drivers@emulex.com
+  *
+- * ServerEngines
+- * 209 N. Fair Oaks Ave
+- * Sunnyvale, CA 94085
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
+  */
  
--static struct iwl_ops iwl4965_ops = {
-+static const struct iwl_ops iwl4965_ops = {
- 	.ucode = &iwl4965_ucode,
- 	.lib = &iwl4965_lib,
- 	.hcmd = &iwl4965_hcmd,
-diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
-index 1f423f2..e37c192 100644
---- a/drivers/net/wireless/iwlwifi/iwl-5000.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
-@@ -1633,14 +1633,14 @@ static struct iwl_lib_ops iwl5150_lib = {
- 	 },
++#ifndef BE_CMDS_H
++#define BE_CMDS_H
++
+ /*
+  * The driver sends configuration and managements command requests to the
+  * firmware in the BE. These requests are communicated to the processor
+@@ -29,9 +32,10 @@ struct be_sge {
+ 	u32 len;
+ };
+ 
+-#define MCC_WRB_EMBEDDED_MASK	1 	/* bit 0 of dword 0*/
++#define MCC_WRB_EMBEDDED_MASK	1	/* bit 0 of dword 0*/
+ #define MCC_WRB_SGE_CNT_SHIFT	3	/* bits 3 - 7 of dword 0 */
+ #define MCC_WRB_SGE_CNT_MASK	0x1F	/* bits 3 - 7 of dword 0 */
++#define MCC_WRB_PASS_THRU	0xFF	/* this wrb is used for pass thru cmd */
+ struct be_mcc_wrb {
+ 	u32 embedded;		/* dword 0 */
+ 	u32 payload_length;	/* dword 1 */
+@@ -44,24 +48,19 @@ struct be_mcc_wrb {
+ 	} payload;
+ };
+ 
+-#define CQE_FLAGS_VALID_MASK 		(1 << 31)
+-#define CQE_FLAGS_ASYNC_MASK 		(1 << 30)
+-#define CQE_FLAGS_COMPLETED_MASK 	(1 << 28)
+-#define CQE_FLAGS_CONSUMED_MASK 	(1 << 27)
++#define CQE_FLAGS_VALID_MASK		(1 << 31)
++#define CQE_FLAGS_ASYNC_MASK		(1 << 30)
++#define CQE_FLAGS_COMPLETED_MASK	(1 << 28)
++#define CQE_FLAGS_CONSUMED_MASK		(1 << 27)
+ 
+ /* Completion Status */
+ enum {
+-	MCC_STATUS_SUCCESS = 0x0,
+-/* The client does not have sufficient privileges to execute the command */
+-	MCC_STATUS_INSUFFICIENT_PRIVILEGES = 0x1,
+-/* A parameter in the command was invalid. */
+-	MCC_STATUS_INVALID_PARAMETER = 0x2,
+-/* There are insufficient chip resources to execute the command */
+-	MCC_STATUS_INSUFFICIENT_RESOURCES = 0x3,
+-/* The command is completing because the queue was getting flushed */
+-	MCC_STATUS_QUEUE_FLUSHING = 0x4,
+-/* The command is completing with a DMA error */
+-	MCC_STATUS_DMA_FAILED = 0x5,
++	MCC_STATUS_SUCCESS = 0,
++	MCC_STATUS_FAILED = 1,
++	MCC_STATUS_ILLEGAL_REQUEST = 2,
++	MCC_STATUS_ILLEGAL_FIELD = 3,
++	MCC_STATUS_INSUFFICIENT_BUFFER = 4,
++	MCC_STATUS_UNAUTHORIZED_REQUEST = 5,
+ 	MCC_STATUS_NOT_SUPPORTED = 66
+ };
+ 
+@@ -81,15 +80,24 @@ struct be_mcc_compl {
+  * mcc_compl is interpreted as follows:
+  */
+ #define ASYNC_TRAILER_EVENT_CODE_SHIFT	8	/* bits 8 - 15 */
++#define ASYNC_TRAILER_EVENT_TYPE_SHIFT	16	/* bits 16 - 23 */
+ #define ASYNC_TRAILER_EVENT_CODE_MASK	0xFF
++#define ASYNC_TRAILER_EVENT_TYPE_MASK	0xFF
+ #define ASYNC_EVENT_CODE_LINK_STATE	0x1
++#define ASYNC_EVENT_CODE_GRP_5		0x5
++#define ASYNC_EVENT_QOS_SPEED		0x1
++#define ASYNC_EVENT_COS_PRIORITY	0x2
++#define ASYNC_EVENT_PVID_STATE		0x3
++#define GRP5_TYPE_PRIO_TC_MAP		4
++
+ struct be_async_event_trailer {
+ 	u32 code;
  };
  
--struct iwl_ops iwl5000_ops = {
-+const struct iwl_ops iwl5000_ops = {
- 	.ucode = &iwl5000_ucode,
- 	.lib = &iwl5000_lib,
- 	.hcmd = &iwl5000_hcmd,
- 	.utils = &iwl5000_hcmd_utils,
+ enum {
+-	ASYNC_EVENT_LINK_DOWN 	= 0x0,
+-	ASYNC_EVENT_LINK_UP 	= 0x1
++	ASYNC_EVENT_LINK_DOWN	= 0x0,
++	ASYNC_EVENT_LINK_UP	= 0x1,
++	ASYNC_EVENT_LOGICAL	= 0x2
+ };
+ 
+ /* When the event code of an async trailer is link-state, the mcc_compl
+@@ -101,7 +109,51 @@ struct be_async_event_link_state {
+ 	u8 port_duplex;
+ 	u8 port_speed;
+ 	u8 port_fault;
+-	u8 rsvd0[7];
++	u8 rsvd0;
++	u16 qos_link_speed;
++	u32 event_tag;
++	struct be_async_event_trailer trailer;
++} __packed;
++
++/* When the event code of an async trailer is GRP-5 and event_type is QOS_SPEED
++ * the mcc_compl must be interpreted as follows
++ */
++struct be_async_event_grp5_qos_link_speed {
++	u8 physical_port;
++	u8 rsvd[5];
++	u16 qos_link_speed;
++	u32 event_tag;
++	struct be_async_event_trailer trailer;
++} __packed;
++
++/* When the event code of an async trailer is GRP5 and event type is
++ * CoS-Priority, the mcc_compl must be interpreted as follows
++ */
++struct be_async_event_grp5_cos_priority {
++	u8 physical_port;
++	u8 available_priority_bmap;
++	u8 reco_default_priority;
++	u8 valid;
++	u8 rsvd0;
++	u8 event_tag;
++	struct be_async_event_trailer trailer;
++} __packed;
++
++/* When the event code of an async trailer is GRP5 and event type is
++ * PVID state, the mcc_compl must be interpreted as follows
++ */
++struct be_async_event_grp5_pvid_state {
++	u8 enabled;
++	u8 rsvd0;
++	u16 tag;
++	u32 event_tag;
++	u32 rsvd1;
++	struct be_async_event_trailer trailer;
++} __packed;
++
++/* GRP5 prio-tc-map event */
++struct be_async_event_grp5_prio_tc_map {
++	u8 prio_tc_map[8];	/* map[prio] -> tc_id */
+ 	struct be_async_event_trailer trailer;
+ } __packed;
+ 
+@@ -111,41 +163,68 @@ struct be_mcc_mailbox {
+ };
+ 
+ #define CMD_SUBSYSTEM_COMMON	0x1
+-#define CMD_SUBSYSTEM_ETH 	0x3
++#define CMD_SUBSYSTEM_ETH	0x3
++#define CMD_SUBSYSTEM_LOWLEVEL	0xb
+ 
+ #define OPCODE_COMMON_NTWK_MAC_QUERY			1
+ #define OPCODE_COMMON_NTWK_MAC_SET			2
+ #define OPCODE_COMMON_NTWK_MULTICAST_SET		3
+-#define OPCODE_COMMON_NTWK_VLAN_CONFIG  		4
++#define OPCODE_COMMON_NTWK_VLAN_CONFIG			4
+ #define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY		5
++#define OPCODE_COMMON_READ_FLASHROM			6
+ #define OPCODE_COMMON_WRITE_FLASHROM			7
+ #define OPCODE_COMMON_CQ_CREATE				12
+ #define OPCODE_COMMON_EQ_CREATE				13
+-#define OPCODE_COMMON_MCC_CREATE        		21
+-#define OPCODE_COMMON_NTWK_RX_FILTER    		34
++#define OPCODE_COMMON_MCC_CREATE			21
++#define OPCODE_COMMON_SET_QOS				28
++#define OPCODE_COMMON_MCC_CREATE_EXT			90
++#define OPCODE_COMMON_SEEPROM_READ			30
++#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES		32
++#define OPCODE_COMMON_NTWK_RX_FILTER			34
+ #define OPCODE_COMMON_GET_FW_VERSION			35
+ #define OPCODE_COMMON_SET_FLOW_CONTROL			36
+ #define OPCODE_COMMON_GET_FLOW_CONTROL			37
+ #define OPCODE_COMMON_SET_FRAME_SIZE			39
+ #define OPCODE_COMMON_MODIFY_EQ_DELAY			41
+ #define OPCODE_COMMON_FIRMWARE_CONFIG			42
+-#define OPCODE_COMMON_NTWK_INTERFACE_CREATE 		50
+-#define OPCODE_COMMON_NTWK_INTERFACE_DESTROY 		51
+-#define OPCODE_COMMON_MCC_DESTROY        		53
+-#define OPCODE_COMMON_CQ_DESTROY        		54
+-#define OPCODE_COMMON_EQ_DESTROY        		55
++#define OPCODE_COMMON_NTWK_INTERFACE_CREATE		50
++#define OPCODE_COMMON_NTWK_INTERFACE_DESTROY		51
++#define OPCODE_COMMON_MCC_DESTROY			53
++#define OPCODE_COMMON_CQ_DESTROY			54
++#define OPCODE_COMMON_EQ_DESTROY			55
++#define OPCODE_COMMON_NTWK_SET_LINK_SPEED		57
+ #define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG		58
+ #define OPCODE_COMMON_NTWK_PMAC_ADD			59
+ #define OPCODE_COMMON_NTWK_PMAC_DEL			60
+ #define OPCODE_COMMON_FUNCTION_RESET			61
++#define OPCODE_COMMON_MANAGE_FAT			68
++#define OPCODE_COMMON_ENABLE_DISABLE_BEACON		69
++#define OPCODE_COMMON_GET_BEACON_STATE			70
++#define OPCODE_COMMON_READ_TRANSRECV_DATA		73
++#define OPCODE_COMMON_GET_PORT_NAME			77
++#define OPCODE_COMMON_SET_FN_PRIVILEGES			100
++#define OPCODE_COMMON_GET_PHY_DETAILS			102
++#define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP		103
++#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES	121
++#define OPCODE_COMMON_NTWK_GET_LINK_SPEED               134
++#define OPCODE_COMMON_GET_HSW_CONFIG			152
++#define OPCODE_COMMON_SET_HSW_CONFIG			153
++#define OPCODE_COMMON_GET_FN_PRIVILEGES			170
+ 
++#define OPCODE_ETH_RSS_CONFIG				1
+ #define OPCODE_ETH_ACPI_CONFIG				2
+ #define OPCODE_ETH_PROMISCUOUS				3
+ #define OPCODE_ETH_GET_STATISTICS			4
+ #define OPCODE_ETH_TX_CREATE				7
+-#define OPCODE_ETH_RX_CREATE            		8
+-#define OPCODE_ETH_TX_DESTROY           		9
+-#define OPCODE_ETH_RX_DESTROY           		10
++#define OPCODE_ETH_RX_CREATE				8
++#define OPCODE_ETH_TX_DESTROY				9
++#define OPCODE_ETH_RX_DESTROY				10
++#define OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG		12
++#define OPCODE_ETH_PG_FEATURE_QUERY_REQUEST		23
++
++#define OPCODE_LOWLEVEL_HOST_DDR_DMA                    17
++#define OPCODE_LOWLEVEL_LOOPBACK_TEST                   18
++#define OPCODE_LOWLEVEL_SET_LOOPBACK_MODE		19
+ 
+ struct be_cmd_req_hdr {
+ 	u8 opcode;		/* dword 0 */
+@@ -159,7 +238,7 @@ struct be_cmd_req_hdr {
+ };
+ 
+ #define RESP_HDR_INFO_OPCODE_SHIFT	0	/* bits 0 - 7 */
+-#define RESP_HDR_INFO_SUBSYS_SHIFT	8 	/* bits 8 - 15 */
++#define RESP_HDR_INFO_SUBSYS_SHIFT	8	/* bits 8 - 15 */
+ struct be_cmd_resp_hdr {
+ 	u32 info;		/* dword 0 */
+ 	u32 status;		/* dword 1 */
+@@ -265,7 +344,7 @@ struct be_cmd_req_pmac_del {
+ /******************** Create CQ ***************************/
+ /* Pseudo amap definition in which each bit of the actual structure is defined
+  * as a byte: used to calculate offset/shift/mask of each field */
+-struct amap_cq_context {
++struct amap_cq_context_be {
+ 	u8 cidx[11];		/* dword 0*/
+ 	u8 rsvd0;		/* dword 0*/
+ 	u8 coalescwm[2];	/* dword 0*/
+@@ -288,11 +367,28 @@ struct amap_cq_context {
+ 	u8 rsvd5[32];		/* dword 3*/
+ } __packed;
+ 
++struct amap_cq_context_lancer {
++	u8 rsvd0[12];		/* dword 0*/
++	u8 coalescwm[2];	/* dword 0*/
++	u8 nodelay;		/* dword 0*/
++	u8 rsvd1[12];		/* dword 0*/
++	u8 count[2];		/* dword 0*/
++	u8 valid;		/* dword 0*/
++	u8 rsvd2;		/* dword 0*/
++	u8 eventable;		/* dword 0*/
++	u8 eqid[16];		/* dword 1*/
++	u8 rsvd3[15];		/* dword 1*/
++	u8 armed;		/* dword 1*/
++	u8 rsvd4[32];		/* dword 2*/
++	u8 rsvd5[32];		/* dword 3*/
++} __packed;
++
+ struct be_cmd_req_cq_create {
+ 	struct be_cmd_req_hdr hdr;
+ 	u16 num_pages;
+-	u16 rsvd0;
+-	u8 context[sizeof(struct amap_cq_context) / 8];
++	u8 page_size;
++	u8 rsvd0;
++	u8 context[sizeof(struct amap_cq_context_be) / 8];
+ 	struct phys_addr pages[8];
+ } __packed;
+ 
+@@ -302,10 +398,28 @@ struct be_cmd_resp_cq_create {
+ 	u16 rsvd0;
+ } __packed;
+ 
++struct be_cmd_req_get_fat {
++	struct be_cmd_req_hdr hdr;
++	u32 fat_operation;
++	u32 read_log_offset;
++	u32 read_log_length;
++	u32 data_buffer_size;
++	u32 data_buffer[1];
++} __packed;
++
++struct be_cmd_resp_get_fat {
++	struct be_cmd_resp_hdr hdr;
++	u32 log_size;
++	u32 read_log_length;
++	u32 rsvd[2];
++	u32 data_buffer[1];
++} __packed;
++
++
+ /******************** Create MCCQ ***************************/
+ /* Pseudo amap definition in which each bit of the actual structure is defined
+  * as a byte: used to calculate offset/shift/mask of each field */
+-struct amap_mcc_context {
++struct amap_mcc_context_be {
+ 	u8 con_index[14];
+ 	u8 rsvd0[2];
+ 	u8 ring_size[4];
+@@ -320,11 +434,31 @@ struct amap_mcc_context {
+ 	u8 rsvd2[32];
+ } __packed;
+ 
++struct amap_mcc_context_lancer {
++	u8 async_cq_id[16];
++	u8 ring_size[4];
++	u8 rsvd0[12];
++	u8 rsvd1[31];
++	u8 valid;
++	u8 async_cq_valid[1];
++	u8 rsvd2[31];
++	u8 rsvd3[32];
++} __packed;
++
+ struct be_cmd_req_mcc_create {
+ 	struct be_cmd_req_hdr hdr;
+ 	u16 num_pages;
+-	u16 rsvd0;
+-	u8 context[sizeof(struct amap_mcc_context) / 8];
++	u16 cq_id;
++	u8 context[sizeof(struct amap_mcc_context_be) / 8];
++	struct phys_addr pages[8];
++} __packed;
++
++struct be_cmd_req_mcc_ext_create {
++	struct be_cmd_req_hdr hdr;
++	u16 num_pages;
++	u16 cq_id;
++	u32 async_event_bitmap[1];
++	u8 context[sizeof(struct amap_mcc_context_be) / 8];
+ 	struct phys_addr pages[8];
+ } __packed;
+ 
+@@ -335,49 +469,32 @@ struct be_cmd_resp_mcc_create {
+ } __packed;
+ 
+ /******************** Create TxQ ***************************/
+-#define BE_ETH_TX_RING_TYPE_STANDARD    	2
++#define ETX_QUEUE_TYPE_STANDARD			0x2
++#define ETX_QUEUE_TYPE_PRIORITY			0x10
+ #define BE_ULP1_NUM				1
+ 
+-/* Pseudo amap definition in which each bit of the actual structure is defined
+- * as a byte: used to calculate offset/shift/mask of each field */
+-struct amap_tx_context {
+-	u8 rsvd0[16];		/* dword 0 */
+-	u8 tx_ring_size[4];	/* dword 0 */
+-	u8 rsvd1[26];		/* dword 0 */
+-	u8 pci_func_id[8];	/* dword 1 */
+-	u8 rsvd2[9];		/* dword 1 */
+-	u8 ctx_valid;		/* dword 1 */
+-	u8 cq_id_send[16];	/* dword 2 */
+-	u8 rsvd3[16];		/* dword 2 */
+-	u8 rsvd4[32];		/* dword 3 */
+-	u8 rsvd5[32];		/* dword 4 */
+-	u8 rsvd6[32];		/* dword 5 */
+-	u8 rsvd7[32];		/* dword 6 */
+-	u8 rsvd8[32];		/* dword 7 */
+-	u8 rsvd9[32];		/* dword 8 */
+-	u8 rsvd10[32];		/* dword 9 */
+-	u8 rsvd11[32];		/* dword 10 */
+-	u8 rsvd12[32];		/* dword 11 */
+-	u8 rsvd13[32];		/* dword 12 */
+-	u8 rsvd14[32];		/* dword 13 */
+-	u8 rsvd15[32];		/* dword 14 */
+-	u8 rsvd16[32];		/* dword 15 */
+-} __packed;
+-
+ struct be_cmd_req_eth_tx_create {
+ 	struct be_cmd_req_hdr hdr;
+ 	u8 num_pages;
+ 	u8 ulp_num;
+-	u8 type;
+-	u8 bound_port;
+-	u8 context[sizeof(struct amap_tx_context) / 8];
++	u16 type;
++	u16 if_id;
++	u8 queue_size;
++	u8 rsvd1;
++	u32 rsvd2;
++	u16 cq_id;
++	u16 rsvd3;
++	u32 rsvd4[13];
+ 	struct phys_addr pages[8];
+ } __packed;
+ 
+ struct be_cmd_resp_eth_tx_create {
+ 	struct be_cmd_resp_hdr hdr;
+ 	u16 cid;
+-	u16 rsvd0;
++	u16 rid;
++	u32 db_offset;
++	u8 tc_id;
++	u8 rsvd0[3];
+ } __packed;
+ 
+ /******************** Create RxQ ***************************/
+@@ -396,7 +513,7 @@ struct be_cmd_req_eth_rx_create {
+ struct be_cmd_resp_eth_rx_create {
+ 	struct be_cmd_resp_hdr hdr;
+ 	u16 id;
+-	u8 cpu_id;
++	u8 rss_id;
+ 	u8 rsvd0;
+ } __packed;
+ 
+@@ -429,14 +546,15 @@ enum be_if_flags {
+ 	BE_IF_FLAGS_VLAN = 0x100,
+ 	BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200,
+ 	BE_IF_FLAGS_PASS_L2_ERRORS = 0x400,
+-	BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800
++	BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800,
++	BE_IF_FLAGS_MULTICAST = 0x1000
+ };
+ 
+ /* An RX interface is an object with one or more MAC addresses and
+  * filtering capabilities. */
+ struct be_cmd_req_if_create {
+ 	struct be_cmd_req_hdr hdr;
+-	u32 version;		/* ignore currntly */
++	u32 version;		/* ignore currently */
+ 	u32 capability_flags;
+ 	u32 enable_flags;
+ 	u8 mac_addr[ETH_ALEN];
+@@ -458,7 +576,7 @@ struct be_cmd_req_if_destroy {
+ };
+ 
+ /*************** HW Stats Get **********************************/
+-struct be_port_rxf_stats {
++struct be_port_rxf_stats_v0 {
+ 	u32 rx_bytes_lsd;	/* dword 0*/
+ 	u32 rx_bytes_msd;	/* dword 1*/
+ 	u32 rx_total_frames;	/* dword 2*/
+@@ -527,8 +645,8 @@ struct be_port_rxf_stats {
+ 	u32 rx_input_fifo_overflow;	/* dword 65*/
+ };
+ 
+-struct be_rxf_stats {
+-	struct be_port_rxf_stats port[2];
++struct be_rxf_stats_v0 {
++	struct be_port_rxf_stats_v0 port[2];
+ 	u32 rx_drops_no_pbuf;	/* dword 132*/
+ 	u32 rx_drops_no_txpb;	/* dword 133*/
+ 	u32 rx_drops_no_erx_descr;	/* dword 134*/
+@@ -545,31 +663,51 @@ struct be_rxf_stats {
+ 	u32 rx_drops_invalid_ring;	/* dword 145*/
+ 	u32 forwarded_packets;	/* dword 146*/
+ 	u32 rx_drops_mtu;	/* dword 147*/
+-	u32 rsvd0[15];
++	u32 rsvd0[7];
++	u32 port0_jabber_events;
++	u32 port1_jabber_events;
++	u32 rsvd1[6];
+ };
+ 
+-struct be_erx_stats {
++struct be_erx_stats_v0 {
+ 	u32 rx_drops_no_fragments[44];     /* dwordS 0 to 43*/
+-	u32 debug_wdma_sent_hold;          /* dword 44*/
+-	u32 debug_wdma_pbfree_sent_hold;   /* dword 45*/
+-	u32 debug_wdma_zerobyte_pbfree_sent_hold; /* dword 46*/
+-	u32 debug_pmem_pbuf_dealloc;       /* dword 47*/
++	u32 rsvd[4];
+ };
+ 
+-struct be_hw_stats {
+-	struct be_rxf_stats rxf;
++struct be_pmem_stats {
++	u32 eth_red_drops;
++	u32 rsvd[5];
++};
++
++struct be_hw_stats_v0 {
++	struct be_rxf_stats_v0 rxf;
+ 	u32 rsvd[48];
+-	struct be_erx_stats erx;
++	struct be_erx_stats_v0 erx;
++	struct be_pmem_stats pmem;
  };
  
--static struct iwl_ops iwl5150_ops = {
-+static const struct iwl_ops iwl5150_ops = {
- 	.ucode = &iwl5000_ucode,
- 	.lib = &iwl5150_lib,
- 	.hcmd = &iwl5000_hcmd,
-diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
-index 1473452..f07d5e1 100644
---- a/drivers/net/wireless/iwlwifi/iwl-6000.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
-@@ -146,7 +146,7 @@ static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
- 	.calc_rssi = iwl5000_calc_rssi,
+-struct be_cmd_req_get_stats {
++struct be_cmd_req_get_stats_v0 {
+ 	struct be_cmd_req_hdr hdr;
+-	u8 rsvd[sizeof(struct be_hw_stats)];
++	u8 rsvd[sizeof(struct be_hw_stats_v0)];
  };
  
--static struct iwl_ops iwl6000_ops = {
-+static const struct iwl_ops iwl6000_ops = {
- 	.ucode = &iwl5000_ucode,
- 	.lib = &iwl6000_lib,
- 	.hcmd = &iwl5000_hcmd,
-diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
-index 1a3dfa2..b3e0a61 100644
---- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
-@@ -857,6 +857,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
- 	u8 active_index = 0;
- 	s32 tpt = 0;
- 
-+	pax_track_stack();
+-struct be_cmd_resp_get_stats {
++struct be_cmd_resp_get_stats_v0 {
+ 	struct be_cmd_resp_hdr hdr;
+-	struct be_hw_stats hw_stats;
++	struct be_hw_stats_v0 hw_stats;
++};
 +
- 	IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
- 
- 	if (!ieee80211_is_data(hdr->frame_control) ||
-@@ -2722,6 +2724,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
- 	u8 valid_tx_ant = 0;
- 	struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq;
- 
-+	pax_track_stack();
++struct be_cmd_req_get_cntl_addnl_attribs {
++	struct be_cmd_req_hdr hdr;
++	u8 rsvd[8];
++};
 +
- 	/* Override starting rate (index 0) if needed for debug purposes */
- 	rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
- 
-diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
-index 0e56d78..6a3c107 100644
---- a/drivers/net/wireless/iwlwifi/iwl-agn.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
-@@ -2911,7 +2911,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
- 		if (iwl_debug_level & IWL_DL_INFO)
- 			dev_printk(KERN_DEBUG, &(pdev->dev),
- 				   "Disabling hw_scan\n");
--		iwl_hw_ops.hw_scan = NULL;
-+		pax_open_kernel();
-+		*(void **)&iwl_hw_ops.hw_scan = NULL;
-+		pax_close_kernel();
- 	}
++struct be_cmd_resp_get_cntl_addnl_attribs {
++	struct be_cmd_resp_hdr hdr;
++	u16 ipl_file_number;
++	u8 ipl_file_version;
++	u8 rsvd0;
++	u8 on_die_temperature; /* in degrees centigrade*/
++	u8 rsvd1[3];
+ };
+ 
+ struct be_cmd_req_vlan_config {
+@@ -581,30 +719,22 @@ struct be_cmd_req_vlan_config {
+ 	u16 normal_vlan[64];
+ } __packed;
+ 
+-struct be_cmd_req_promiscuous_config {
+-	struct be_cmd_req_hdr hdr;
+-	u8 port0_promiscuous;
+-	u8 port1_promiscuous;
+-	u16 rsvd0;
+-} __packed;
+-
++/******************** RX FILTER ******************************/
++#define BE_MAX_MC		64 /* set mcast promisc if > 64 */
+ struct macaddr {
+ 	u8 byte[ETH_ALEN];
+ };
+ 
+-struct be_cmd_req_mcast_mac_config {
++struct be_cmd_req_rx_filter {
+ 	struct be_cmd_req_hdr hdr;
+-	u16 num_mac;
+-	u8 promiscuous;
+-	u8 interface_id;
+-	struct macaddr mac[32];
+-} __packed;
+-
+-static inline struct be_hw_stats *
+-hw_stats_from_cmd(struct be_cmd_resp_get_stats *cmd)
+-{
+-	return &cmd->hw_stats;
+-}
++	u32 global_flags_mask;
++	u32 global_flags;
++	u32 if_flags_mask;
++	u32 if_flags;
++	u32 if_id;
++	u32 mcast_num;
++	struct macaddr mcast_mac[BE_MAX_MC];
++};
  
- 	hw = iwl_alloc_all(cfg, &iwl_hw_ops);
-diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
-index cbc6290..eb323d7 100644
---- a/drivers/net/wireless/iwlwifi/iwl-debug.h
-+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
-@@ -118,8 +118,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv);
- #endif
+ /******************** Link Status Query *******************/
+ struct be_cmd_req_link_status {
+@@ -619,13 +749,18 @@ enum {
+ };
  
- #else
--#define IWL_DEBUG(__priv, level, fmt, args...)
--#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
-+#define IWL_DEBUG(__priv, level, fmt, args...) do {} while (0)
-+#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) do {} while (0)
- static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
- 				      void *p, u32 len)
- {}
-diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
-index a198bcf..8e68233 100644
---- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
-@@ -524,6 +524,8 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
- 	int pos = 0;
- 	const size_t bufsz = sizeof(buf);
+ enum {
+-	PHY_LINK_SPEED_ZERO = 0x0, 	/* => No link */
++	PHY_LINK_SPEED_ZERO = 0x0,	/* => No link */
+ 	PHY_LINK_SPEED_10MBPS = 0x1,
+ 	PHY_LINK_SPEED_100MBPS = 0x2,
+ 	PHY_LINK_SPEED_1GBPS = 0x3,
+ 	PHY_LINK_SPEED_10GBPS = 0x4
+ };
  
-+	pax_track_stack();
++enum {
++	LINK_DOWN = 0x0,
++	LINK_UP = 0X1
++};
 +
- 	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
- 		test_bit(STATUS_HCMD_ACTIVE, &priv->status));
- 	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n",
-@@ -658,6 +660,8 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
- 	const size_t bufsz = sizeof(buf);
- 	ssize_t ret;
- 
-+	pax_track_stack();
+ struct be_cmd_resp_link_status {
+ 	struct be_cmd_resp_hdr hdr;
+ 	u8 physical_port;
+@@ -634,9 +769,47 @@ struct be_cmd_resp_link_status {
+ 	u8 mac_fault;
+ 	u8 mgmt_mac_duplex;
+ 	u8 mgmt_mac_speed;
+-	u16 rsvd0;
++	u16 link_speed;
++	u32 logical_link_status;
+ } __packed;
+ 
++/******************** Port Identification ***************************/
++/*    Identifies the type of port attached to NIC     */
++struct be_cmd_req_port_type {
++	struct be_cmd_req_hdr hdr;
++	u32 page_num;
++	u32 port;
++};
 +
- 	for (i = 0; i < AC_NUM; i++) {
- 		pos += scnprintf(buf + pos, bufsz - pos,
- 			"\tcw_min\tcw_max\taifsn\ttxop\n");
-diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
-index 3539ea4..b174bfa 100644
---- a/drivers/net/wireless/iwlwifi/iwl-dev.h
-+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
-@@ -68,7 +68,7 @@ struct iwl_tx_queue;
- 
- /* shared structures from iwl-5000.c */
- extern struct iwl_mod_params iwl50_mod_params;
--extern struct iwl_ops iwl5000_ops;
-+extern const struct iwl_ops iwl5000_ops;
- extern struct iwl_ucode_ops iwl5000_ucode;
- extern struct iwl_lib_ops iwl5000_lib;
- extern struct iwl_hcmd_ops iwl5000_hcmd;
-diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
-index 619590d..69235ee 100644
---- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
-+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
-@@ -3927,7 +3927,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
- 	 */
- 	if (iwl3945_mod_params.disable_hw_scan) {
- 		IWL_DEBUG_INFO(priv, "Disabling hw_scan\n");
--		iwl3945_hw_ops.hw_scan = NULL;
-+		pax_open_kernel();
-+		*(void **)&iwl3945_hw_ops.hw_scan = NULL;
-+		pax_close_kernel();
- 	}
- 
- 
-diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
-index 1465379..fe4d78b 100644
---- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
-+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
-@@ -299,6 +299,8 @@ static ssize_t iwm_debugfs_fw_err_read(struct file *filp,
- 	int buf_len = 512;
- 	size_t len = 0;
- 
-+	pax_track_stack();
++enum {
++	TR_PAGE_A0 = 0xa0,
++	TR_PAGE_A2 = 0xa2
++};
 +
- 	if (*ppos != 0)
- 		return 0;
- 	if (count < sizeof(buf))
-diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
-index 893a55c..7f66a50 100644
---- a/drivers/net/wireless/libertas/debugfs.c
-+++ b/drivers/net/wireless/libertas/debugfs.c
-@@ -708,7 +708,7 @@ out_unlock:
- struct lbs_debugfs_files {
- 	const char *name;
- 	int perm;
--	struct file_operations fops;
-+	const struct file_operations fops;
- };
- 
- static const struct lbs_debugfs_files debugfs_files[] = {
-diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
-index 2ecbedb..42704f0 100644
---- a/drivers/net/wireless/rndis_wlan.c
-+++ b/drivers/net/wireless/rndis_wlan.c
-@@ -1176,7 +1176,7 @@ static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold)
- 
- 	devdbg(usbdev, "set_rts_threshold %i", rts_threshold);
- 
--	if (rts_threshold < 0 || rts_threshold > 2347)
-+	if (rts_threshold > 2347)
- 		rts_threshold = 2347;
- 
- 	tmp = cpu_to_le32(rts_threshold);
-diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
-index 334ccd6..47f8944 100644
---- a/drivers/oprofile/buffer_sync.c
-+++ b/drivers/oprofile/buffer_sync.c
-@@ -342,7 +342,7 @@ static void add_data(struct op_entry *entry, struct mm_struct *mm)
- 		if (cookie == NO_COOKIE)
- 			offset = pc;
- 		if (cookie == INVALID_COOKIE) {
--			atomic_inc(&oprofile_stats.sample_lost_no_mapping);
-+			atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
- 			offset = pc;
- 		}
- 		if (cookie != last_cookie) {
-@@ -386,14 +386,14 @@ add_sample(struct mm_struct *mm, struct op_sample *s, int in_kernel)
- 	/* add userspace sample */
- 
- 	if (!mm) {
--		atomic_inc(&oprofile_stats.sample_lost_no_mm);
-+		atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mm);
- 		return 0;
- 	}
- 
- 	cookie = lookup_dcookie(mm, s->eip, &offset);
- 
- 	if (cookie == INVALID_COOKIE) {
--		atomic_inc(&oprofile_stats.sample_lost_no_mapping);
-+		atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
- 		return 0;
- 	}
- 
-@@ -562,7 +562,7 @@ void sync_buffer(int cpu)
- 		/* ignore backtraces if failed to add a sample */
- 		if (state == sb_bt_start) {
- 			state = sb_bt_ignore;
--			atomic_inc(&oprofile_stats.bt_lost_no_mapping);
-+			atomic_inc_unchecked(&oprofile_stats.bt_lost_no_mapping);
- 		}
- 	}
- 	release_mm(mm);
-diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c
-index 5df60a6..72f5c1c 100644
---- a/drivers/oprofile/event_buffer.c
-+++ b/drivers/oprofile/event_buffer.c
-@@ -53,7 +53,7 @@ void add_event_entry(unsigned long value)
- 	}
- 
- 	if (buffer_pos == buffer_size) {
--		atomic_inc(&oprofile_stats.event_lost_overflow);
-+		atomic_inc_unchecked(&oprofile_stats.event_lost_overflow);
- 		return;
- 	}
- 
-diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
-index dc8a042..fe5f315 100644
---- a/drivers/oprofile/oprof.c
-+++ b/drivers/oprofile/oprof.c
-@@ -110,7 +110,7 @@ static void switch_worker(struct work_struct *work)
- 	if (oprofile_ops.switch_events())
- 		return;
- 
--	atomic_inc(&oprofile_stats.multiplex_counter);
-+	atomic_inc_unchecked(&oprofile_stats.multiplex_counter);
- 	start_switch_worker();
- }
- 
-diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c
-index 61689e8..387f7f8 100644
---- a/drivers/oprofile/oprofile_stats.c
-+++ b/drivers/oprofile/oprofile_stats.c
-@@ -30,11 +30,11 @@ void oprofile_reset_stats(void)
- 		cpu_buf->sample_invalid_eip = 0;
- 	}
- 
--	atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
--	atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
--	atomic_set(&oprofile_stats.event_lost_overflow, 0);
--	atomic_set(&oprofile_stats.bt_lost_no_mapping, 0);
--	atomic_set(&oprofile_stats.multiplex_counter, 0);
-+	atomic_set_unchecked(&oprofile_stats.sample_lost_no_mm, 0);
-+	atomic_set_unchecked(&oprofile_stats.sample_lost_no_mapping, 0);
-+	atomic_set_unchecked(&oprofile_stats.event_lost_overflow, 0);
-+	atomic_set_unchecked(&oprofile_stats.bt_lost_no_mapping, 0);
-+	atomic_set_unchecked(&oprofile_stats.multiplex_counter, 0);
- }
- 
- 
-diff --git a/drivers/oprofile/oprofile_stats.h b/drivers/oprofile/oprofile_stats.h
-index 0b54e46..a37c527 100644
---- a/drivers/oprofile/oprofile_stats.h
-+++ b/drivers/oprofile/oprofile_stats.h
-@@ -13,11 +13,11 @@
- #include <asm/atomic.h>
- 
- struct oprofile_stat_struct {
--	atomic_t sample_lost_no_mm;
--	atomic_t sample_lost_no_mapping;
--	atomic_t bt_lost_no_mapping;
--	atomic_t event_lost_overflow;
--	atomic_t multiplex_counter;
-+	atomic_unchecked_t sample_lost_no_mm;
-+	atomic_unchecked_t sample_lost_no_mapping;
-+	atomic_unchecked_t bt_lost_no_mapping;
-+	atomic_unchecked_t event_lost_overflow;
-+	atomic_unchecked_t multiplex_counter;
- };
- 
- extern struct oprofile_stat_struct oprofile_stats;
-diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
-index 2766a6d..80c77e2 100644
---- a/drivers/oprofile/oprofilefs.c
-+++ b/drivers/oprofile/oprofilefs.c
-@@ -187,7 +187,7 @@ static const struct file_operations atomic_ro_fops = {
- 
- 
- int oprofilefs_create_ro_atomic(struct super_block *sb, struct dentry *root,
--	char const *name, atomic_t *val)
-+	char const *name, atomic_unchecked_t *val)
- {
- 	struct dentry *d = __oprofilefs_create_file(sb, root, name,
- 						     &atomic_ro_fops, 0444);
-diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
-index 13a64bc..ad62835 100644
---- a/drivers/parisc/pdc_stable.c
-+++ b/drivers/parisc/pdc_stable.c
-@@ -481,7 +481,7 @@ pdcspath_attr_store(struct kobject *kobj, struct attribute *attr,
- 	return ret;
- }
- 
--static struct sysfs_ops pdcspath_attr_ops = {
-+static const struct sysfs_ops pdcspath_attr_ops = {
- 	.show = pdcspath_attr_show,
- 	.store = pdcspath_attr_store,
- };
-diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
-index 8eefe56..40751a7 100644
---- a/drivers/parport/procfs.c
-+++ b/drivers/parport/procfs.c
-@@ -64,7 +64,7 @@ static int do_active_device(ctl_table *table, int write,
- 
- 	*ppos += len;
- 
--	return copy_to_user(result, buffer, len) ? -EFAULT : 0;
-+	return (len > sizeof buffer || copy_to_user(result, buffer, len)) ? -EFAULT : 0;
- }
- 
- #ifdef CONFIG_PARPORT_1284
-@@ -106,7 +106,7 @@ static int do_autoprobe(ctl_table *table, int write,
- 
- 	*ppos += len;
- 
--	return copy_to_user (result, buffer, len) ? -EFAULT : 0;
-+	return (len > sizeof buffer || copy_to_user (result, buffer, len)) ? -EFAULT : 0;
- }
- #endif /* IEEE1284.3 support. */
- 
-diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
-index 73e7d8e..c80f3d2 100644
---- a/drivers/pci/hotplug/acpiphp_glue.c
-+++ b/drivers/pci/hotplug/acpiphp_glue.c
-@@ -111,7 +111,7 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
- }
- 
- 
--static struct acpi_dock_ops acpiphp_dock_ops = {
-+static const struct acpi_dock_ops acpiphp_dock_ops = {
- 	.handler = handle_hotplug_event_func,
- };
- 
-diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
-index 9fff878..ad0ad53 100644
---- a/drivers/pci/hotplug/cpci_hotplug.h
-+++ b/drivers/pci/hotplug/cpci_hotplug.h
-@@ -59,7 +59,7 @@ struct cpci_hp_controller_ops {
- 	int (*hardware_test) (struct slot* slot, u32 value);
- 	u8  (*get_power) (struct slot* slot);
- 	int (*set_power) (struct slot* slot, int value);
--};
-+} __no_const;
- 
- struct cpci_hp_controller {
- 	unsigned int irq;
-diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
-index 76ba8a1..20ca857 100644
---- a/drivers/pci/hotplug/cpqphp_nvram.c
-+++ b/drivers/pci/hotplug/cpqphp_nvram.c
-@@ -428,9 +428,13 @@ static u32 store_HRT (void __iomem *rom_start)
- 
- void compaq_nvram_init (void __iomem *rom_start)
- {
++struct be_cmd_resp_port_type {
++	struct be_cmd_resp_hdr hdr;
++	u32 page_num;
++	u32 port;
++	struct data {
++		u8 identifier;
++		u8 identifier_ext;
++		u8 connector;
++		u8 transceiver[8];
++		u8 rsvd0[3];
++		u8 length_km;
++		u8 length_hm;
++		u8 length_om1;
++		u8 length_om2;
++		u8 length_cu;
++		u8 length_cu_m;
++		u8 vendor_name[16];
++		u8 rsvd;
++		u8 vendor_oui[3];
++		u8 vendor_pn[16];
++		u8 vendor_rev[4];
++	} data;
++};
 +
-+#ifndef CONFIG_PAX_KERNEXEC
- 	if (rom_start) {
- 		compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
- 	}
+ /******************** Get FW Version *******************/
+ struct be_cmd_req_get_fw_version {
+ 	struct be_cmd_req_hdr hdr;
+@@ -686,9 +859,13 @@ struct be_cmd_resp_modify_eq_delay {
+ } __packed;
+ 
+ /******************** Get FW Config *******************/
++#define FLEX10_MODE             0x400
++#define VNIC_MODE               0x20000
++#define UMC_ENABLED             0x1000000
++
+ struct be_cmd_req_query_fw_cfg {
+ 	struct be_cmd_req_hdr hdr;
+-	u32 rsvd[30];
++	u32 rsvd[31];
+ };
+ 
+ struct be_cmd_resp_query_fw_cfg {
+@@ -696,10 +873,61 @@ struct be_cmd_resp_query_fw_cfg {
+ 	u32 be_config_number;
+ 	u32 asic_revision;
+ 	u32 phys_port;
+-	u32 function_cap;
++	u32 function_mode;
+ 	u32 rsvd[26];
++	u32 function_caps;
+ };
+ 
++/******************** RSS Config *******************/
++/* RSS types */
++#define RSS_ENABLE_NONE				0x0
++#define RSS_ENABLE_IPV4				0x1
++#define RSS_ENABLE_TCP_IPV4			0x2
++#define RSS_ENABLE_IPV6				0x4
++#define RSS_ENABLE_TCP_IPV6			0x8
++
++struct be_cmd_req_rss_config {
++	struct be_cmd_req_hdr hdr;
++	u32 if_id;
++	u16 enable_rss;
++	u16 cpu_table_size_log2;
++	u32 hash[10];
++	u8 cpu_table[128];
++	u8 flush;
++	u8 rsvd0[3];
++};
++
++/******************** Port Beacon ***************************/
++
++#define BEACON_STATE_ENABLED		0x1
++#define BEACON_STATE_DISABLED		0x0
++
++struct be_cmd_req_enable_disable_beacon {
++	struct be_cmd_req_hdr hdr;
++	u8  port_num;
++	u8  beacon_state;
++	u8  beacon_duration;
++	u8  status_duration;
++} __packed;
++
++struct be_cmd_resp_enable_disable_beacon {
++	struct be_cmd_resp_hdr resp_hdr;
++	u32 rsvd0;
++} __packed;
++
++struct be_cmd_req_get_beacon_state {
++	struct be_cmd_req_hdr hdr;
++	u8  port_num;
++	u8  rsvd0;
++	u16 rsvd1;
++} __packed;
++
++struct be_cmd_resp_get_beacon_state {
++	struct be_cmd_resp_hdr resp_hdr;
++	u8 beacon_state;
++	u8 rsvd0[3];
++} __packed;
++
+ /****************** Firmware Flash ******************/
+ struct flashrom_params {
+ 	u32 op_code;
+@@ -714,17 +942,468 @@ struct be_cmd_write_flashrom {
+ 	struct flashrom_params params;
+ };
+ 
++/************************ WOL *******************************/
++struct be_cmd_req_acpi_wol_magic_config {
++	struct be_cmd_req_hdr hdr;
++	u32 rsvd0[145];
++	u8 magic_mac[6];
++	u8 rsvd2[2];
++} __packed;
++
++/********************** LoopBack test *********************/
++struct be_cmd_req_loopback_test {
++	struct be_cmd_req_hdr hdr;
++	u32 loopback_type;
++	u32 num_pkts;
++	u64 pattern;
++	u32 src_port;
++	u32 dest_port;
++	u32 pkt_size;
++};
++
++struct be_cmd_resp_loopback_test {
++	struct be_cmd_resp_hdr resp_hdr;
++	u32    status;
++	u32    num_txfer;
++	u32    num_rx;
++	u32    miscomp_off;
++	u32    ticks_compl;
++};
++
++struct be_cmd_req_set_lmode {
++	struct be_cmd_req_hdr hdr;
++	u8 src_port;
++	u8 dest_port;
++	u8 loopback_type;
++	u8 loopback_state;
++};
++
++struct be_cmd_resp_set_lmode {
++	struct be_cmd_resp_hdr resp_hdr;
++	u8 rsvd0[4];
++};
++
++/********************** DDR DMA test *********************/
++struct be_cmd_req_ddrdma_test {
++	struct be_cmd_req_hdr hdr;
++	u64 pattern;
++	u32 byte_count;
++	u32 rsvd0;
++	u8  snd_buff[4096];
++	u8  rsvd1[4096];
++};
++
++struct be_cmd_resp_ddrdma_test {
++	struct be_cmd_resp_hdr hdr;
++	u64 pattern;
++	u32 byte_cnt;
++	u32 snd_err;
++	u8  rsvd0[4096];
++	u8  rcv_buff[4096];
++};
++
++/*********************** SEEPROM Read ***********************/
++
++#define BE_READ_SEEPROM_LEN 1024
++struct be_cmd_req_seeprom_read {
++	struct be_cmd_req_hdr hdr;
++	u8 rsvd0[BE_READ_SEEPROM_LEN];
++};
++
++struct be_cmd_resp_seeprom_read {
++	struct be_cmd_req_hdr hdr;
++	u8 seeprom_data[BE_READ_SEEPROM_LEN];
++};
++
++enum {
++	PHY_TYPE_CX4_10GB = 0,
++	PHY_TYPE_XFP_10GB,
++	PHY_TYPE_SFP_1GB,
++	PHY_TYPE_SFP_PLUS_10GB,
++	PHY_TYPE_KR_10GB,
++	PHY_TYPE_KX4_10GB,
++	PHY_TYPE_BASET_10GB,
++	PHY_TYPE_BASET_1GB,
++	PHY_TYPE_BASEX_1GB,
++	PHY_TYPE_SGMII,
++	PHY_TYPE_DISABLED = 255
++};
++
++#define BE_AN_EN			0x2
++#define BE_PAUSE_SYM_EN			0x80
++
++struct be_cmd_req_get_phy_info {
++	struct be_cmd_req_hdr hdr;
++	u8 rsvd0[24];
++};
++
++struct be_phy_info {
++	u16 phy_type;
++	u16 interface_type;
++	u32 misc_params;
++	u16 ext_phy_details;
++	u16 rsvd;
++	u16 auto_speeds_supported;
++	u16 fixed_speeds_supported;
++	u32 future_use[2];
++};
++
++struct be_cmd_resp_get_phy_info {
++	struct be_cmd_req_hdr hdr;
++	struct be_phy_info phy_info;
++};
++
++/*********************** Set QOS ***********************/
++
++#define BE_QOS_BITS_NIC				1
++
++struct be_cmd_req_set_qos {
++	struct be_cmd_req_hdr hdr;
++	u32 valid_bits;
++	u32 max_bps_nic;
++	u32 rsvd[7];
++};
++
++struct be_cmd_resp_set_qos {
++	struct be_cmd_resp_hdr hdr;
++	u32 rsvd;
++};
++
++/*********************** Controller Attributes ***********************/
++struct be_cmd_req_cntl_attribs {
++	struct be_cmd_req_hdr hdr;
++};
++
++struct be_cmd_resp_cntl_attribs {
++	struct be_cmd_resp_hdr hdr;
++	struct mgmt_controller_attrib attribs;
++};
++
++/******************* get port names ***************/
++struct be_cmd_req_get_port_name {
++	struct be_cmd_req_hdr hdr;
++	u32 rsvd0;
++};
++
++struct be_cmd_resp_get_port_name {
++	struct be_cmd_req_hdr hdr;
++	u8 port0_name;
++	u8 port1_name;
++	u8 rsvd0[2];
++};
++
++struct be_cmd_resp_get_port_name_v1 {
++	struct be_cmd_req_hdr hdr;
++	u32 pt : 2;
++	u32 rsvd0 : 30;
++	u8 port0_name;
++	u8 port1_name;
++	u8 port2_name;
++	u8 port3_name;
++};
++
++/*********************** Set driver function ***********************/
++#define CAPABILITY_SW_TIMESTAMPS	2
++#define CAPABILITY_BE3_NATIVE_ERX_API	4
++
++struct be_cmd_req_set_func_cap {
++	struct be_cmd_req_hdr hdr;
++	u32 valid_cap_flags;
++	u32 cap_flags;
++	u8 rsvd[212];
++};
++
++struct be_cmd_resp_set_func_cap {
++	struct be_cmd_resp_hdr hdr;
++	u32 valid_cap_flags;
++	u32 cap_flags;
++	u8 rsvd[212];
++};
++
++/*********************** PG Query Request ****************************/
++#define REQ_PG_QUERY	0x1
++#define REQ_PG_FEAT	0x1
++struct be_cmd_req_pg {
++	struct be_cmd_req_hdr hdr;
++	u32 query;
++	u32 pfc_pg;
++};
++
++struct be_cmd_resp_pg {
++	struct be_cmd_resp_hdr hdr;
++	u32 pfc_pg;
++	u32 num_tx_rings;
++};
++
++/*********************** Function Privileges ***********************/
++enum {
++	BE_PRIV_DEFAULT = 0x1,
++	BE_PRIV_LNKQUERY = 0x2,
++	BE_PRIV_LNKSTATS = 0x4,
++	BE_PRIV_LNKMGMT = 0x8,
++	BE_PRIV_LNKDIAG = 0x10,
++	BE_PRIV_UTILQUERY = 0x20,
++	BE_PRIV_FILTMGMT = 0x40,
++	BE_PRIV_IFACEMGMT = 0x80,
++	BE_PRIV_VHADM = 0x100,
++	BE_PRIV_DEVCFG = 0x200,
++	BE_PRIV_DEVSEC = 0x400
++};
++
++struct be_cmd_req_get_fn_privileges {
++	struct be_cmd_req_hdr hdr;
++	u32 rsvd;
++};
++
++struct be_cmd_resp_get_fn_privileges {
++	struct be_cmd_resp_hdr hdr;
++	u32 privilege_mask;
++};
++
++struct be_cmd_req_set_fn_privileges {
++	struct be_cmd_req_hdr hdr;
++	u32 privilege_mask;
++};
++
++struct be_cmd_resp_set_fn_privileges {
++	struct be_cmd_resp_hdr hdr;
++	u32 prev_privilege_mask;
++};
++
++/*********************** HSW Config ***********************/
++struct amap_set_hsw_context {
++	u8 interface_id[16];
++	u8 rsvd0[14];
++	u8 pvid_valid;
++	u8 rsvd1;
++	u8 rsvd2[16];
++	u8 pvid[16];
++	u8 rsvd3[32];
++	u8 rsvd4[32];
++	u8 rsvd5[32];
++} __packed;
++
++struct be_cmd_req_set_hsw_config {
++	struct be_cmd_req_hdr hdr;
++	u8 context[sizeof(struct amap_set_hsw_context) / 8];
++} __packed;
++
++struct be_cmd_resp_set_hsw_config {
++	struct be_cmd_resp_hdr hdr;
++	u32 rsvd;
++};
++
++struct amap_get_hsw_req_context {
++	u8 interface_id[16];
++	u8 rsvd0[14];
++	u8 pvid_valid;
++	u8 pport;
++} __packed;
++
++struct amap_get_hsw_resp_context {
++	u8 rsvd1[16];
++	u8 pvid[16];
++	u8 rsvd2[32];
++	u8 rsvd3[32];
++	u8 rsvd4[32];
++} __packed;
++
++struct be_cmd_req_get_hsw_config {
++	struct be_cmd_req_hdr hdr;
++	u8 context[sizeof(struct amap_get_hsw_req_context) / 8];
++} __packed;
++
++struct be_cmd_resp_get_hsw_config {
++	struct be_cmd_resp_hdr hdr;
++	u8 context[sizeof(struct amap_get_hsw_resp_context) / 8];
++	u32 rsvd;
++};
++
++/*************** Set speed ********************/
++struct be_cmd_req_set_port_speed_v1 {
++	struct be_cmd_req_hdr hdr;
++	u8 port_num;
++	u8 virt_port;
++	u16 mac_speed;
++	u16 dac_cable_length;
++	u16 rsvd0;
++};
++	
++struct be_cmd_resp_set_port_speed_v1 {
++	struct be_cmd_resp_hdr hdr;
++	u32 rsvd0;
++};
++
++/************** get port speed *******************/
++struct be_cmd_req_get_port_speed {
++	struct be_cmd_req_hdr hdr;
++	u8 port_num;
++};
++
++struct be_cmd_resp_get_port_speed {
++	struct be_cmd_req_hdr hdr;
++	u16 mac_speed;
++	u16 dac_cable_length;
++};
++
++/*************** HW Stats Get v1 **********************************/
++#define BE_TXP_SW_SZ			48
++struct be_port_rxf_stats_v1 {
++	u32 rsvd0[12];
++	u32 rx_crc_errors;
++	u32 rx_alignment_symbol_errors;
++	u32 rx_pause_frames;
++	u32 rx_priority_pause_frames;
++	u32 rx_control_frames;
++	u32 rx_in_range_errors;
++	u32 rx_out_range_errors;
++	u32 rx_frame_too_long;
++	u32 rx_address_match_errors;
++	u32 rx_dropped_too_small;
++	u32 rx_dropped_too_short;
++	u32 rx_dropped_header_too_small;
++	u32 rx_dropped_tcp_length;
++	u32 rx_dropped_runt;
++	u32 rsvd1[10];
++	u32 rx_ip_checksum_errs;
++	u32 rx_tcp_checksum_errs;
++	u32 rx_udp_checksum_errs;
++	u32 rsvd2[7];
++	u32 rx_switched_unicast_packets;
++	u32 rx_switched_multicast_packets;
++	u32 rx_switched_broadcast_packets;
++	u32 rsvd3[3];
++	u32 tx_pauseframes;
++	u32 tx_priority_pauseframes;
++	u32 tx_controlframes;
++	u32 rsvd4[10];
++	u32 rxpp_fifo_overflow_drop;
++	u32 rx_input_fifo_overflow_drop;
++	u32 pmem_fifo_overflow_drop;
++	u32 jabber_events;
++	u32 rsvd5[3];
++};
++
++
++struct be_rxf_stats_v1 {
++	struct be_port_rxf_stats_v1 port[4];
++	u32 rsvd0[2];
++	u32 rx_drops_no_pbuf;
++	u32 rx_drops_no_txpb;
++	u32 rx_drops_no_erx_descr;
++	u32 rx_drops_no_tpre_descr;
++	u32 rsvd1[6];
++	u32 rx_drops_too_many_frags;
++	u32 rx_drops_invalid_ring;
++	u32 forwarded_packets;
++	u32 rx_drops_mtu;
++	u32 rsvd2[14];
++};
++
++struct be_erx_stats_v1 {
++	u32 rx_drops_no_fragments[68];     /* dwordS 0 to 67*/
++	u32 rsvd[4];
++};
++
++struct be_hw_stats_v1 {
++	struct be_rxf_stats_v1 rxf;
++	u32 rsvd0[BE_TXP_SW_SZ];
++	struct be_erx_stats_v1 erx;
++	struct be_pmem_stats pmem;
++	u32 rsvd1[3];
++};
++
++struct be_cmd_req_get_stats_v1 {
++	struct be_cmd_req_hdr hdr;
++	u8 rsvd[sizeof(struct be_hw_stats_v1)];
++};
++
++struct be_cmd_resp_get_stats_v1 {
++	struct be_cmd_resp_hdr hdr;
++	struct be_hw_stats_v1 hw_stats;
++};
++
++static inline void *
++hw_stats_from_cmd(struct be_adapter *adapter)
++{
++	if (adapter->generation == BE_GEN3) {
++		struct be_cmd_resp_get_stats_v1 *cmd = adapter->stats_cmd.va;
++
++		return &cmd->hw_stats;
++	} else {
++		struct be_cmd_resp_get_stats_v0 *cmd = adapter->stats_cmd.va;
++
++		return &cmd->hw_stats;
++	}
++}
++
++static inline void *be_port_rxf_stats_from_cmd(struct be_adapter *adapter)
++{
++	if (adapter->generation == BE_GEN3) {
++		struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
++		struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf;
++
++		return &rxf_stats->port[adapter->port_num];
++	} else {
++		struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
++		struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf;
++
++		return &rxf_stats->port[adapter->port_num];
++	}
++}
++
++static inline void *be_rxf_stats_from_cmd(struct be_adapter *adapter)
++{
++	if (adapter->generation == BE_GEN3) {
++		struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
++
++		return &hw_stats->rxf;
++	} else {
++		struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
++
++		return &hw_stats->rxf;
++	}
++}
++
++static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter)
++{
++	if (adapter->generation == BE_GEN3) {
++		struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
++
++		return &hw_stats->erx;
++	} else {
++		struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
++
++		return &hw_stats->erx;
++	}
++}
++
++static inline void *be_pmem_stats_from_cmd(struct be_adapter *adapter)
++{
++	if (adapter->generation == BE_GEN3) {
++		struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
++
++		return &hw_stats->pmem;
++	} else {
++		struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
++
++		return &hw_stats->pmem;
++	}
++}
++
+ extern int be_pci_fnum_get(struct be_adapter *adapter);
+ extern int be_cmd_POST(struct be_adapter *adapter);
+ extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
+ 			u8 type, bool permanent, u32 if_handle);
+ extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
+-			u32 if_id, u32 *pmac_id);
+-extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id);
++			u32 if_id, u32 *pmac_id, u32 domain);
++extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id,
++			u32 domain);
+ extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags,
+ 			u32 en_flags, u8 *mac, bool pmac_invalid,
+-			u32 *if_handle, u32 *pmac_id);
+-extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle);
++			u32 *if_handle, u32 *pmac_id, u32 domain);
++extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle,
++			u32 domain);
+ extern int be_cmd_eq_create(struct be_adapter *adapter,
+ 			struct be_queue_info *eq, int eq_delay);
+ extern int be_cmd_cq_create(struct be_adapter *adapter,
+@@ -736,36 +1415,92 @@ extern int be_cmd_mccq_create(struct be_adapter *adapter,
+ 			struct be_queue_info *cq);
+ extern int be_cmd_txq_create(struct be_adapter *adapter,
+ 			struct be_queue_info *txq,
+-			struct be_queue_info *cq);
++			struct be_queue_info *cq, u8 *tc_id);
+ extern int be_cmd_rxq_create(struct be_adapter *adapter,
+ 			struct be_queue_info *rxq, u16 cq_id,
+ 			u16 frag_size, u16 max_frame_size, u32 if_id,
+-			u32 rss);
++			u32 rss, u8 *rss_id);
+ extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
+ 			int type);
++extern int be_cmd_rxq_destroy(struct be_adapter *adapter,
++			struct be_queue_info *q);
+ extern int be_cmd_link_status_query(struct be_adapter *adapter,
+-			bool *link_up);
++			int *link_status, u8 *mac_speed, u16 *link_speed, u32 dom);
+ extern int be_cmd_reset(struct be_adapter *adapter);
+ extern int be_cmd_get_stats(struct be_adapter *adapter,
+ 			struct be_dma_mem *nonemb_cmd);
+-extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver);
++extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver,
++		char *fw_on_flash);
+ 
+ extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd);
+ extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
+ 			u16 *vtag_array, u32 num, bool untagged,
+ 			bool promiscuous);
+-extern int be_cmd_promiscuous_config(struct be_adapter *adapter,
+-			u8 port_num, bool en);
+-extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
+-			struct dev_mc_list *mc_list, u32 mc_count);
++extern int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 status);
+ extern int be_cmd_set_flow_control(struct be_adapter *adapter,
+ 			u32 tx_fc, u32 rx_fc);
+ extern int be_cmd_get_flow_control(struct be_adapter *adapter,
+ 			u32 *tx_fc, u32 *rx_fc);
+-extern int be_cmd_query_fw_cfg(struct be_adapter *adapter,
+-			u32 *port_num, u32 *cap);
++extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
++			u32 *function_mode, u32 *functions_caps);
+ extern int be_cmd_reset_function(struct be_adapter *adapter);
+-extern int be_process_mcc(struct be_adapter *adapter);
++extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
++			u16 table_size);
++extern int be_process_mcc(struct be_adapter *adapter, int *status);
++extern int be_cmd_set_beacon_state(struct be_adapter *adapter,
++			u8 port_num, u8 beacon, u8 status, u8 state);
++extern int be_cmd_get_beacon_state(struct be_adapter *adapter,
++			u8 port_num, u32 *state);
++extern int be_cmd_read_port_type(struct be_adapter *adapter, u32 port,
++					u8 *connector);
+ extern int be_cmd_write_flashrom(struct be_adapter *adapter,
+ 			struct be_dma_mem *cmd, u32 flash_oper,
+ 			u32 flash_opcode, u32 buf_size);
++int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
++				int offset);
++extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
++				struct be_dma_mem *nonemb_cmd);
++extern int be_cmd_fw_init(struct be_adapter *adapter);
++extern int be_cmd_fw_clean(struct be_adapter *adapter);
++extern void be_async_mcc_enable(struct be_adapter *adapter);
++extern void be_async_mcc_disable(struct be_adapter *adapter);
++extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
++				u32 loopback_type, u32 pkt_size,
++				u32 num_pkts, u64 pattern);
++extern int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
++			u32 byte_cnt, struct be_dma_mem *cmd);
++extern int be_cmd_get_seeprom_data(struct be_adapter *adapter,
++				struct be_dma_mem *nonemb_cmd);
++extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
++				u8 loopback_type, u8 enable);
++extern int be_cmd_get_phy_info(struct be_adapter *adapter,
++		struct be_phy_info *phy_info);
++extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain);
++extern void be_detect_dump_ue(struct be_adapter *adapter);
++extern int be_cmd_get_die_temperature(struct be_adapter *adapter);
++extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
++extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size);
++extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
++extern int be_cmd_req_native_mode(struct be_adapter *adapter);
++extern int be_cmd_query_port_names_v0(struct be_adapter *adapter, u8 *port_name);
++extern int be_cmd_query_port_names_v1(struct be_adapter *adapter, u8 *port_name);
++extern int be_cmd_req_pg_pfc(struct be_adapter *adapter, int *fw_num_txqs);
++
++extern int be_cmd_get_fn_privileges(struct be_adapter *adapter,
++				u32 *privilege, u32 domain);
++extern int be_cmd_set_fn_privileges(struct be_adapter *adapter,
++				u32 mask, u32 *prev, u32 domain);
++extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
++			u32 domain, u16 intf_id);
++extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
++			u32 domain, u16 intf_id);
++extern int be_cmd_set_port_speed_v1(struct be_adapter *adapter, u8 port_num,
++			u16 mac_speed, u16 dac_cable_len);
++extern int be_cmd_get_port_speed(struct be_adapter *adapter, u8 port_num,
++			u16 *dac_cable_len, u16 *port_speed);
++#ifdef CONFIG_PALAU
++int be_cmd_pass_ext_ioctl(struct be_adapter *adapter, dma_addr_t dma,
++			  int req_size, void *va);
++#endif
++
++#endif /* !BE_CMDS_H */
+diff --git a/drivers/net/benet/be_compat.c b/drivers/net/benet/be_compat.c
+new file mode 100644
+index 0000000..bdd1dba
+--- /dev/null
++++ b/drivers/net/benet/be_compat.c
+@@ -0,0 +1,630 @@
++/*
++ * Copyright (C) 2005 - 2011 Emulex
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation. The full GNU General
++ * Public License is included in this distribution in the file called COPYING.
++ *
++ * Contact Information:
++ * linux-drivers@emulex.com
++ *
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
++ */
++
++#include "be.h"
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
++void be_netdev_ops_init(struct net_device *netdev, struct net_device_ops *ops)
++{
++	netdev->open = ops->ndo_open;
++	netdev->stop = ops->ndo_stop;
++	netdev->hard_start_xmit = ops->ndo_start_xmit;
++	netdev->set_mac_address = ops->ndo_set_mac_address;
++	netdev->get_stats = ops->ndo_get_stats;
++	netdev->set_multicast_list = ops->ndo_set_rx_mode;
++	netdev->change_mtu = ops->ndo_change_mtu;
++	netdev->vlan_rx_register = ops->ndo_vlan_rx_register;
++	netdev->vlan_rx_add_vid = ops->ndo_vlan_rx_add_vid;
++	netdev->vlan_rx_kill_vid = ops->ndo_vlan_rx_kill_vid;
++	netdev->do_ioctl = ops->ndo_do_ioctl;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	netdev->poll_controller = ops->ndo_poll_controller;
++#endif
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
++	netdev->select_queue = ops->ndo_select_queue;
++#endif
++}
 +#endif
 +
- 	dbg("int15 entry  = %p\n", compaq_int15_entry_point);
- 
- 	/* initialize our int15 lock */
-diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
-index 6151389..0a894ef 100644
---- a/drivers/pci/hotplug/fakephp.c
-+++ b/drivers/pci/hotplug/fakephp.c
-@@ -73,7 +73,7 @@ static void legacy_release(struct kobject *kobj)
- }
- 
- static struct kobj_type legacy_ktype = {
--	.sysfs_ops = &(struct sysfs_ops){
-+	.sysfs_ops = &(const struct sysfs_ops){
- 		.store = legacy_store, .show = legacy_show
- 	},
- 	.release = &legacy_release,
-diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
-index 5b680df..fe05b7e 100644
---- a/drivers/pci/intel-iommu.c
-+++ b/drivers/pci/intel-iommu.c
-@@ -2643,7 +2643,7 @@ error:
- 	return 0;
- }
- 
--static dma_addr_t intel_map_page(struct device *dev, struct page *page,
-+dma_addr_t intel_map_page(struct device *dev, struct page *page,
- 				 unsigned long offset, size_t size,
- 				 enum dma_data_direction dir,
- 				 struct dma_attrs *attrs)
-@@ -2719,7 +2719,7 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova)
- 	spin_unlock_irqrestore(&async_umap_flush_lock, flags);
- }
- 
--static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
-+void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
- 			     size_t size, enum dma_data_direction dir,
- 			     struct dma_attrs *attrs)
- {
-@@ -2768,7 +2768,7 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
- 	}
- }
- 
--static void *intel_alloc_coherent(struct device *hwdev, size_t size,
-+void *intel_alloc_coherent(struct device *hwdev, size_t size,
- 				  dma_addr_t *dma_handle, gfp_t flags)
- {
- 	void *vaddr;
-@@ -2800,7 +2800,7 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,
- 	return NULL;
- }
- 
--static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-+void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
- 				dma_addr_t dma_handle)
- {
- 	int order;
-@@ -2812,7 +2812,7 @@ static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
- 	free_pages((unsigned long)vaddr, order);
- }
- 
--static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
-+void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
- 			   int nelems, enum dma_data_direction dir,
- 			   struct dma_attrs *attrs)
- {
-@@ -2872,7 +2872,7 @@ static int intel_nontranslate_map_sg(struct device *hddev,
- 	return nelems;
- }
- 
--static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
-+int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
- 			enum dma_data_direction dir, struct dma_attrs *attrs)
- {
- 	int i;
-@@ -2941,12 +2941,12 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne
- 	return nelems;
- }
- 
--static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
-+int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
- {
- 	return !dma_addr;
- }
- 
--struct dma_map_ops intel_dma_ops = {
-+const struct dma_map_ops intel_dma_ops = {
- 	.alloc_coherent = intel_alloc_coherent,
- 	.free_coherent = intel_free_coherent,
- 	.map_sg = intel_map_sg,
-diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
-index 5b7056c..607bc94 100644
---- a/drivers/pci/pcie/aspm.c
-+++ b/drivers/pci/pcie/aspm.c
-@@ -27,9 +27,9 @@
- #define MODULE_PARAM_PREFIX "pcie_aspm."
- 
- /* Note: those are not register definitions */
--#define ASPM_STATE_L0S_UP	(1)	/* Upstream direction L0s state */
--#define ASPM_STATE_L0S_DW	(2)	/* Downstream direction L0s state */
--#define ASPM_STATE_L1		(4)	/* L1 state */
-+#define ASPM_STATE_L0S_UP	(1U)	/* Upstream direction L0s state */
-+#define ASPM_STATE_L0S_DW	(2U)	/* Downstream direction L0s state */
-+#define ASPM_STATE_L1		(4U)	/* L1 state */
- #define ASPM_STATE_L0S		(ASPM_STATE_L0S_UP | ASPM_STATE_L0S_DW)
- #define ASPM_STATE_ALL		(ASPM_STATE_L0S | ASPM_STATE_L1)
- 
-diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
-index 8105e32..ca10419 100644
---- a/drivers/pci/probe.c
-+++ b/drivers/pci/probe.c
-@@ -62,14 +62,14 @@ static ssize_t pci_bus_show_cpuaffinity(struct device *dev,
- 	return ret;
- }
- 
--static ssize_t inline pci_bus_show_cpumaskaffinity(struct device *dev,
-+static inline ssize_t pci_bus_show_cpumaskaffinity(struct device *dev,
- 					struct device_attribute *attr,
- 					char *buf)
- {
- 	return pci_bus_show_cpuaffinity(dev, 0, attr, buf);
- }
- 
--static ssize_t inline pci_bus_show_cpulistaffinity(struct device *dev,
-+static inline ssize_t pci_bus_show_cpulistaffinity(struct device *dev,
- 					struct device_attribute *attr,
- 					char *buf)
- {
-diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
-index a03ad8c..024b0da 100644
---- a/drivers/pci/proc.c
-+++ b/drivers/pci/proc.c
-@@ -480,7 +480,16 @@ static const struct file_operations proc_bus_pci_dev_operations = {
- static int __init pci_proc_init(void)
- {
- 	struct pci_dev *dev = NULL;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
++int eth_validate_addr(struct net_device *netdev)
++{
++	return 0;
++}
++#endif
 +
-+#ifdef CONFIG_GRKERNSEC_PROC_ADD
-+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+	proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
-+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
-+	proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
++/* New NAPI backport */
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
++
++int be_poll_compat(struct net_device *netdev, int *budget)
++{
++	struct napi_struct *napi = netdev->priv;
++	u32 work_done, can_do;
++
++	can_do = min(*budget, netdev->quota);
++	work_done = napi->poll(napi, can_do);
++
++	*budget -= work_done;
++	netdev->quota -= work_done;
++	if (napi->rx)
++		return (work_done >= can_do);
++	return 0;
++}
++
++
++#endif /* New NAPI backport */
++
++int be_netif_napi_add(struct net_device *netdev,
++		struct napi_struct *napi,
++		int (*poll) (struct napi_struct *, int), int weight)
++{
++#ifdef HAVE_SIMULATED_MULTI_NAPI
++	struct be_adapter *adapter = netdev_priv(netdev);
++	struct net_device *nd;
++
++	nd = alloc_netdev(0, "", ether_setup);
++	if (!nd)
++		return -ENOMEM;
++	nd->priv = napi;
++	nd->weight = BE_NAPI_WEIGHT;
++	nd->poll = be_poll_compat;
++	set_bit(__LINK_STATE_START, &nd->state);
++
++	if (napi == &adapter->rx_obj[0].rx_eq.napi)
++		napi->rx = true;
++	napi->poll = poll;
++	napi->dev = nd;
++#ifdef RHEL_NEW_NAPI
++	napi->napi.dev = netdev;
 +#endif
++	return 0;
 +#else
- 	proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
++	netif_napi_add(netdev, napi, poll, weight);
++	return 0;
 +#endif
- 	proc_create("devices", 0, proc_bus_pci_dir,
- 		    &proc_bus_pci_dev_operations);
- 	proc_initialized = 1;
-diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
-index 8c02b6c..5584d8e 100644
---- a/drivers/pci/slot.c
-+++ b/drivers/pci/slot.c
-@@ -29,7 +29,7 @@ static ssize_t pci_slot_attr_store(struct kobject *kobj,
- 	return attribute->store ? attribute->store(slot, buf, len) : -EIO;
- }
- 
--static struct sysfs_ops pci_slot_sysfs_ops = {
-+static const struct sysfs_ops pci_slot_sysfs_ops = {
- 	.show = pci_slot_attr_show,
- 	.store = pci_slot_attr_store,
- };
-diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
-index 30cf71d2..50938f1 100644
---- a/drivers/pcmcia/pcmcia_ioctl.c
-+++ b/drivers/pcmcia/pcmcia_ioctl.c
-@@ -819,7 +819,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
- 	    return -EFAULT;
- 	}
-     }
--    buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
-+    buf = kzalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
-     if (!buf)
- 	return -ENOMEM;
- 
-diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
-index 52183c4..b224c69 100644
---- a/drivers/platform/x86/acer-wmi.c
-+++ b/drivers/platform/x86/acer-wmi.c
-@@ -918,7 +918,7 @@ static int update_bl_status(struct backlight_device *bd)
- 	return 0;
- }
- 
--static struct backlight_ops acer_bl_ops = {
-+static const struct backlight_ops acer_bl_ops = {
- 	.get_brightness = read_brightness,
- 	.update_status = update_bl_status,
- };
-diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
-index 767cb61..a87380b 100644
---- a/drivers/platform/x86/asus-laptop.c
-+++ b/drivers/platform/x86/asus-laptop.c
-@@ -250,7 +250,7 @@ static struct backlight_device *asus_backlight_device;
-  */
- static int read_brightness(struct backlight_device *bd);
- static int update_bl_status(struct backlight_device *bd);
--static struct backlight_ops asusbl_ops = {
-+static const struct backlight_ops asusbl_ops = {
- 	.get_brightness = read_brightness,
- 	.update_status = update_bl_status,
- };
-diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c
-index d66c07a..a4abaac 100644
---- a/drivers/platform/x86/asus_acpi.c
-+++ b/drivers/platform/x86/asus_acpi.c
-@@ -1396,7 +1396,7 @@ static int asus_hotk_remove(struct acpi_device *device, int type)
- 	return 0;
- }
- 
--static struct backlight_ops asus_backlight_data = {
-+static const struct backlight_ops asus_backlight_data = {
- 	.get_brightness = read_brightness,
- 	.update_status  = set_brightness_status,
- };
-diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c
-index 11003bb..550ff1b 100644
---- a/drivers/platform/x86/compal-laptop.c
-+++ b/drivers/platform/x86/compal-laptop.c
-@@ -163,7 +163,7 @@ static int bl_update_status(struct backlight_device *b)
- 	return set_lcd_level(b->props.brightness);
- }
- 
--static struct backlight_ops compalbl_ops = {
-+static const struct backlight_ops compalbl_ops = {
- 	.get_brightness = bl_get_brightness,
- 	.update_status	= bl_update_status,
- };
-diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
-index 07a74da..9dc99fa 100644
---- a/drivers/platform/x86/dell-laptop.c
-+++ b/drivers/platform/x86/dell-laptop.c
-@@ -318,7 +318,7 @@ static int dell_get_intensity(struct backlight_device *bd)
- 	return buffer.output[1];
- }
- 
--static struct backlight_ops dell_ops = {
-+static const struct backlight_ops dell_ops = {
- 	.get_brightness = dell_get_intensity,
- 	.update_status  = dell_send_intensity,
- };
-diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
-index c533b1c..5c81f22 100644
---- a/drivers/platform/x86/eeepc-laptop.c
-+++ b/drivers/platform/x86/eeepc-laptop.c
-@@ -245,7 +245,7 @@ static struct device *eeepc_hwmon_device;
-  */
- static int read_brightness(struct backlight_device *bd);
- static int update_bl_status(struct backlight_device *bd);
--static struct backlight_ops eeepcbl_ops = {
-+static const struct backlight_ops eeepcbl_ops = {
- 	.get_brightness = read_brightness,
- 	.update_status = update_bl_status,
- };
-diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
-index bcd4ba8..a249b35 100644
---- a/drivers/platform/x86/fujitsu-laptop.c
-+++ b/drivers/platform/x86/fujitsu-laptop.c
-@@ -436,7 +436,7 @@ static int bl_update_status(struct backlight_device *b)
- 	return ret;
- }
- 
--static struct backlight_ops fujitsubl_ops = {
-+static const struct backlight_ops fujitsubl_ops = {
- 	.get_brightness = bl_get_brightness,
- 	.update_status = bl_update_status,
- };
-diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
-index 759763d..1093ba2 100644
---- a/drivers/platform/x86/msi-laptop.c
-+++ b/drivers/platform/x86/msi-laptop.c
-@@ -161,7 +161,7 @@ static int bl_update_status(struct backlight_device *b)
- 	return set_lcd_level(b->props.brightness);
- }
- 
--static struct backlight_ops msibl_ops = {
-+static const struct backlight_ops msibl_ops = {
- 	.get_brightness = bl_get_brightness,
- 	.update_status  = bl_update_status,
- };
-diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
-index fe7cf01..9012d8d 100644
---- a/drivers/platform/x86/panasonic-laptop.c
-+++ b/drivers/platform/x86/panasonic-laptop.c
-@@ -352,7 +352,7 @@ static int bl_set_status(struct backlight_device *bd)
- 	return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright);
- }
- 
--static struct backlight_ops pcc_backlight_ops = {
-+static const struct backlight_ops pcc_backlight_ops = {
- 	.get_brightness	= bl_get,
- 	.update_status	= bl_set_status,
- };
-diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
-index a2a742c..b37e25e 100644
---- a/drivers/platform/x86/sony-laptop.c
-+++ b/drivers/platform/x86/sony-laptop.c
-@@ -850,7 +850,7 @@ static int sony_backlight_get_brightness(struct backlight_device *bd)
- }
- 
- static struct backlight_device *sony_backlight_device;
--static struct backlight_ops sony_backlight_ops = {
-+static const struct backlight_ops sony_backlight_ops = {
- 	.update_status = sony_backlight_update_status,
- 	.get_brightness = sony_backlight_get_brightness,
- };
-diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
-index 68271ae..5e8fb10 100644
---- a/drivers/platform/x86/thinkpad_acpi.c
-+++ b/drivers/platform/x86/thinkpad_acpi.c
-@@ -2139,7 +2139,7 @@ static int hotkey_mask_get(void)
- 	return 0;
- }
- 
--void static hotkey_mask_warn_incomplete_mask(void)
-+static void hotkey_mask_warn_incomplete_mask(void)
- {
- 	/* log only what the user can fix... */
- 	const u32 wantedmask = hotkey_driver_mask &
-@@ -6125,7 +6125,7 @@ static void tpacpi_brightness_notify_change(void)
- 			       BACKLIGHT_UPDATE_HOTKEY);
- }
- 
--static struct backlight_ops ibm_backlight_data = {
-+static const struct backlight_ops ibm_backlight_data = {
- 	.get_brightness = brightness_get,
- 	.update_status  = brightness_update_status,
- };
-diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
-index 51c0a8b..0786629 100644
---- a/drivers/platform/x86/toshiba_acpi.c
-+++ b/drivers/platform/x86/toshiba_acpi.c
-@@ -671,7 +671,7 @@ static acpi_status remove_device(void)
- 	return AE_OK;
- }
- 
--static struct backlight_ops toshiba_backlight_data = {
-+static const struct backlight_ops toshiba_backlight_data = {
-         .get_brightness = get_lcd,
-         .update_status  = set_lcd_status,
- };
-diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
-index fc83783c..cf370d7 100644
---- a/drivers/pnp/pnpbios/bioscalls.c
-+++ b/drivers/pnp/pnpbios/bioscalls.c
-@@ -60,7 +60,7 @@ do { \
- 	set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
- } while(0)
- 
--static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
-+static const struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4093,
- 			(unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
- 
- /*
-@@ -97,7 +97,10 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
- 
- 	cpu = get_cpu();
- 	save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
++}
++void be_netif_napi_del(struct net_device *netdev)
++{
++#ifdef HAVE_SIMULATED_MULTI_NAPI
++	struct be_adapter *adapter = netdev_priv(netdev);
++	struct napi_struct *napi;
++	struct be_rx_obj *rxo;
++	int i;
 +
-+	pax_open_kernel();
- 	get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
-+	pax_close_kernel();
- 
- 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
- 	spin_lock_irqsave(&pnp_bios_lock, flags);
-@@ -135,7 +138,10 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
- 			     :"memory");
- 	spin_unlock_irqrestore(&pnp_bios_lock, flags);
- 
-+	pax_open_kernel();
- 	get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
-+	pax_close_kernel();
++	for_all_rx_queues(adapter, rxo, i) {
++		napi = &rxo->rx_eq.napi;
++		if (napi->dev) {
++			free_netdev(napi->dev);
++			napi->dev = NULL;
++		}
++	}
 +
- 	put_cpu();
- 
- 	/* If we get here and this is set then the PnP BIOS faulted on us. */
-@@ -469,7 +475,7 @@ int pnp_bios_read_escd(char *data, u32 nvram_base)
- 	return status;
- }
- 
--void pnpbios_calls_init(union pnp_bios_install_struct *header)
-+void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
- {
- 	int i;
- 
-@@ -477,6 +483,8 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
- 	pnp_bios_callpoint.offset = header->fields.pm16offset;
- 	pnp_bios_callpoint.segment = PNP_CS16;
- 
-+	pax_open_kernel();
++	napi = &adapter->tx_eq.napi;
++	if (napi->dev) {
++		free_netdev(napi->dev);
++		napi->dev = NULL;
++	}
++#endif
++}
++/* INET_LRO backport */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
 +
- 	for_each_possible_cpu(i) {
- 		struct desc_struct *gdt = get_cpu_gdt_table(i);
- 		if (!gdt)
-@@ -488,4 +496,6 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
- 		set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_DS],
- 			 (unsigned long)__va(header->fields.pm16dseg));
- 	}
++#define TCP_HDR_LEN(tcph)		(tcph->doff << 2)
++#define IP_HDR_LEN(iph)			(iph->ihl << 2)
++#define TCP_PAYLOAD_LENGTH(iph, tcph)	(ntohs(iph->tot_len) - IP_HDR_LEN(iph) \
++						- TCP_HDR_LEN(tcph))
 +
-+	pax_close_kernel();
- }
-diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
-index ba97654..66b99d4 100644
---- a/drivers/pnp/resource.c
-+++ b/drivers/pnp/resource.c
-@@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
- 		return 1;
- 
- 	/* check if the resource is valid */
--	if (*irq < 0 || *irq > 15)
-+	if (*irq > 15)
- 		return 0;
- 
- 	/* check if the resource is reserved */
-@@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
- 		return 1;
- 
- 	/* check if the resource is valid */
--	if (*dma < 0 || *dma == 4 || *dma > 7)
-+	if (*dma == 4 || *dma > 7)
- 		return 0;
- 
- 	/* check if the resource is reserved */
-diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
-index 62bb981..24a2dc9 100644
---- a/drivers/power/bq27x00_battery.c
-+++ b/drivers/power/bq27x00_battery.c
-@@ -44,7 +44,7 @@ struct bq27x00_device_info;
- struct bq27x00_access_methods {
- 	int (*read)(u8 reg, int *rt_value, int b_single,
- 		struct bq27x00_device_info *di);
--};
-+} __no_const;
- 
- struct bq27x00_device_info {
- 	struct device 		*dev;
-diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
-index 62227cd..b5b538b 100644
---- a/drivers/rtc/rtc-dev.c
-+++ b/drivers/rtc/rtc-dev.c
-@@ -14,6 +14,7 @@
- #include <linux/module.h>
- #include <linux/rtc.h>
- #include <linux/sched.h>
-+#include <linux/grsecurity.h>
- #include "rtc-core.h"
- 
- static dev_t rtc_devt;
-@@ -357,6 +358,8 @@ static long rtc_dev_ioctl(struct file *file,
- 		if (copy_from_user(&tm, uarg, sizeof(tm)))
- 			return -EFAULT;
- 
-+		gr_log_timechange();
++#define IPH_LEN_WO_OPTIONS		5
++#define TCPH_LEN_WO_OPTIONS		5
++#define TCPH_LEN_W_TIMESTAMP		8
 +
- 		return rtc_set_time(rtc, &tm);
- 
- 	case RTC_PIE_ON:
-diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c
-index 968e3c7..fbc637a 100644
---- a/drivers/s390/cio/qdio_perf.c
-+++ b/drivers/s390/cio/qdio_perf.c
-@@ -31,51 +31,51 @@ static struct proc_dir_entry *qdio_perf_pde;
- static int qdio_perf_proc_show(struct seq_file *m, void *v)
- {
- 	seq_printf(m, "Number of qdio interrupts\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.qdio_int));
-+		   (long)atomic_long_read_unchecked(&perf_stats.qdio_int));
- 	seq_printf(m, "Number of PCI interrupts\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.pci_int));
-+		   (long)atomic_long_read_unchecked(&perf_stats.pci_int));
- 	seq_printf(m, "Number of adapter interrupts\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.thin_int));
-+		   (long)atomic_long_read_unchecked(&perf_stats.thin_int));
- 	seq_printf(m, "\n");
- 	seq_printf(m, "Inbound tasklet runs\t\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.tasklet_inbound));
-+		   (long)atomic_long_read_unchecked(&perf_stats.tasklet_inbound));
- 	seq_printf(m, "Outbound tasklet runs\t\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.tasklet_outbound));
-+		   (long)atomic_long_read_unchecked(&perf_stats.tasklet_outbound));
- 	seq_printf(m, "Adapter interrupt tasklet runs/loops\t\t: %li/%li\n",
--		   (long)atomic_long_read(&perf_stats.tasklet_thinint),
--		   (long)atomic_long_read(&perf_stats.tasklet_thinint_loop));
-+		   (long)atomic_long_read_unchecked(&perf_stats.tasklet_thinint),
-+		   (long)atomic_long_read_unchecked(&perf_stats.tasklet_thinint_loop));
- 	seq_printf(m, "Adapter interrupt inbound tasklet runs/loops\t: %li/%li\n",
--		   (long)atomic_long_read(&perf_stats.thinint_inbound),
--		   (long)atomic_long_read(&perf_stats.thinint_inbound_loop));
-+		   (long)atomic_long_read_unchecked(&perf_stats.thinint_inbound),
-+		   (long)atomic_long_read_unchecked(&perf_stats.thinint_inbound_loop));
- 	seq_printf(m, "\n");
- 	seq_printf(m, "Number of SIGA In issued\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.siga_in));
-+		   (long)atomic_long_read_unchecked(&perf_stats.siga_in));
- 	seq_printf(m, "Number of SIGA Out issued\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.siga_out));
-+		   (long)atomic_long_read_unchecked(&perf_stats.siga_out));
- 	seq_printf(m, "Number of SIGA Sync issued\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.siga_sync));
-+		   (long)atomic_long_read_unchecked(&perf_stats.siga_sync));
- 	seq_printf(m, "\n");
- 	seq_printf(m, "Number of inbound transfers\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.inbound_handler));
-+		   (long)atomic_long_read_unchecked(&perf_stats.inbound_handler));
- 	seq_printf(m, "Number of outbound transfers\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.outbound_handler));
-+		   (long)atomic_long_read_unchecked(&perf_stats.outbound_handler));
- 	seq_printf(m, "\n");
- 	seq_printf(m, "Number of fast requeues (outg. SBAL w/o SIGA)\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.fast_requeue));
-+		   (long)atomic_long_read_unchecked(&perf_stats.fast_requeue));
- 	seq_printf(m, "Number of outbound target full condition\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.outbound_target_full));
-+		   (long)atomic_long_read_unchecked(&perf_stats.outbound_target_full));
- 	seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.debug_tl_out_timer));
-+		   (long)atomic_long_read_unchecked(&perf_stats.debug_tl_out_timer));
- 	seq_printf(m, "Number of stop polling calls\t\t\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.debug_stop_polling));
-+		   (long)atomic_long_read_unchecked(&perf_stats.debug_stop_polling));
- 	seq_printf(m, "AI inbound tasklet loops after stop polling\t: %li\n",
--		   (long)atomic_long_read(&perf_stats.thinint_inbound_loop2));
-+		   (long)atomic_long_read_unchecked(&perf_stats.thinint_inbound_loop2));
- 	seq_printf(m, "QEBSM EQBS total/incomplete\t\t\t: %li/%li\n",
--		   (long)atomic_long_read(&perf_stats.debug_eqbs_all),
--		   (long)atomic_long_read(&perf_stats.debug_eqbs_incomplete));
-+		   (long)atomic_long_read_unchecked(&perf_stats.debug_eqbs_all),
-+		   (long)atomic_long_read_unchecked(&perf_stats.debug_eqbs_incomplete));
- 	seq_printf(m, "QEBSM SQBS total/incomplete\t\t\t: %li/%li\n",
--		   (long)atomic_long_read(&perf_stats.debug_sqbs_all),
--		   (long)atomic_long_read(&perf_stats.debug_sqbs_incomplete));
-+		   (long)atomic_long_read_unchecked(&perf_stats.debug_sqbs_all),
-+		   (long)atomic_long_read_unchecked(&perf_stats.debug_sqbs_incomplete));
- 	seq_printf(m, "\n");
- 	return 0;
- }
-diff --git a/drivers/s390/cio/qdio_perf.h b/drivers/s390/cio/qdio_perf.h
-index ff4504c..b3604c3 100644
---- a/drivers/s390/cio/qdio_perf.h
-+++ b/drivers/s390/cio/qdio_perf.h
-@@ -13,46 +13,46 @@
- 
- struct qdio_perf_stats {
- 	/* interrupt handler calls */
--	atomic_long_t qdio_int;
--	atomic_long_t pci_int;
--	atomic_long_t thin_int;
-+	atomic_long_unchecked_t qdio_int;
-+	atomic_long_unchecked_t pci_int;
-+	atomic_long_unchecked_t thin_int;
- 
- 	/* tasklet runs */
--	atomic_long_t tasklet_inbound;
--	atomic_long_t tasklet_outbound;
--	atomic_long_t tasklet_thinint;
--	atomic_long_t tasklet_thinint_loop;
--	atomic_long_t thinint_inbound;
--	atomic_long_t thinint_inbound_loop;
--	atomic_long_t thinint_inbound_loop2;
-+	atomic_long_unchecked_t tasklet_inbound;
-+	atomic_long_unchecked_t tasklet_outbound;
-+	atomic_long_unchecked_t tasklet_thinint;
-+	atomic_long_unchecked_t tasklet_thinint_loop;
-+	atomic_long_unchecked_t thinint_inbound;
-+	atomic_long_unchecked_t thinint_inbound_loop;
-+	atomic_long_unchecked_t thinint_inbound_loop2;
- 
- 	/* signal adapter calls */
--	atomic_long_t siga_out;
--	atomic_long_t siga_in;
--	atomic_long_t siga_sync;
-+	atomic_long_unchecked_t siga_out;
-+	atomic_long_unchecked_t siga_in;
-+	atomic_long_unchecked_t siga_sync;
- 
- 	/* misc */
--	atomic_long_t inbound_handler;
--	atomic_long_t outbound_handler;
--	atomic_long_t fast_requeue;
--	atomic_long_t outbound_target_full;
-+	atomic_long_unchecked_t inbound_handler;
-+	atomic_long_unchecked_t outbound_handler;
-+	atomic_long_unchecked_t fast_requeue;
-+	atomic_long_unchecked_t outbound_target_full;
- 
- 	/* for debugging */
--	atomic_long_t debug_tl_out_timer;
--	atomic_long_t debug_stop_polling;
--	atomic_long_t debug_eqbs_all;
--	atomic_long_t debug_eqbs_incomplete;
--	atomic_long_t debug_sqbs_all;
--	atomic_long_t debug_sqbs_incomplete;
-+	atomic_long_unchecked_t debug_tl_out_timer;
-+	atomic_long_unchecked_t debug_stop_polling;
-+	atomic_long_unchecked_t debug_eqbs_all;
-+	atomic_long_unchecked_t debug_eqbs_incomplete;
-+	atomic_long_unchecked_t debug_sqbs_all;
-+	atomic_long_unchecked_t debug_sqbs_incomplete;
- };
- 
- extern struct qdio_perf_stats perf_stats;
- extern int qdio_performance_stats;
- 
--static inline void qdio_perf_stat_inc(atomic_long_t *count)
-+static inline void qdio_perf_stat_inc(atomic_long_unchecked_t *count)
- {
- 	if (qdio_performance_stats)
--		atomic_long_inc(count);
-+		atomic_long_inc_unchecked(count);
- }
- 
- int qdio_setup_perf_stats(void);
-diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
-index 1ddcf40..a85f062 100644
---- a/drivers/scsi/BusLogic.c
-+++ b/drivers/scsi/BusLogic.c
-@@ -961,6 +961,8 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda
- static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
- 						    *PrototypeHostAdapter)
- {
-+	pax_track_stack();
++#define LRO_MAX_PG_HLEN			64
++#define LRO_INC_STATS(lro_mgr, attr)	{ lro_mgr->stats.attr++; }
++/*
++ * Basic tcp checks whether packet is suitable for LRO
++ */
++static int lro_tcp_ip_check(struct iphdr *iph, struct tcphdr *tcph,
++			    int len, struct net_lro_desc *lro_desc)
++{
++	/* check ip header: don't aggregate padded frames */
++	if (ntohs(iph->tot_len) != len)
++		return -1;
 +
- 	/*
- 	   If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
- 	   Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
-diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
-index cdbdec9..b7d560b 100644
---- a/drivers/scsi/aacraid/aacraid.h
-+++ b/drivers/scsi/aacraid/aacraid.h
-@@ -471,7 +471,7 @@ struct adapter_ops
- 	int  (*adapter_scsi)(struct fib * fib, struct scsi_cmnd * cmd);
- 	/* Administrative operations */
- 	int  (*adapter_comm)(struct aac_dev * dev, int comm);
--};
-+} __no_const;
- 
- /*
-  *	Define which interrupt handler needs to be installed
-diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
-index a5b8e7b..a6a0e43 100644
---- a/drivers/scsi/aacraid/commctrl.c
-+++ b/drivers/scsi/aacraid/commctrl.c
-@@ -481,6 +481,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
- 	u32 actual_fibsize64, actual_fibsize = 0;
- 	int i;
- 
-+	pax_track_stack();
- 
- 	if (dev->in_reset) {
- 		dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n"));
-diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
-index 9b97c3e..f099725 100644
---- a/drivers/scsi/aacraid/linit.c
-+++ b/drivers/scsi/aacraid/linit.c
-@@ -91,7 +91,7 @@ static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = {
- #elif defined(__devinitconst)
- static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
- #else
--static const struct pci_device_id aac_pci_tbl[] __devinitdata = {
-+static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
- #endif
- 	{ 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */
- 	{ 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */
-diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
-index 996f722..9127845 100644
---- a/drivers/scsi/aic94xx/aic94xx_init.c
-+++ b/drivers/scsi/aic94xx/aic94xx_init.c
-@@ -485,7 +485,7 @@ static ssize_t asd_show_update_bios(struct device *dev,
- 			flash_error_table[i].reason);
- }
- 
--static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUGO,
-+static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUSR,
- 	asd_show_update_bios, asd_store_update_bios);
- 
- static int asd_create_dev_attrs(struct asd_ha_struct *asd_ha)
-@@ -1011,7 +1011,7 @@ static struct sas_domain_function_template aic94xx_transport_functions = {
- 	.lldd_control_phy	= asd_control_phy,
- };
- 
--static const struct pci_device_id aic94xx_pci_table[] __devinitdata = {
-+static const struct pci_device_id aic94xx_pci_table[] __devinitconst = {
- 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x410),0, 0, 1},
- 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x412),0, 0, 1},
- 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x416),0, 0, 1},
-diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
-index 58efd4b..cb48dc7 100644
---- a/drivers/scsi/bfa/bfa_ioc.h
-+++ b/drivers/scsi/bfa/bfa_ioc.h
-@@ -127,7 +127,7 @@ struct bfa_ioc_cbfn_s {
- 	bfa_ioc_disable_cbfn_t	disable_cbfn;
- 	bfa_ioc_hbfail_cbfn_t	hbfail_cbfn;
- 	bfa_ioc_reset_cbfn_t	reset_cbfn;
--};
-+} __no_const;
- 
- /**
-  * Heartbeat failure notification queue element.
-diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h
-index 7ad177e..5503586 100644
---- a/drivers/scsi/bfa/bfa_iocfc.h
-+++ b/drivers/scsi/bfa/bfa_iocfc.h
-@@ -61,7 +61,7 @@ struct bfa_hwif_s {
- 	void (*hw_isr_mode_set)(struct bfa_s *bfa, bfa_boolean_t msix);
- 	void (*hw_msix_getvecs)(struct bfa_s *bfa, u32 *vecmap,
- 			u32 *nvecs, u32 *maxvec);
--};
-+} __no_const;
- typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status);
- 
- struct bfa_iocfc_s {
-diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
-index 4967643..cbec06b 100644
---- a/drivers/scsi/dpt_i2o.c
-+++ b/drivers/scsi/dpt_i2o.c
-@@ -1804,6 +1804,8 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
- 	dma_addr_t addr;
- 	ulong flags = 0;
- 
-+	pax_track_stack();
++	if (iph->ihl != IPH_LEN_WO_OPTIONS)
++		return -1;
 +
- 	memset(&msg, 0, MAX_MESSAGE_SIZE*4);
- 	// get user msg size in u32s 
- 	if(get_user(size, &user_msg[0])){
-@@ -2297,6 +2299,8 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
- 	s32 rcode;
- 	dma_addr_t addr;
- 
-+	pax_track_stack();
++	if (tcph->cwr || tcph->ece || tcph->urg || !tcph->ack
++		|| tcph->rst || tcph->syn || tcph->fin)
++		return -1;
 +
- 	memset(msg, 0 , sizeof(msg));
- 	len = scsi_bufflen(cmd);
- 	direction = 0x00000000;	
-diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
-index c7076ce..e20c67c 100644
---- a/drivers/scsi/eata.c
-+++ b/drivers/scsi/eata.c
-@@ -1087,6 +1087,8 @@ static int port_detect(unsigned long port_base, unsigned int j,
- 	struct hostdata *ha;
- 	char name[16];
- 
-+	pax_track_stack();
++	if (INET_ECN_is_ce(ipv4_get_dsfield(iph)))
++		return -1;
 +
- 	sprintf(name, "%s%d", driver_name, j);
- 
- 	if (!request_region(port_base, REGION_SIZE, driver_name)) {
-diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
-index 11ae5c9..891daec 100644
---- a/drivers/scsi/fcoe/libfcoe.c
-+++ b/drivers/scsi/fcoe/libfcoe.c
-@@ -809,6 +809,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
- 	size_t rlen;
- 	size_t dlen;
- 
-+	pax_track_stack();
++	if (tcph->doff != TCPH_LEN_WO_OPTIONS
++		&& tcph->doff != TCPH_LEN_W_TIMESTAMP)
++		return -1;
 +
- 	fiph = (struct fip_header *)skb->data;
- 	sub = fiph->fip_subcode;
- 	if (sub != FIP_SC_REQ && sub != FIP_SC_REP)
-diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
-index 71c7bbe..e93088a 100644
---- a/drivers/scsi/fnic/fnic_main.c
-+++ b/drivers/scsi/fnic/fnic_main.c
-@@ -669,7 +669,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
- 	/* Start local port initiatialization */
- 
- 	lp->link_up = 0;
--	lp->tt = fnic_transport_template;
-+	memcpy((void *)&lp->tt, &fnic_transport_template, sizeof(fnic_transport_template));
- 
- 	lp->max_retry_count = fnic->config.flogi_retries;
- 	lp->max_rport_retry_count = fnic->config.plogi_retries;
-diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
-index bb96d74..9ec3ce4 100644
---- a/drivers/scsi/gdth.c
-+++ b/drivers/scsi/gdth.c
-@@ -4102,6 +4102,8 @@ static int ioc_lockdrv(void __user *arg)
-     ulong flags;
-     gdth_ha_str *ha;
- 
-+    pax_track_stack();
++	/* check tcp options (only timestamp allowed) */
++	if (tcph->doff == TCPH_LEN_W_TIMESTAMP) {
++		u32 *topt = (u32 *)(tcph + 1);
++
++		if (*topt != htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
++				| (TCPOPT_TIMESTAMP << 8)
++				| TCPOLEN_TIMESTAMP))
++			return -1;
++
++		/* timestamp should be in right order */
++		topt++;
++		if (lro_desc && after(ntohl(lro_desc->tcp_rcv_tsval),
++				ntohl(*topt)))
++			return -1;
++
++		/* timestamp reply should not be zero */
++		topt++;
++		if (*topt == 0)
++			return -1;
++	}
 +
-     if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)))
-         return -EFAULT;
-     ha = gdth_find_ha(ldrv.ionode);
-@@ -4134,6 +4136,8 @@ static int ioc_resetdrv(void __user *arg, char *cmnd)
-     gdth_ha_str *ha;
-     int rval;
- 
-+    pax_track_stack();
++	return 0;
++}
 +
-     if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) ||
-         res.number >= MAX_HDRIVES)
-         return -EFAULT;
-@@ -4169,6 +4173,8 @@ static int ioc_general(void __user *arg, char *cmnd)
-     gdth_ha_str *ha;
-     int rval;
- 
-+    pax_track_stack();
++static void lro_update_tcp_ip_header(struct net_lro_desc *lro_desc)
++{
++	struct iphdr *iph = lro_desc->iph;
++	struct tcphdr *tcph = lro_desc->tcph;
++	u32 *p;
++	__wsum tcp_hdr_csum;
 +
-     if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)))
-         return -EFAULT;
-     ha = gdth_find_ha(gen.ionode);
-@@ -4625,6 +4631,9 @@ static void gdth_flush(gdth_ha_str *ha)
-     int             i;
-     gdth_cmd_str    gdtcmd;
-     char            cmnd[MAX_COMMAND_SIZE];   
++	tcph->ack_seq = lro_desc->tcp_ack;
++	tcph->window = lro_desc->tcp_window;
 +
-+    pax_track_stack();
++	if (lro_desc->tcp_saw_tstamp) {
++		p = (u32 *)(tcph + 1);
++		*(p+2) = lro_desc->tcp_rcv_tsecr;
++	}
 +
-     memset(cmnd, 0xff, MAX_COMMAND_SIZE);
- 
-     TRACE2(("gdth_flush() hanum %d\n", ha->hanum));
-diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
-index 1258da3..20d8ae6 100644
---- a/drivers/scsi/gdth_proc.c
-+++ b/drivers/scsi/gdth_proc.c
-@@ -46,6 +46,9 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
-     ulong64         paddr;
- 
-     char            cmnd[MAX_COMMAND_SIZE];
++	iph->tot_len = htons(lro_desc->ip_tot_len);
 +
-+    pax_track_stack();
++	iph->check = 0;
++	iph->check = ip_fast_csum((u8 *)lro_desc->iph, iph->ihl);
 +
-     memset(cmnd, 0xff, 12);
-     memset(&gdtcmd, 0, sizeof(gdth_cmd_str));
- 
-@@ -174,6 +177,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
-     gdth_hget_str *phg;
-     char cmnd[MAX_COMMAND_SIZE];
- 
-+    pax_track_stack();
++	tcph->check = 0;
++	tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), 0);
++	lro_desc->data_csum = csum_add(lro_desc->data_csum, tcp_hdr_csum);
++	tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
++					lro_desc->ip_tot_len -
++					IP_HDR_LEN(iph), IPPROTO_TCP,
++					lro_desc->data_csum);
++}
 +
-     gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL);
-     estr = kmalloc(sizeof(*estr), GFP_KERNEL);
-     if (!gdtcmd || !estr)
-diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
-index d03a926..f324286 100644
---- a/drivers/scsi/hosts.c
-+++ b/drivers/scsi/hosts.c
-@@ -40,7 +40,7 @@
- #include "scsi_logging.h"
- 
- 
--static atomic_t scsi_host_next_hn;	/* host_no for next new host */
-+static atomic_unchecked_t scsi_host_next_hn;	/* host_no for next new host */
- 
- 
- static void scsi_host_cls_release(struct device *dev)
-@@ -347,7 +347,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
- 	 * subtract one because we increment first then return, but we need to
- 	 * know what the next host number was before increment
- 	 */
--	shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1;
-+	shost->host_no = atomic_inc_return_unchecked(&scsi_host_next_hn) - 1;
- 	shost->dma_channel = 0xff;
- 
- 	/* These three are default values which can be overridden */
-diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
-index a601159..55e19d2 100644
---- a/drivers/scsi/ipr.c
-+++ b/drivers/scsi/ipr.c
-@@ -5286,7 +5286,7 @@ static bool ipr_qc_fill_rtf(struct ata_queued_cmd *qc)
- 	return true;
- }
- 
--static struct ata_port_operations ipr_sata_ops = {
-+static const struct ata_port_operations ipr_sata_ops = {
- 	.phy_reset = ipr_ata_phy_reset,
- 	.hardreset = ipr_sata_reset,
- 	.post_internal_cmd = ipr_ata_post_internal,
-diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
-index 4e49fbc..97907ff 100644
---- a/drivers/scsi/ips.h
-+++ b/drivers/scsi/ips.h
-@@ -1027,7 +1027,7 @@ typedef struct {
-    int       (*intr)(struct ips_ha *);
-    void      (*enableint)(struct ips_ha *);
-    uint32_t (*statupd)(struct ips_ha *);
--} ips_hw_func_t;
-+} __no_const ips_hw_func_t;
- 
- typedef struct ips_ha {
-    uint8_t            ha_id[IPS_MAX_CHANNELS+1];
-diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
-index c1c1574..a9c9348 100644
---- a/drivers/scsi/libfc/fc_exch.c
-+++ b/drivers/scsi/libfc/fc_exch.c
-@@ -86,12 +86,12 @@ struct fc_exch_mgr {
- 	 * all together if not used XXX
- 	 */
- 	struct {
--		atomic_t no_free_exch;
--		atomic_t no_free_exch_xid;
--		atomic_t xid_not_found;
--		atomic_t xid_busy;
--		atomic_t seq_not_found;
--		atomic_t non_bls_resp;
-+		atomic_unchecked_t no_free_exch;
-+		atomic_unchecked_t no_free_exch_xid;
-+		atomic_unchecked_t xid_not_found;
-+		atomic_unchecked_t xid_busy;
-+		atomic_unchecked_t seq_not_found;
-+		atomic_unchecked_t non_bls_resp;
- 	} stats;
- };
- #define	fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
-@@ -510,7 +510,7 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
- 	/* allocate memory for exchange */
- 	ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
- 	if (!ep) {
--		atomic_inc(&mp->stats.no_free_exch);
-+		atomic_inc_unchecked(&mp->stats.no_free_exch);
- 		goto out;
- 	}
- 	memset(ep, 0, sizeof(*ep));
-@@ -557,7 +557,7 @@ out:
- 	return ep;
- err:
- 	spin_unlock_bh(&pool->lock);
--	atomic_inc(&mp->stats.no_free_exch_xid);
-+	atomic_inc_unchecked(&mp->stats.no_free_exch_xid);
- 	mempool_free(ep, mp->ep_pool);
- 	return NULL;
- }
-@@ -690,7 +690,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
- 		xid = ntohs(fh->fh_ox_id);	/* we originated exch */
- 		ep = fc_exch_find(mp, xid);
- 		if (!ep) {
--			atomic_inc(&mp->stats.xid_not_found);
-+			atomic_inc_unchecked(&mp->stats.xid_not_found);
- 			reject = FC_RJT_OX_ID;
- 			goto out;
- 		}
-@@ -720,7 +720,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
- 		ep = fc_exch_find(mp, xid);
- 		if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) {
- 			if (ep) {
--				atomic_inc(&mp->stats.xid_busy);
-+				atomic_inc_unchecked(&mp->stats.xid_busy);
- 				reject = FC_RJT_RX_ID;
- 				goto rel;
- 			}
-@@ -731,7 +731,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
- 			}
- 			xid = ep->xid;	/* get our XID */
- 		} else if (!ep) {
--			atomic_inc(&mp->stats.xid_not_found);
-+			atomic_inc_unchecked(&mp->stats.xid_not_found);
- 			reject = FC_RJT_RX_ID;	/* XID not found */
- 			goto out;
- 		}
-@@ -752,7 +752,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
- 	} else {
- 		sp = &ep->seq;
- 		if (sp->id != fh->fh_seq_id) {
--			atomic_inc(&mp->stats.seq_not_found);
-+			atomic_inc_unchecked(&mp->stats.seq_not_found);
- 			reject = FC_RJT_SEQ_ID;	/* sequence/exch should exist */
- 			goto rel;
- 		}
-@@ -1163,22 +1163,22 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
- 
- 	ep = fc_exch_find(mp, ntohs(fh->fh_ox_id));
- 	if (!ep) {
--		atomic_inc(&mp->stats.xid_not_found);
-+		atomic_inc_unchecked(&mp->stats.xid_not_found);
- 		goto out;
- 	}
- 	if (ep->esb_stat & ESB_ST_COMPLETE) {
--		atomic_inc(&mp->stats.xid_not_found);
-+		atomic_inc_unchecked(&mp->stats.xid_not_found);
- 		goto out;
- 	}
- 	if (ep->rxid == FC_XID_UNKNOWN)
- 		ep->rxid = ntohs(fh->fh_rx_id);
- 	if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) {
--		atomic_inc(&mp->stats.xid_not_found);
-+		atomic_inc_unchecked(&mp->stats.xid_not_found);
- 		goto rel;
- 	}
- 	if (ep->did != ntoh24(fh->fh_s_id) &&
- 	    ep->did != FC_FID_FLOGI) {
--		atomic_inc(&mp->stats.xid_not_found);
-+		atomic_inc_unchecked(&mp->stats.xid_not_found);
- 		goto rel;
- 	}
- 	sof = fr_sof(fp);
-@@ -1189,7 +1189,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
- 	} else {
- 		sp = &ep->seq;
- 		if (sp->id != fh->fh_seq_id) {
--			atomic_inc(&mp->stats.seq_not_found);
-+			atomic_inc_unchecked(&mp->stats.seq_not_found);
- 			goto rel;
- 		}
- 	}
-@@ -1249,9 +1249,9 @@ static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
- 	sp = fc_seq_lookup_orig(mp, fp);	/* doesn't hold sequence */
- 
- 	if (!sp)
--		atomic_inc(&mp->stats.xid_not_found);
-+		atomic_inc_unchecked(&mp->stats.xid_not_found);
- 	else
--		atomic_inc(&mp->stats.non_bls_resp);
-+		atomic_inc_unchecked(&mp->stats.non_bls_resp);
- 
- 	fc_frame_free(fp);
- }
-diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
-index 0ee989f..a582241 100644
---- a/drivers/scsi/libsas/sas_ata.c
-+++ b/drivers/scsi/libsas/sas_ata.c
-@@ -343,7 +343,7 @@ static int sas_ata_scr_read(struct ata_link *link, unsigned int sc_reg_in,
- 	}
- }
- 
--static struct ata_port_operations sas_sata_ops = {
-+static const struct ata_port_operations sas_sata_ops = {
- 	.phy_reset		= sas_ata_phy_reset,
- 	.post_internal_cmd	= sas_ata_post_internal,
- 	.qc_defer               = ata_std_qc_defer,
-diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
-index aa10f79..5cc79e4 100644
---- a/drivers/scsi/lpfc/lpfc.h
-+++ b/drivers/scsi/lpfc/lpfc.h
-@@ -400,7 +400,7 @@ struct lpfc_vport {
- 	struct dentry *debug_nodelist;
- 	struct dentry *vport_debugfs_root;
- 	struct lpfc_debugfs_trc *disc_trc;
--	atomic_t disc_trc_cnt;
-+	atomic_unchecked_t disc_trc_cnt;
- #endif
- 	uint8_t stat_data_enabled;
- 	uint8_t stat_data_blocked;
-@@ -725,8 +725,8 @@ struct lpfc_hba {
- 	struct timer_list fabric_block_timer;
- 	unsigned long bit_flags;
- #define	FABRIC_COMANDS_BLOCKED	0
--	atomic_t num_rsrc_err;
--	atomic_t num_cmd_success;
-+	atomic_unchecked_t num_rsrc_err;
-+	atomic_unchecked_t num_cmd_success;
- 	unsigned long last_rsrc_error_time;
- 	unsigned long last_ramp_down_time;
- 	unsigned long last_ramp_up_time;
-@@ -740,7 +740,7 @@ struct lpfc_hba {
- 	struct dentry *debug_dumpDif;    /* BlockGuard BPL*/
- 	struct dentry *debug_slow_ring_trc;
- 	struct lpfc_debugfs_trc *slow_ring_trc;
--	atomic_t slow_ring_trc_cnt;
-+	atomic_unchecked_t slow_ring_trc_cnt;
- #endif
- 
- 	/* Used for deferred freeing of ELS data buffers */
-diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
-index 8d0f0de..7c77a62 100644
---- a/drivers/scsi/lpfc/lpfc_debugfs.c
-+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
-@@ -124,7 +124,7 @@ struct lpfc_debug {
- 	int  len;
- };
- 
--static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
-+static atomic_unchecked_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
- static unsigned long lpfc_debugfs_start_time = 0L;
- 
- /**
-@@ -158,7 +158,7 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
- 	lpfc_debugfs_enable = 0;
- 
- 	len = 0;
--	index = (atomic_read(&vport->disc_trc_cnt) + 1) &
-+	index = (atomic_read_unchecked(&vport->disc_trc_cnt) + 1) &
- 		(lpfc_debugfs_max_disc_trc - 1);
- 	for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
- 		dtp = vport->disc_trc + i;
-@@ -219,7 +219,7 @@ lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
- 	lpfc_debugfs_enable = 0;
- 
- 	len = 0;
--	index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
-+	index = (atomic_read_unchecked(&phba->slow_ring_trc_cnt) + 1) &
- 		(lpfc_debugfs_max_slow_ring_trc - 1);
- 	for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
- 		dtp = phba->slow_ring_trc + i;
-@@ -397,6 +397,8 @@ lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
- 	uint32_t *ptr;
- 	char buffer[1024];
- 
-+	pax_track_stack();
++static __wsum lro_tcp_data_csum(struct iphdr *iph, struct tcphdr *tcph, int len)
++{
++	__wsum tcp_csum;
++	__wsum tcp_hdr_csum;
++	__wsum tcp_ps_hdr_csum;
 +
- 	off = 0;
- 	spin_lock_irq(&phba->hbalock);
- 
-@@ -634,14 +636,14 @@ lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
- 		!vport || !vport->disc_trc)
- 		return;
- 
--	index = atomic_inc_return(&vport->disc_trc_cnt) &
-+	index = atomic_inc_return_unchecked(&vport->disc_trc_cnt) &
- 		(lpfc_debugfs_max_disc_trc - 1);
- 	dtp = vport->disc_trc + index;
- 	dtp->fmt = fmt;
- 	dtp->data1 = data1;
- 	dtp->data2 = data2;
- 	dtp->data3 = data3;
--	dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
-+	dtp->seq_cnt = atomic_inc_return_unchecked(&lpfc_debugfs_seq_trc_cnt);
- 	dtp->jif = jiffies;
- #endif
- 	return;
-@@ -672,14 +674,14 @@ lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
- 		!phba || !phba->slow_ring_trc)
- 		return;
- 
--	index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
-+	index = atomic_inc_return_unchecked(&phba->slow_ring_trc_cnt) &
- 		(lpfc_debugfs_max_slow_ring_trc - 1);
- 	dtp = phba->slow_ring_trc + index;
- 	dtp->fmt = fmt;
- 	dtp->data1 = data1;
- 	dtp->data2 = data2;
- 	dtp->data3 = data3;
--	dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
-+	dtp->seq_cnt = atomic_inc_return_unchecked(&lpfc_debugfs_seq_trc_cnt);
- 	dtp->jif = jiffies;
- #endif
- 	return;
-@@ -1364,7 +1366,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
- 						 "slow_ring buffer\n");
- 				goto debug_failed;
- 			}
--			atomic_set(&phba->slow_ring_trc_cnt, 0);
-+			atomic_set_unchecked(&phba->slow_ring_trc_cnt, 0);
- 			memset(phba->slow_ring_trc, 0,
- 				(sizeof(struct lpfc_debugfs_trc) *
- 				lpfc_debugfs_max_slow_ring_trc));
-@@ -1410,7 +1412,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
- 				 "buffer\n");
- 		goto debug_failed;
- 	}
--	atomic_set(&vport->disc_trc_cnt, 0);
-+	atomic_set_unchecked(&vport->disc_trc_cnt, 0);
- 
- 	snprintf(name, sizeof(name), "discovery_trace");
- 	vport->debug_disc_trc =
-diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
-index 549bc7d..8189dbb 100644
---- a/drivers/scsi/lpfc/lpfc_init.c
-+++ b/drivers/scsi/lpfc/lpfc_init.c
-@@ -8021,8 +8021,10 @@ lpfc_init(void)
- 	printk(LPFC_COPYRIGHT "\n");
- 
- 	if (lpfc_enable_npiv) {
--		lpfc_transport_functions.vport_create = lpfc_vport_create;
--		lpfc_transport_functions.vport_delete = lpfc_vport_delete;
-+		pax_open_kernel();
-+		*(void **)&lpfc_transport_functions.vport_create = lpfc_vport_create;
-+		*(void **)&lpfc_transport_functions.vport_delete = lpfc_vport_delete;
-+		pax_close_kernel();
- 	}
- 	lpfc_transport_template =
- 				fc_attach_transport(&lpfc_transport_functions);
-diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
-index c88f59f..ff2a42f 100644
---- a/drivers/scsi/lpfc/lpfc_scsi.c
-+++ b/drivers/scsi/lpfc/lpfc_scsi.c
-@@ -259,7 +259,7 @@ lpfc_rampdown_queue_depth(struct lpfc_hba *phba)
- 	uint32_t evt_posted;
- 
- 	spin_lock_irqsave(&phba->hbalock, flags);
--	atomic_inc(&phba->num_rsrc_err);
-+	atomic_inc_unchecked(&phba->num_rsrc_err);
- 	phba->last_rsrc_error_time = jiffies;
- 
- 	if ((phba->last_ramp_down_time + QUEUE_RAMP_DOWN_INTERVAL) > jiffies) {
-@@ -300,7 +300,7 @@ lpfc_rampup_queue_depth(struct lpfc_vport  *vport,
- 	unsigned long flags;
- 	struct lpfc_hba *phba = vport->phba;
- 	uint32_t evt_posted;
--	atomic_inc(&phba->num_cmd_success);
-+	atomic_inc_unchecked(&phba->num_cmd_success);
- 
- 	if (vport->cfg_lun_queue_depth <= queue_depth)
- 		return;
-@@ -343,8 +343,8 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
- 	int i;
- 	struct lpfc_rport_data *rdata;
- 
--	num_rsrc_err = atomic_read(&phba->num_rsrc_err);
--	num_cmd_success = atomic_read(&phba->num_cmd_success);
-+	num_rsrc_err = atomic_read_unchecked(&phba->num_rsrc_err);
-+	num_cmd_success = atomic_read_unchecked(&phba->num_cmd_success);
- 
- 	vports = lpfc_create_vport_work_array(phba);
- 	if (vports != NULL)
-@@ -378,8 +378,8 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
- 			}
- 		}
- 	lpfc_destroy_vport_work_array(phba, vports);
--	atomic_set(&phba->num_rsrc_err, 0);
--	atomic_set(&phba->num_cmd_success, 0);
-+	atomic_set_unchecked(&phba->num_rsrc_err, 0);
-+	atomic_set_unchecked(&phba->num_cmd_success, 0);
- }
++	tcp_csum = ~csum_unfold(tcph->check);
++	tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), tcp_csum);
++
++	tcp_ps_hdr_csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
++					     len + TCP_HDR_LEN(tcph),
++					     IPPROTO_TCP, 0);
++
++	return csum_sub(csum_sub(tcp_csum, tcp_hdr_csum),
++			tcp_ps_hdr_csum);
++}
++
++static void lro_init_desc(struct net_lro_desc *lro_desc, struct sk_buff *skb,
++			  struct iphdr *iph, struct tcphdr *tcph,
++			  u16 vlan_tag, struct vlan_group *vgrp)
++{
++	int nr_frags;
++	u32 *ptr;
++	u32 tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph);
++
++	nr_frags = skb_shinfo(skb)->nr_frags;
++	lro_desc->parent = skb;
++	lro_desc->next_frag = &(skb_shinfo(skb)->frags[nr_frags]);
++	lro_desc->iph = iph;
++	lro_desc->tcph = tcph;
++	lro_desc->tcp_next_seq = ntohl(tcph->seq) + tcp_data_len;
++	lro_desc->tcp_ack = ntohl(tcph->ack_seq);
++	lro_desc->tcp_window = tcph->window;
++
++	lro_desc->pkt_aggr_cnt = 1;
++	lro_desc->ip_tot_len = ntohs(iph->tot_len);
++
++	if (tcph->doff == 8) {
++		ptr = (u32 *)(tcph+1);
++		lro_desc->tcp_saw_tstamp = 1;
++		lro_desc->tcp_rcv_tsval = *(ptr+1);
++		lro_desc->tcp_rcv_tsecr = *(ptr+2);
++	}
++
++	lro_desc->mss = tcp_data_len;
++	lro_desc->vgrp = vgrp;
++	lro_desc->vlan_tag = vlan_tag;
++	lro_desc->active = 1;
++
++	if (tcp_data_len)
++		lro_desc->data_csum = lro_tcp_data_csum(iph, tcph,
++						tcp_data_len);
++
++	if (!tcp_data_len)
++		lro_desc->ack_cnt++;
++}
++
++static inline void lro_clear_desc(struct net_lro_desc *lro_desc)
++{
++	memset(lro_desc, 0, sizeof(struct net_lro_desc));
++}
++
++static void lro_add_common(struct net_lro_desc *lro_desc, struct iphdr *iph,
++			   struct tcphdr *tcph, int tcp_data_len)
++{
++	struct sk_buff *parent = lro_desc->parent;
++	u32 *topt;
++
++	lro_desc->pkt_aggr_cnt++;
++	lro_desc->ip_tot_len += tcp_data_len;
++	lro_desc->tcp_next_seq += tcp_data_len;
++	lro_desc->tcp_window = tcph->window;
++	lro_desc->tcp_ack = tcph->ack_seq;
++
++	/* don't update tcp_rcv_tsval, would not work with PAWS */
++	if (lro_desc->tcp_saw_tstamp) {
++		topt = (u32 *) (tcph + 1);
++		lro_desc->tcp_rcv_tsecr = *(topt + 2);
++	}
++
++	if (tcp_data_len)
++		lro_desc->data_csum = csum_block_add(lro_desc->data_csum,
++					lro_tcp_data_csum(iph, tcph,
++						tcp_data_len),
++					parent->len);
++
++	parent->len += tcp_data_len;
++	parent->data_len += tcp_data_len;
++	if (tcp_data_len > lro_desc->mss)
++		lro_desc->mss = tcp_data_len;
++}
++
++static void lro_add_frags(struct net_lro_desc *lro_desc,
++			  int len, int hlen, int truesize,
++			  struct skb_frag_struct *skb_frags,
++			  struct iphdr *iph, struct tcphdr *tcph)
++{
++	struct sk_buff *skb = lro_desc->parent;
++	int tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph);
++
++	lro_add_common(lro_desc, iph, tcph, tcp_data_len);
++
++	skb->truesize += truesize;
++
++	if (!tcp_data_len) {
++		put_page(skb_frags[0].page);
++		lro_desc->ack_cnt++;
++		return;
++	}
++
++	skb_frags[0].page_offset += hlen;
++	skb_frags[0].size -= hlen;
++
++	while (tcp_data_len > 0) {
++		*(lro_desc->next_frag) = *skb_frags;
++		tcp_data_len -= skb_frags->size;
++		lro_desc->next_frag++;
++		skb_frags++;
++		skb_shinfo(skb)->nr_frags++;
++	}
++}
++
++static int lro_check_tcp_conn(struct net_lro_desc *lro_desc,
++			      struct iphdr *iph,
++			      struct tcphdr *tcph)
++{
++	if ((lro_desc->iph->saddr != iph->saddr)
++	    || (lro_desc->iph->daddr != iph->daddr)
++	    || (lro_desc->tcph->source != tcph->source)
++	    || (lro_desc->tcph->dest != tcph->dest))
++		return -1;
++	return 0;
++}
++
++static struct net_lro_desc *lro_get_desc(struct net_lro_mgr *lro_mgr,
++					 struct net_lro_desc *lro_arr,
++					 struct iphdr *iph,
++					 struct tcphdr *tcph)
++{
++	struct net_lro_desc *lro_desc = NULL;
++	struct net_lro_desc *tmp;
++	int max_desc = lro_mgr->max_desc;
++	int i;
++
++	for (i = 0; i < max_desc; i++) {
++		tmp = &lro_arr[i];
++		if (tmp->active)
++			if (!lro_check_tcp_conn(tmp, iph, tcph)) {
++				lro_desc = tmp;
++				goto out;
++			}
++	}
++
++	for (i = 0; i < max_desc; i++) {
++		if (!lro_arr[i].active) {
++			lro_desc = &lro_arr[i];
++			goto out;
++		}
++	}
++
++	LRO_INC_STATS(lro_mgr, no_desc);
++out:
++	return lro_desc;
++}
++
++static void lro_flush(struct net_lro_mgr *lro_mgr,
++		      struct net_lro_desc *lro_desc)
++{
++	struct be_adapter *adapter = netdev_priv(lro_mgr->dev);
++
++	if (lro_desc->pkt_aggr_cnt > 1)
++		lro_update_tcp_ip_header(lro_desc);
++
++	skb_shinfo(lro_desc->parent)->gso_size = lro_desc->mss;
++
++	if (lro_desc->vgrp) {
++		if (test_bit(LRO_F_NAPI, &lro_mgr->features))
++			vlan_hwaccel_receive_skb(lro_desc->parent,
++				lro_desc->vgrp,
++				lro_desc->vlan_tag);
++		else
++			vlan_hwaccel_rx(lro_desc->parent,
++				lro_desc->vgrp,
++				lro_desc->vlan_tag);
++
++	} else {
++		if (test_bit(LRO_F_NAPI, &lro_mgr->features))
++			netif_receive_skb(lro_desc->parent);
++		else
++			netif_rx(lro_desc->parent);
++	}
++
++	LRO_INC_STATS(lro_mgr, flushed);
++	lro_clear_desc(lro_desc);
++}
++
++static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr,
++				   struct skb_frag_struct *frags,
++				   int len, int true_size,
++				   void *mac_hdr,
++				   int hlen, __wsum sum,
++				   u32 ip_summed)
++{
++	struct sk_buff *skb;
++	struct skb_frag_struct *skb_frags;
++	int data_len = len;
++	int hdr_len = min(len, hlen);
++
++	skb = netdev_alloc_skb(lro_mgr->dev, hlen);
++	if (!skb)
++		return NULL;
++
++	skb->len = len;
++	skb->data_len = len - hdr_len;
++	skb->truesize += true_size;
++	skb->tail += hdr_len;
++
++	memcpy(skb->data, mac_hdr, hdr_len);
++
++	if (skb->data_len) {
++		skb_frags = skb_shinfo(skb)->frags;
++		while (data_len > 0) {
++			*skb_frags = *frags;
++			data_len -= frags->size;
++			skb_frags++;
++			frags++;
++			skb_shinfo(skb)->nr_frags++;
++		}
++		skb_shinfo(skb)->frags[0].page_offset += hdr_len;
++		skb_shinfo(skb)->frags[0].size -= hdr_len;
++	} else {
++		put_page(frags[0].page);
++	}
++
++
++	skb->ip_summed = ip_summed;
++	skb->csum = sum;
++	skb->protocol = eth_type_trans(skb, lro_mgr->dev);
++	return skb;
++}
++
++static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr,
++					  struct skb_frag_struct *frags,
++					  int len, int true_size,
++					  struct vlan_group *vgrp,
++					  u16 vlan_tag, void *priv, __wsum sum)
++{
++	struct net_lro_desc *lro_desc;
++	struct iphdr *iph;
++	struct tcphdr *tcph;
++	struct sk_buff *skb;
++	u64 flags;
++	void *mac_hdr;
++	int mac_hdr_len;
++	int hdr_len = LRO_MAX_PG_HLEN;
++	int vlan_hdr_len = 0;
++	u8 pad_bytes;
++
++	if (!lro_mgr->get_frag_header
++	    || lro_mgr->get_frag_header(frags, (void *)&mac_hdr, (void *)&iph,
++					(void *)&tcph, &flags, priv)) {
++		mac_hdr = page_address(frags->page) + frags->page_offset;
++		goto out1;
++	}
++
++	if (!(flags & LRO_IPV4) || !(flags & LRO_TCP))
++		goto out1;
++
++	hdr_len = (int)((void *)(tcph) + TCP_HDR_LEN(tcph) - mac_hdr);
++	mac_hdr_len = (int)((void *)(iph) - mac_hdr);
++
++	lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);
++	if (!lro_desc)
++		goto out1;
++
++	pad_bytes = len - (ntohs(iph->tot_len) + mac_hdr_len);
++	if (!TCP_PAYLOAD_LENGTH(iph, tcph) && pad_bytes) {
++		len -= pad_bytes; /* trim the packet */
++		frags[0].size -= pad_bytes;
++		true_size -= pad_bytes;
++	}
++
++	if (!lro_desc->active) { /* start new lro session */
++		if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, NULL))
++			goto out1;
++
++		skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr,
++				  hdr_len, 0, lro_mgr->ip_summed_aggr);
++		if (!skb)
++			goto out;
++
++		if ((skb->protocol == htons(ETH_P_8021Q))
++		    && !test_bit(LRO_F_EXTRACT_VLAN_ID, &lro_mgr->features))
++			vlan_hdr_len = VLAN_HLEN;
++
++		iph = (void *)(skb->data + vlan_hdr_len);
++		tcph = (void *)((u8 *)skb->data + vlan_hdr_len
++				+ IP_HDR_LEN(iph));
++
++		lro_init_desc(lro_desc, skb, iph, tcph, vlan_tag, vgrp);
++		LRO_INC_STATS(lro_mgr, aggregated);
++		return 0;
++	}
++
++	if (lro_desc->tcp_next_seq != ntohl(tcph->seq))
++		goto out2;
++
++	if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, lro_desc))
++		goto out2;
++
++	lro_add_frags(lro_desc, len, hdr_len, true_size, frags, iph, tcph);
++	LRO_INC_STATS(lro_mgr, aggregated);
++
++	if ((skb_shinfo(lro_desc->parent)->nr_frags >= lro_mgr->max_aggr) ||
++	    lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu))
++		lro_flush(lro_mgr, lro_desc);
++
++	return NULL;
++
++out2: /* send aggregated packets to the stack */
++	lro_flush(lro_mgr, lro_desc);
++
++out1:  /* Original packet has to be posted to the stack */
++	skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr,
++			  hdr_len, sum, lro_mgr->ip_summed);
++out:
++	return skb;
++}
++
++void lro_receive_frags_compat(struct net_lro_mgr *lro_mgr,
++		       struct skb_frag_struct *frags,
++		       int len, int true_size, void *priv, __wsum sum)
++{
++	struct sk_buff *skb;
++
++	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, NULL, 0,
++				 priv, sum);
++	if (!skb)
++		return;
++
++	if (test_bit(LRO_F_NAPI, &lro_mgr->features))
++		netif_receive_skb(skb);
++	else
++		netif_rx(skb);
++}
++
++void lro_vlan_hwaccel_receive_frags_compat(struct net_lro_mgr *lro_mgr,
++				    struct skb_frag_struct *frags,
++				    int len, int true_size,
++				    struct vlan_group *vgrp,
++				    u16 vlan_tag, void *priv, __wsum sum)
++{
++	struct sk_buff *skb;
++
++	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, vgrp,
++				 vlan_tag, priv, sum);
++	if (!skb)
++		return;
++
++	if (test_bit(LRO_F_NAPI, &lro_mgr->features))
++		vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
++	else
++		vlan_hwaccel_rx(skb, vgrp, vlan_tag);
++}
++
++void lro_flush_all_compat(struct net_lro_mgr *lro_mgr)
++{
++	int i;
++	struct net_lro_desc *lro_desc = lro_mgr->lro_arr;
++
++	for (i = 0; i < lro_mgr->max_desc; i++) {
++		if (lro_desc[i].active)
++			lro_flush(lro_mgr, &lro_desc[i]);
++	}
++}
++#endif /* INET_LRO backport */
++
++#ifndef TX_MQ
++struct net_device *alloc_etherdev_mq_compat(int sizeof_priv,
++					unsigned int queue_count)
++{
++	return alloc_etherdev(sizeof_priv);
++}
++
++void netif_wake_subqueue_compat(struct net_device *dev, u16 queue_index)
++{
++	netif_wake_queue(dev);
++}
++
++void netif_stop_subqueue_compat(struct net_device *dev, u16 queue_index)
++{
++	netif_stop_queue(dev);
++}
++
++int __netif_subqueue_stopped_compat(const struct net_device *dev,
++						u16 queue_index)
++{
++	return netif_queue_stopped(dev);
++}
++
++u16 skb_get_queue_mapping_compat(const struct sk_buff *skb)
++{
++        return 0;
++}
++
++void netif_set_real_num_tx_queues_compat(struct net_device *dev,
++					unsigned int txq)
++{
++	return;
++}
++
++u16 skb_tx_hash_compat(const struct net_device *dev,
++			const struct sk_buff *skb)
++{
++	return 0;
++}
++#endif
+diff --git a/drivers/net/benet/be_compat.h b/drivers/net/benet/be_compat.h
+new file mode 100644
+index 0000000..8ceecc8
+--- /dev/null
++++ b/drivers/net/benet/be_compat.h
+@@ -0,0 +1,621 @@
++/*
++ * Copyright (C) 2005 - 2011 Emulex
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation. The full GNU General
++ * Public License is included in this distribution in the file called COPYING.
++ *
++ * Contact Information:
++ * linux-drivers@emulex.com
++ *
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
++ */
++
++#ifndef BE_COMPAT_H
++#define BE_COMPAT_H
++
++/****************** RHEL5 and SLES10 backport ***************************/
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
++
++#ifndef upper_32_bits
++#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
++#endif
++
++#ifndef CHECKSUM_PARTIAL
++#define CHECKSUM_PARTIAL CHECKSUM_HW
++#define CHECKSUM_COMPLETE CHECKSUM_HW
++#endif
++
++#if !defined(ip_hdr)
++#define ip_hdr(skb)	(skb->nh.iph)
++#define ipv6_hdr(skb)	(skb->nh.ipv6h)
++#endif
++
++#if !defined(__packed)
++#define __packed	__attribute__ ((packed))
++#endif
++
++#if !defined(RHEL_MINOR)
++/* Only for RH5U1 (Maui) and SLES10 NIC driver */
++enum {
++	false = 0,
++	true = 1
++};
++#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18)
++/* Only for RH5U1 (Maui) NIC driver */
++static inline __attribute__((const))
++int __ilog2_u32(u32 n)
++{
++	return fls(n) - 1;
++}
++#endif
++#endif
++
++#define ETH_FCS_LEN			4
++#define bool				u8
++#ifndef PTR_ALIGN
++#define PTR_ALIGN(p, a)			((typeof(p))			\
++					ALIGN((unsigned long)(p), (a)))
++#endif
++#define list_first_entry(ptr, type, member)				\
++			list_entry((ptr)->next, type, member)
++
++#if (defined(RHEL_MINOR) && RHEL_MINOR < 6) || \
++	LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)
++#define DEFINE_PCI_DEVICE_TABLE(_table) struct pci_device_id _table[]	\
++						__devinitdata
++#endif
++
++/* Backport of request_irq */
++typedef irqreturn_t(*backport_irq_handler_t) (int, void *);
++static inline int
++backport_request_irq(unsigned int irq, irqreturn_t(*handler) (int, void *),
++		unsigned long flags, const char *dev_name, void *dev_id)
++{
++	return request_irq(irq,
++			(irqreturn_t(*) (int, void *, struct pt_regs *))handler,
++			flags, dev_name, dev_id);
++}
++#define request_irq			backport_request_irq
++
++#endif /*** RHEL5 and SLES10 backport ***/
++
++#if !defined(__packed)
++#define __packed			__attribute__ ((packed))
++#endif
++
++/****************** SLES10 only backport ***************************/
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
++
++#include <linux/tifm.h>
++
++#define FIELD_SIZEOF(t, f)		(sizeof(((t *)0)->f))
++#define IRQF_SHARED			SA_SHIRQ
++#define CHECKSUM_PARTIAL		CHECKSUM_HW
++#define CHECKSUM_COMPLETE		CHECKSUM_HW
++#define DIV_ROUND_UP(n, d)		(((n) + (d) - 1) / (d))
++#define NETIF_F_IPV6_CSUM		NETIF_F_IP_CSUM
++#define NETIF_F_TSO6			NETIF_F_TSO
++
++
++static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev,
++					       unsigned int length)
++{
++	/* 16 == NET_PAD_SKB */
++	struct sk_buff *skb;
++	skb = alloc_skb(length + 16, GFP_ATOMIC);
++	if (likely(skb != NULL)) {
++		skb_reserve(skb, 16);
++		skb->dev = dev;
++	}
++	return skb;
++}
++
++#define PCI_SAVE_STATE(x)
++
++#else  /* SLES10 only backport */
++
++#define PCI_SAVE_STATE(x)	pci_save_state(x)
++
++#endif /* SLES10 only backport */
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31)
++#define netdev_tx_t	int
++#endif
++
++#ifndef VLAN_PRIO_MASK
++#define VLAN_PRIO_MASK          0xe000 /* Priority Code Point */
++#define VLAN_PRIO_SHIFT         13
++#endif
++
++/*
++ * Backport of netdev ops struct
++ */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
++struct net_device_ops {
++	int	(*ndo_init)(struct net_device *dev);
++	void	(*ndo_uninit)(struct net_device *dev);
++	int	(*ndo_open)(struct net_device *dev);
++	int	(*ndo_stop)(struct net_device *dev);
++	int	(*ndo_start_xmit) (struct sk_buff *skb, struct net_device *dev);
++	u16	(*ndo_select_queue)(struct net_device *dev,
++				    struct sk_buff *skb);
++	void	(*ndo_change_rx_flags)(struct net_device *dev, int flags);
++	void	(*ndo_set_rx_mode)(struct net_device *dev);
++	void	(*ndo_set_multicast_list)(struct net_device *dev);
++	int	(*ndo_set_mac_address)(struct net_device *dev, void *addr);
++	int	(*ndo_validate_addr)(struct net_device *dev);
++	int	(*ndo_do_ioctl)(struct net_device *dev,
++			struct ifreq *ifr, int cmd);
++	int	(*ndo_set_config)(struct net_device *dev, struct ifmap *map);
++	int	(*ndo_change_mtu)(struct net_device *dev, int new_mtu);
++	int	(*ndo_neigh_setup)(struct net_device *dev,
++				struct neigh_parms *);
++	void	(*ndo_tx_timeout) (struct net_device *dev);
++
++	struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
++
++	void	(*ndo_vlan_rx_register)(struct net_device *dev,
++				struct vlan_group *grp);
++	void	(*ndo_vlan_rx_add_vid)(struct net_device *dev,
++				unsigned short vid);
++	void	(*ndo_vlan_rx_kill_vid)(struct net_device *dev,
++				unsigned short vid);
++#ifdef CONFIG_NET_POLL_CONTROLLER
++#define HAVE_NETDEV_POLL
++	void	(*ndo_poll_controller)(struct net_device *dev);
++#endif
++};
++extern void be_netdev_ops_init(struct net_device *netdev,
++			struct net_device_ops *ops);
++extern int eth_validate_addr(struct net_device *);
++
++#endif /* Netdev ops backport */
++
++#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 29)
++#undef NETIF_F_GRO
++#endif
++
++#ifdef NO_GRO
++#if ((defined(RHEL_MAJOR) && (RHEL_MAJOR == 5)))
++#undef NETIF_F_GRO
++#endif
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
++#define HAVE_ETHTOOL_FLASH
++#endif
++
++/*
++ * Backport of NAPI
++ */
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
++
++#if defined(RHEL_MINOR) && (RHEL_MINOR > 3)
++#define RHEL_NEW_NAPI
++#endif
++
++/* We need a new struct that has some meta data beyond rhel 5.4's napi_struct
++ * to fix rhel5.4's half-baked new napi implementation.
++ * We don't want to use rhel 5.4's broken napi_complete; so
++ * define a new be_napi_complete that executes the logic only for Rx
++ */
++
++#ifdef RHEL_NEW_NAPI
++#define napi_complete			be_napi_complete
++typedef struct napi_struct		rhel_napi_struct;
++#endif
++#define napi_struct			be_napi_struct
++#define napi_gro_frags(napi) napi_gro_frags((rhel_napi_struct *) napi)
++#define vlan_gro_frags(napi, vlan_grp, vid)\
++		vlan_gro_frags((rhel_napi_struct *) napi, vlan_grp, vid)
++#define napi_get_frags(napi) napi_get_frags((rhel_napi_struct *) napi)
++
++struct napi_struct {
++#ifdef RHEL_NEW_NAPI
++	rhel_napi_struct napi;	/* must be the first member */
++#endif
++	struct net_device *dev;
++	int (*poll) (struct napi_struct *napi, int budget);
++	bool rx;
++};
++
++static inline void napi_complete(struct napi_struct *napi)
++{
++#ifdef NETIF_F_GRO
++	napi_gro_flush((rhel_napi_struct *)napi);
++#endif
++	netif_rx_complete(napi->dev);
++}
++
++static inline void napi_schedule(struct napi_struct *napi)
++{
++	netif_rx_schedule(napi->dev);
++}
++
++static inline void napi_enable(struct napi_struct *napi)
++{
++	netif_poll_enable(napi->dev);
++}
++
++static inline void napi_disable(struct napi_struct *napi)
++{
++	netif_poll_disable(napi->dev);
++}
++
++#if (defined(RHEL_MINOR) && RHEL_MINOR < 6) || \
++	LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)
++static inline void vlan_group_set_device(struct vlan_group *vg,
++					u16 vlan_id,
++					struct net_device *dev)
++{
++	struct net_device **array;
++	if (!vg)
++		return;
++	array = vg->vlan_devices;
++	array[vlan_id] = dev;
++}
++#endif
++
++#endif /* New NAPI backport */
++
++extern int be_netif_napi_add(struct net_device *netdev,
++		struct napi_struct *napi,
++		int (*poll) (struct napi_struct *, int), int weight);
++extern void be_netif_napi_del(struct net_device *netdev);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
++#define HAVE_SIMULATED_MULTI_NAPI
++#endif
++
++/************** Backport of Delayed work queues interface ****************/
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
++#if (defined(RHEL_MINOR) && RHEL_MINOR < 6) || \
++	LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 16)
++struct delayed_work {
++	struct work_struct work;
++};
++#endif
++
++#define INIT_DELAYED_WORK(_work, _func)				\
++		INIT_WORK(&(_work)->work, _func, &(_work)->work)
++
++static inline int backport_cancel_delayed_work_sync(struct delayed_work *work)
++{
++	cancel_rearming_delayed_work(&work->work);
++	return 0;
++}
++#define cancel_delayed_work_sync backport_cancel_delayed_work_sync
++
++static inline int backport_schedule_delayed_work(struct delayed_work *work,
++		unsigned long delay)
++{
++	if (unlikely(!delay))
++		return schedule_work(&work->work);
++	else
++		return schedule_delayed_work(&work->work, delay);
++}
++#define schedule_delayed_work backport_schedule_delayed_work
++#endif /* backport delayed workqueue */
++
++
++/************** Backport of INET_LRO **********************************/
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)
++
++#include <linux/inet_lro.h>
++
++#else
++
++#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18)
++
++#if defined(RHEL_MINOR) && RHEL_MINOR < 6
++typedef __u16 __bitwise __sum16;
++typedef __u32 __bitwise __wsum;
++#endif
++
++#if ((defined(RHEL_MAJOR) && (RHEL_MAJOR == 5) && (RHEL_MINOR <= 3)) || \
++	(!defined(RHEL_MINOR)))
++static inline __wsum csum_unfold(__sum16 n)
++{
++	return (__force __wsum)n;
++}
++#endif
++
++#endif
++
++#define lro_flush_all lro_flush_all_compat
++#define lro_vlan_hwaccel_receive_frags lro_vlan_hwaccel_receive_frags_compat
++#define lro_receive_frags lro_receive_frags_compat
++
++struct net_lro_stats {
++	unsigned long aggregated;
++	unsigned long flushed;
++	unsigned long no_desc;
++};
++
++struct net_lro_desc {
++	struct sk_buff *parent;
++	struct sk_buff *last_skb;
++	struct skb_frag_struct *next_frag;
++	struct iphdr *iph;
++	struct tcphdr *tcph;
++	struct vlan_group *vgrp;
++	__wsum  data_csum;
++	u32 tcp_rcv_tsecr;
++	u32 tcp_rcv_tsval;
++	u32 tcp_ack;
++	u32 tcp_next_seq;
++	u32 skb_tot_frags_len;
++	u32 ack_cnt;
++	u16 ip_tot_len;
++	u16 tcp_saw_tstamp;		/* timestamps enabled */
++	u16 tcp_window;
++	u16 vlan_tag;
++	int pkt_aggr_cnt;		/* counts aggregated packets */
++	int vlan_packet;
++	int mss;
++	int active;
++};
++
++struct net_lro_mgr {
++	struct net_device *dev;
++	struct net_lro_stats stats;
++
++	/* LRO features */
++	unsigned long features;
++#define LRO_F_NAPI            1  /* Pass packets to stack via NAPI */
++#define LRO_F_EXTRACT_VLAN_ID 2  /* Set flag if VLAN IDs are extracted
++				from received packets and eth protocol
++				    is still ETH_P_8021Q */
++
++	u32 ip_summed;      /* Set in non generated SKBs in page mode */
++	u32 ip_summed_aggr; /* Set in aggregated SKBs: CHECKSUM_UNNECESSARY
++			     * or CHECKSUM_NONE */
++
++	int max_desc; /* Max number of LRO descriptors  */
++	int max_aggr; /* Max number of LRO packets to be aggregated */
++
++	struct net_lro_desc *lro_arr; /* Array of LRO descriptors */
++
++	/* Optimized driver functions
++	 * get_skb_header: returns tcp and ip header for packet in SKB
++	 */
++	int (*get_skb_header)(struct sk_buff *skb, void **ip_hdr,
++			      void **tcpudp_hdr, u64 *hdr_flags, void *priv);
++
++	/* hdr_flags: */
++#define LRO_IPV4 1 /* ip_hdr is IPv4 header */
++#define LRO_TCP  2 /* tcpudp_hdr is TCP header */
++
++	/*
++	 * get_frag_header: returns mac, tcp and ip header for packet in SKB
++	 *
++	 * @hdr_flags: Indicate what kind of LRO has to be done
++	 *             (IPv4/IPv6/TCP/UDP)
++	 */
++	int (*get_frag_header)(struct skb_frag_struct *frag, void **mac_hdr,
++			       void **ip_hdr, void **tcpudp_hdr, u64 *hdr_flags,
++			       void *priv);
++};
++
++extern void lro_receive_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb,
++			void *priv);
++
++extern void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
++			struct sk_buff *skb, struct vlan_group *vgrp,
++			u16 vlan_tag, void *priv);
++
++/* This functions aggregate fragments and generate SKBs do pass
++ * the packets to the stack.
++ *
++ * @lro_mgr: LRO manager to use
++ * @frags: Fragment to be processed. Must contain entire header in first
++ *         element.
++ * @len: Length of received data
++ * @true_size: Actual size of memory the fragment is consuming
++ * @priv: Private data that may be used by driver functions
++ *        (for example get_tcp_ip_hdr)
++ */
++extern void lro_receive_frags_compat(struct net_lro_mgr *lro_mgr,
++			struct skb_frag_struct *frags, int len, int true_size,
++			void *priv, __wsum sum);
++
++extern void lro_vlan_hwaccel_receive_frags_compat(struct net_lro_mgr *lro_mgr,
++			struct skb_frag_struct *frags, int len, int true_size,
++			struct vlan_group *vgrp, u16 vlan_tag, void *priv,
++			__wsum sum);
++
++/* Forward all aggregated SKBs held by lro_mgr to network stack */
++extern void lro_flush_all_compat(struct net_lro_mgr *lro_mgr);
++
++extern void lro_flush_pkt(struct net_lro_mgr *lro_mgr, struct iphdr *iph,
++			struct tcphdr *tcph);
++#endif /* backport of inet_lro */
++
++#ifndef ETHTOOL_FLASH_MAX_FILENAME
++#define ETHTOOL_FLASH_MAX_FILENAME	128
++#endif
++
++#if defined(CONFIG_XEN) && !defined(NETIF_F_GRO)
++#define BE_INIT_FRAGS_PER_FRAME  (u32) 1
++#else
++#define BE_INIT_FRAGS_PER_FRAME  (min((u32) 16, (u32) MAX_SKB_FRAGS))
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
++#ifdef CONFIG_PCI_IOV
++#if (!(defined(RHEL_MAJOR) && (RHEL_MAJOR == 5) && (RHEL_MINOR == 6)))
++#undef CONFIG_PCI_IOV
++#endif
++#endif
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
++#define dev_to_node(dev)	-1
++#endif
++
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
++#if (!(defined(RHEL_MAJOR) && (RHEL_MAJOR == 5) && (RHEL_MINOR > 6)))
++static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
++		unsigned int length)
++{
++	struct sk_buff *skb = netdev_alloc_skb(dev, length + NET_IP_ALIGN);
++
++	if (NET_IP_ALIGN && skb)
++		skb_reserve(skb, NET_IP_ALIGN);
++	return skb;
++}
++#endif
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
++#ifndef netif_set_gso_max_size
++#define netif_set_gso_max_size(netdev, size) do {} while (0)
++#endif
++#endif
++
++#if (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18))
++#if defined(RHEL_MINOR) && (RHEL_MINOR <= 4)
++static inline int skb_is_gso_v6(const struct sk_buff *skb)
++{
++	return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6;
++}
++#endif
++#endif
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
++static inline int skb_is_gso_v6(const struct sk_buff *skb)
++{
++	return (ip_hdr(skb)->version == 6);
++}
++#endif
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
++#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
++#if ((defined(RHEL_MAJOR) && (RHEL_MAJOR == 6)))
++#define HAVE_SRIOV_CONFIG
++#endif
++#endif
++
++#ifndef NETIF_F_VLAN_SG
++#define NETIF_F_VLAN_SG NETIF_F_SG
++#endif
++
++#ifndef NETIF_F_VLAN_CSUM
++#define NETIF_F_VLAN_CSUM NETIF_F_HW_CSUM
++#endif
++
++#ifndef NETIF_F_VLAN_TSO
++#define NETIF_F_VLAN_TSO NETIF_F_TSO
++#endif
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27))
++#define vlan_features	features
++#endif
++
++#ifndef DEFINE_DMA_UNMAP_ADDR
++#define DEFINE_DMA_UNMAP_ADDR(bus)	dma_addr_t bus
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++
++#ifndef netdev_mc_count
++#define netdev_mc_count(nd) (nd->mc_count)
++#endif
++
++#ifndef netdev_hw_addr
++#define netdev_hw_addr dev_mc_list
++#endif
++
++#ifndef netdev_for_each_mc_addr
++#define netdev_for_each_mc_addr(ha, nd) \
++	for (ha = (nd)->mc_list; ha; ha = ha->next)
++#endif
++
++#define DMI_ADDR dmi_addr
++#else
++#define DMI_ADDR addr
++#endif
++
++#ifndef VLAN_GROUP_ARRAY_LEN
++#define VLAN_GROUP_ARRAY_LEN VLAN_N_VID
++#endif
++/**************************** Multi TXQ Support ******************************/
++
++/* Supported only in RHEL6 and SL11.1 (barring one execption) */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
++#define MQ_TX
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
++#define alloc_etherdev_mq(sz, cnt) 		alloc_etherdev(sz)
++#define skb_get_queue_mapping(skb)		0
++#define skb_tx_hash(dev, skb)			0
++#define netif_set_real_num_tx_queues(dev, txq)	do {} while(0)	
++#define netif_wake_subqueue(dev, idx)		netif_wake_queue(dev)
++#define netif_stop_subqueue(dev, idx)		netif_stop_queue(dev)
++#define __netif_subqueue_stopped(dev, idx)	netif_queue_stopped(dev)
++#endif /* < 2.6.27 */
++
++#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && \
++		        (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)))
++#define skb_tx_hash(dev, skb)			0
++#define netif_set_real_num_tx_queues(dev, txq)	do {} while(0)	
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
++#define netif_set_real_num_tx_queues 		be_set_real_num_tx_queues
++static inline void be_set_real_num_tx_queues(struct net_device *dev,
++						unsigned int txq)
++{
++	dev->real_num_tx_queues = txq;
++}
++#endif
++
++#include <linux/if_vlan.h>
++static inline void be_reset_skb_tx_vlan(struct sk_buff *skb)
++{
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)
++	skb->vlan_tci = 0;
++#else
++	struct vlan_skb_tx_cookie *cookie;
++
++	cookie = VLAN_TX_SKB_CB(skb);
++	cookie->magic = 0;
++#endif
++}
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
++static inline void skb_set_network_header(struct sk_buff *skb, const int offset)
++{
++	skb->nh.raw = skb->data + offset;
++}
++#endif
++
++static inline struct sk_buff *be_vlan_put_tag(struct sk_buff *skb,
++						unsigned short vlan_tag)
++{
++	struct sk_buff *new_skb = __vlan_put_tag(skb, vlan_tag);
++	/* On kernel versions < 2.6.27 the __vlan_put_tag() function
++	 * distorts the network layer hdr pointer in the skb which
++	 * affects the detection of UDP/TCP packets down the line in
++	 * wrb_fill_hdr().This work-around sets it right.
++	 */
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27))
++	skb_set_network_header(new_skb, VLAN_ETH_HLEN);
++#endif
++	return new_skb;
++}
++
++#ifndef ACCESS_ONCE
++#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
++#endif
++
++#endif				/* BE_COMPAT_H */
+diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
+index f0fd95b..37bad99 100644
+--- a/drivers/net/benet/be_ethtool.c
++++ b/drivers/net/benet/be_ethtool.c
+@@ -1,18 +1,18 @@
+ /*
+- * Copyright (C) 2005 - 2009 ServerEngines
++ * Copyright (C) 2005 - 2011 Emulex
+  * All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation.  The full GNU General
++ * as published by the Free Software Foundation. The full GNU General
+  * Public License is included in this distribution in the file called COPYING.
+  *
+  * Contact Information:
+- * linux-drivers@serverengines.com
++ * linux-drivers@emulex.com
+  *
+- * ServerEngines
+- * 209 N. Fair Oaks Ave
+- * Sunnyvale, CA 94085
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
+  */
  
- /**
-@@ -427,8 +427,8 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
- 			}
- 		}
- 	lpfc_destroy_vport_work_array(phba, vports);
--	atomic_set(&phba->num_rsrc_err, 0);
--	atomic_set(&phba->num_cmd_success, 0);
-+	atomic_set_unchecked(&phba->num_rsrc_err, 0);
-+	atomic_set_unchecked(&phba->num_cmd_success, 0);
+ #include "be.h"
+@@ -26,21 +26,19 @@ struct be_ethtool_stat {
+ 	int offset;
+ };
+ 
+-enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT, ERXSTAT};
++enum {NETSTAT, DRVSTAT_TX, DRVSTAT_RX, DRVSTAT};
+ #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
+ 					offsetof(_struct, field)
+-#define NETSTAT_INFO(field) 	#field, NETSTAT,\
++#define NETSTAT_INFO(field)	#field, NETSTAT,\
+ 					FIELDINFO(struct net_device_stats,\
+ 						field)
+-#define DRVSTAT_INFO(field) 	#field, DRVSTAT,\
+-					FIELDINFO(struct be_drvr_stats, field)
+-#define MISCSTAT_INFO(field) 	#field, MISCSTAT,\
+-					FIELDINFO(struct be_rxf_stats, field)
+-#define PORTSTAT_INFO(field) 	#field, PORTSTAT,\
+-					FIELDINFO(struct be_port_rxf_stats, \
++#define DRVSTAT_TX_INFO(field)	#field, DRVSTAT_TX,\
++					FIELDINFO(struct be_tx_stats, field)
++#define DRVSTAT_RX_INFO(field)	#field, DRVSTAT_RX,\
++					FIELDINFO(struct be_rx_stats, field)
++#define	DRVSTAT_INFO(field)	#field, DRVSTAT,\
++					FIELDINFO(struct be_drv_stats, \
+ 						field)
+-#define ERXSTAT_INFO(field) 	#field, ERXSTAT,\
+-					FIELDINFO(struct be_erx_stats, field)
+ 
+ static const struct be_ethtool_stat et_stats[] = {
+ 	{NETSTAT_INFO(rx_packets)},
+@@ -51,70 +49,131 @@ static const struct be_ethtool_stat et_stats[] = {
+ 	{NETSTAT_INFO(tx_errors)},
+ 	{NETSTAT_INFO(rx_dropped)},
+ 	{NETSTAT_INFO(tx_dropped)},
+-	{DRVSTAT_INFO(be_tx_reqs)},
+-	{DRVSTAT_INFO(be_tx_stops)},
+-	{DRVSTAT_INFO(be_fwd_reqs)},
+-	{DRVSTAT_INFO(be_tx_wrbs)},
+-	{DRVSTAT_INFO(be_polls)},
+ 	{DRVSTAT_INFO(be_tx_events)},
+-	{DRVSTAT_INFO(be_rx_events)},
+-	{DRVSTAT_INFO(be_tx_compl)},
+-	{DRVSTAT_INFO(be_rx_compl)},
+-	{DRVSTAT_INFO(be_ethrx_post_fail)},
+-	{DRVSTAT_INFO(be_802_3_dropped_frames)},
+-	{DRVSTAT_INFO(be_802_3_malformed_frames)},
+-	{DRVSTAT_INFO(be_tx_rate)},
+-	{DRVSTAT_INFO(be_rx_rate)},
+-	{PORTSTAT_INFO(rx_unicast_frames)},
+-	{PORTSTAT_INFO(rx_multicast_frames)},
+-	{PORTSTAT_INFO(rx_broadcast_frames)},
+-	{PORTSTAT_INFO(rx_crc_errors)},
+-	{PORTSTAT_INFO(rx_alignment_symbol_errors)},
+-	{PORTSTAT_INFO(rx_pause_frames)},
+-	{PORTSTAT_INFO(rx_control_frames)},
+-	{PORTSTAT_INFO(rx_in_range_errors)},
+-	{PORTSTAT_INFO(rx_out_range_errors)},
+-	{PORTSTAT_INFO(rx_frame_too_long)},
+-	{PORTSTAT_INFO(rx_address_match_errors)},
+-	{PORTSTAT_INFO(rx_vlan_mismatch)},
+-	{PORTSTAT_INFO(rx_dropped_too_small)},
+-	{PORTSTAT_INFO(rx_dropped_too_short)},
+-	{PORTSTAT_INFO(rx_dropped_header_too_small)},
+-	{PORTSTAT_INFO(rx_dropped_tcp_length)},
+-	{PORTSTAT_INFO(rx_dropped_runt)},
+-	{PORTSTAT_INFO(rx_fifo_overflow)},
+-	{PORTSTAT_INFO(rx_input_fifo_overflow)},
+-	{PORTSTAT_INFO(rx_ip_checksum_errs)},
+-	{PORTSTAT_INFO(rx_tcp_checksum_errs)},
+-	{PORTSTAT_INFO(rx_udp_checksum_errs)},
+-	{PORTSTAT_INFO(rx_non_rss_packets)},
+-	{PORTSTAT_INFO(rx_ipv4_packets)},
+-	{PORTSTAT_INFO(rx_ipv6_packets)},
+-	{PORTSTAT_INFO(tx_unicastframes)},
+-	{PORTSTAT_INFO(tx_multicastframes)},
+-	{PORTSTAT_INFO(tx_broadcastframes)},
+-	{PORTSTAT_INFO(tx_pauseframes)},
+-	{PORTSTAT_INFO(tx_controlframes)},
+-	{MISCSTAT_INFO(rx_drops_no_pbuf)},
+-	{MISCSTAT_INFO(rx_drops_no_txpb)},
+-	{MISCSTAT_INFO(rx_drops_no_erx_descr)},
+-	{MISCSTAT_INFO(rx_drops_no_tpre_descr)},
+-	{MISCSTAT_INFO(rx_drops_too_many_frags)},
+-	{MISCSTAT_INFO(rx_drops_invalid_ring)},
+-	{MISCSTAT_INFO(forwarded_packets)},
+-	{MISCSTAT_INFO(rx_drops_mtu)},
+-	{ERXSTAT_INFO(rx_drops_no_fragments)},
++	{DRVSTAT_INFO(rx_crc_errors)},
++	{DRVSTAT_INFO(rx_alignment_symbol_errors)},
++	{DRVSTAT_INFO(rx_pause_frames)},
++	{DRVSTAT_INFO(rx_control_frames)},
++	{DRVSTAT_INFO(rx_in_range_errors)},
++	{DRVSTAT_INFO(rx_out_range_errors)},
++	{DRVSTAT_INFO(rx_frame_too_long)},
++	{DRVSTAT_INFO(rx_address_match_errors)},
++	{DRVSTAT_INFO(rx_dropped_too_small)},
++	{DRVSTAT_INFO(rx_dropped_too_short)},
++	{DRVSTAT_INFO(rx_dropped_header_too_small)},
++	{DRVSTAT_INFO(rx_dropped_tcp_length)},
++	{DRVSTAT_INFO(rx_dropped_runt)},
++	{DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
++	{DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
++	{DRVSTAT_INFO(rx_ip_checksum_errs)},
++	{DRVSTAT_INFO(rx_tcp_checksum_errs)},
++	{DRVSTAT_INFO(rx_udp_checksum_errs)},
++	{DRVSTAT_INFO(rx_switched_unicast_packets)},
++	{DRVSTAT_INFO(rx_switched_multicast_packets)},
++	{DRVSTAT_INFO(rx_switched_broadcast_packets)},
++	{DRVSTAT_INFO(tx_pauseframes)},
++	{DRVSTAT_INFO(tx_controlframes)},
++	{DRVSTAT_INFO(rx_priority_pause_frames)},
++	{DRVSTAT_INFO(pmem_fifo_overflow_drop)},
++	{DRVSTAT_INFO(jabber_events)},
++	{DRVSTAT_INFO(rx_drops_no_pbuf)},
++	{DRVSTAT_INFO(rx_drops_no_txpb)},
++	{DRVSTAT_INFO(rx_drops_no_erx_descr)},
++	{DRVSTAT_INFO(rx_drops_no_tpre_descr)},
++	{DRVSTAT_INFO(rx_drops_too_many_frags)},
++	{DRVSTAT_INFO(rx_drops_invalid_ring)},
++	{DRVSTAT_INFO(forwarded_packets)},
++	{DRVSTAT_INFO(rx_drops_mtu)},
++	{DRVSTAT_INFO(eth_red_drops)},
++	{DRVSTAT_INFO(be_on_die_temperature)}
+ };
+ #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
+ 
++/* Stats related to multi RX queues */
++static const struct be_ethtool_stat et_rx_stats[] = {
++	{DRVSTAT_RX_INFO(rx_bytes)},
++	{DRVSTAT_RX_INFO(rx_pkts)},
++	{DRVSTAT_RX_INFO(rx_rate)},
++	{DRVSTAT_RX_INFO(rx_polls)},
++	{DRVSTAT_RX_INFO(rx_events)},
++	{DRVSTAT_RX_INFO(rx_compl)},
++	{DRVSTAT_RX_INFO(rx_mcast_pkts)},
++	{DRVSTAT_RX_INFO(rx_post_fail)},
++	{DRVSTAT_RX_INFO(rx_drops_no_frags)}
++};
++#define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats))
++
++/* Stats related to multi TX queues */
++static const struct be_ethtool_stat et_tx_stats[] = {
++	{DRVSTAT_TX_INFO(be_tx_rate)},
++	{DRVSTAT_TX_INFO(be_tx_reqs)},
++	{DRVSTAT_TX_INFO(be_tx_wrbs)},
++	{DRVSTAT_TX_INFO(be_tx_stops)},
++	{DRVSTAT_TX_INFO(be_tx_compl)},
++	{DRVSTAT_TX_INFO(be_ipv6_ext_hdr_tx_drop)}
++};
++#define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats))
++
++static const char et_self_tests[][ETH_GSTRING_LEN] = {
++	"MAC Loopback test",
++	"PHY Loopback test",
++	"External Loopback test",
++	"DDR DMA test",
++	"Link test"
++};
++
++#define ETHTOOL_TESTS_NUM ARRAY_SIZE(et_self_tests)
++#define BE_MAC_LOOPBACK 0x0
++#define BE_PHY_LOOPBACK 0x1
++#define BE_ONE_PORT_EXT_LOOPBACK 0x2
++#define BE_NO_LOOPBACK 0xff
++
++/* MAC speed valid values */
++#define SPEED_DEFAULT  0x0
++#define SPEED_FORCED_10GB  0x1
++#define SPEED_FORCED_1GB  0x2
++#define SPEED_AUTONEG_10GB  0x3
++#define SPEED_AUTONEG_1GB  0x4
++#define SPEED_AUTONEG_100MB  0x5
++#define SPEED_AUTONEG_10GB_1GB 0x6
++#define SPEED_AUTONEG_10GB_1GB_100MB 0x7
++#define SPEED_AUTONEG_1GB_100MB  0x8
++#define SPEED_AUTONEG_10MB  0x9
++#define SPEED_AUTONEG_1GB_100MB_10MB 0xa
++#define SPEED_AUTONEG_100MB_10MB 0xb
++#define SPEED_FORCED_100MB  0xc
++#define SPEED_FORCED_10MB  0xd
++
++
++
+ static void
+ be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
++	int len;
++	char fw_on_flash[FW_VER_LEN];
++
++	memset(fw_on_flash, 0 , sizeof(fw_on_flash));
++
++	be_cmd_get_fw_ver(adapter, adapter->fw_ver,
++				fw_on_flash);
+ 
+ 	strcpy(drvinfo->driver, DRV_NAME);
+ 	strcpy(drvinfo->version, DRV_VER);
++
+ 	strncpy(drvinfo->fw_version, adapter->fw_ver, FW_VER_LEN);
++	if (memcmp(adapter->fw_ver, fw_on_flash,
++				FW_VER_LEN) != 0) {
++		len = strlen(drvinfo->fw_version);
++		strncpy(drvinfo->fw_version+len, " [",
++				FW_VER_LEN-len-1);
++		len = strlen(drvinfo->fw_version);
++		strncpy(drvinfo->fw_version+len, fw_on_flash,
++				FW_VER_LEN-len-1);
++		len = strlen(drvinfo->fw_version);
++		strncpy(drvinfo->fw_version+len, "]", FW_VER_LEN-len-1);
++	}
++
+ 	strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
+ 	drvinfo->testinfo_len = 0;
+ 	drvinfo->regdump_len = 0;
+@@ -122,12 +181,37 @@ be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
  }
  
- /**
-diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
-index 234f0b7..3020aea 100644
---- a/drivers/scsi/megaraid/megaraid_mbox.c
-+++ b/drivers/scsi/megaraid/megaraid_mbox.c
-@@ -3503,6 +3503,8 @@ megaraid_cmm_register(adapter_t *adapter)
- 	int		rval;
- 	int		i;
- 
-+	pax_track_stack();
+ static int
++be_get_reg_len(struct net_device *netdev)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++	u32 log_size = 0;
 +
- 	// Allocate memory for the base list of scb for management module.
- 	adapter->uscb_list = kcalloc(MBOX_MAX_USER_CMDS, sizeof(scb_t), GFP_KERNEL);
- 
-diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
-index 7a117c1..ee01e9e 100644
---- a/drivers/scsi/osd/osd_initiator.c
-+++ b/drivers/scsi/osd/osd_initiator.c
-@@ -94,6 +94,8 @@ static int _osd_print_system_info(struct osd_dev *od, void *caps)
- 	int nelem = ARRAY_SIZE(get_attrs), a = 0;
- 	int ret;
- 
-+	pax_track_stack();
++	if (be_physfn(adapter))
++		be_cmd_get_reg_len(adapter, &log_size);
 +
- 	or = osd_start_request(od, GFP_KERNEL);
- 	if (!or)
- 		return -ENOMEM;
-diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
-index 9ab8c86..9425ad3 100644
---- a/drivers/scsi/pmcraid.c
-+++ b/drivers/scsi/pmcraid.c
-@@ -189,8 +189,8 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
- 		res->scsi_dev = scsi_dev;
- 		scsi_dev->hostdata = res;
- 		res->change_detected = 0;
--		atomic_set(&res->read_failures, 0);
--		atomic_set(&res->write_failures, 0);
-+		atomic_set_unchecked(&res->read_failures, 0);
-+		atomic_set_unchecked(&res->write_failures, 0);
- 		rc = 0;
++	return log_size;
++}
++
++static void
++be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++
++	if (be_physfn(adapter)) {
++		memset(buf, 0, regs->len);
++		be_cmd_get_regs(adapter, regs->len, buf);
++	}
++}
++
++static int
+ be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+-	struct be_eq_obj *rx_eq = &adapter->rx_eq;
++	struct be_eq_obj *rx_eq = &adapter->rx_obj[0].rx_eq;
+ 	struct be_eq_obj *tx_eq = &adapter->tx_eq;
+ 
++	coalesce->rx_max_coalesced_frames = adapter->max_rx_coal;
++
+ 	coalesce->rx_coalesce_usecs = rx_eq->cur_eqd;
+ 	coalesce->rx_coalesce_usecs_high = rx_eq->max_eqd;
+ 	coalesce->rx_coalesce_usecs_low = rx_eq->min_eqd;
+@@ -149,25 +233,52 @@ static int
+ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+-	struct be_eq_obj *rx_eq = &adapter->rx_eq;
++	struct be_rx_obj *rxo;
++	struct be_eq_obj *rx_eq;
+ 	struct be_eq_obj *tx_eq = &adapter->tx_eq;
+ 	u32 tx_max, tx_min, tx_cur;
+ 	u32 rx_max, rx_min, rx_cur;
+-	int status = 0;
++	int status = 0, i;
+ 
+ 	if (coalesce->use_adaptive_tx_coalesce == 1)
+ 		return -EINVAL;
++	adapter->max_rx_coal = coalesce->rx_max_coalesced_frames;
++	if (adapter->max_rx_coal > BE_MAX_FRAGS_PER_FRAME)
++		adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME;
+ 
+-	/* if AIC is being turned on now, start with an EQD of 0 */
+-	if (rx_eq->enable_aic == 0 &&
+-		coalesce->use_adaptive_rx_coalesce == 1) {
+-		rx_eq->cur_eqd = 0;
++	for_all_rx_queues(adapter, rxo, i) {
++		rx_eq = &rxo->rx_eq;
++
++		if (!rx_eq->enable_aic && coalesce->use_adaptive_rx_coalesce)
++			rx_eq->cur_eqd = 0;
++		rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce;
++
++		rx_max = coalesce->rx_coalesce_usecs_high;
++		rx_min = coalesce->rx_coalesce_usecs_low;
++		rx_cur = coalesce->rx_coalesce_usecs;
++
++		if (rx_eq->enable_aic) {
++			if (rx_max > BE_MAX_EQD)
++				rx_max = BE_MAX_EQD;
++			if (rx_min > rx_max)
++				rx_min = rx_max;
++			rx_eq->max_eqd = rx_max;
++			rx_eq->min_eqd = rx_min;
++			if (rx_eq->cur_eqd > rx_max)
++				rx_eq->cur_eqd = rx_max;
++			if (rx_eq->cur_eqd < rx_min)
++				rx_eq->cur_eqd = rx_min;
++		} else {
++			if (rx_cur > BE_MAX_EQD)
++				rx_cur = BE_MAX_EQD;
++			if (rx_eq->cur_eqd != rx_cur) {
++				status = be_cmd_modify_eqd(adapter, rx_eq->q.id,
++						rx_cur);
++				if (!status)
++					rx_eq->cur_eqd = rx_cur;
++			}
++		}
  	}
- 	spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
-@@ -2396,9 +2396,9 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
- 
- 	/* If this was a SCSI read/write command keep count of errors */
- 	if (SCSI_CMD_TYPE(scsi_cmd->cmnd[0]) == SCSI_READ_CMD)
--		atomic_inc(&res->read_failures);
-+		atomic_inc_unchecked(&res->read_failures);
- 	else if (SCSI_CMD_TYPE(scsi_cmd->cmnd[0]) == SCSI_WRITE_CMD)
--		atomic_inc(&res->write_failures);
-+		atomic_inc_unchecked(&res->write_failures);
+-	rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce;
+-
+-	rx_max = coalesce->rx_coalesce_usecs_high;
+-	rx_min = coalesce->rx_coalesce_usecs_low;
+-	rx_cur = coalesce->rx_coalesce_usecs;
+ 
+ 	tx_max = coalesce->tx_coalesce_usecs_high;
+ 	tx_min = coalesce->tx_coalesce_usecs_low;
+@@ -181,27 +292,6 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+ 			tx_eq->cur_eqd = tx_cur;
+ 	}
+ 
+-	if (rx_eq->enable_aic) {
+-		if (rx_max > BE_MAX_EQD)
+-			rx_max = BE_MAX_EQD;
+-		if (rx_min > rx_max)
+-			rx_min = rx_max;
+-		rx_eq->max_eqd = rx_max;
+-		rx_eq->min_eqd = rx_min;
+-		if (rx_eq->cur_eqd > rx_max)
+-			rx_eq->cur_eqd = rx_max;
+-		if (rx_eq->cur_eqd < rx_min)
+-			rx_eq->cur_eqd = rx_min;
+-	} else {
+-		if (rx_cur > BE_MAX_EQD)
+-			rx_cur = BE_MAX_EQD;
+-		if (rx_eq->cur_eqd != rx_cur) {
+-			status = be_cmd_modify_eqd(adapter, rx_eq->q.id,
+-					rx_cur);
+-			if (!status)
+-				rx_eq->cur_eqd = rx_cur;
+-		}
+-	}
+ 	return 0;
+ }
  
- 	if (!RES_IS_GSCSI(res->cfg_entry) &&
- 		masked_ioasc != PMCRAID_IOASC_HW_DEVICE_BUS_STATUS_ERROR) {
-@@ -4116,7 +4116,7 @@ static void pmcraid_worker_function(struct work_struct *workp)
+@@ -229,81 +319,294 @@ be_get_ethtool_stats(struct net_device *netdev,
+ 		struct ethtool_stats *stats, uint64_t *data)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+-	struct be_drvr_stats *drvr_stats = &adapter->stats.drvr_stats;
+-	struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va);
+-	struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
+-	struct be_port_rxf_stats *port_stats =
+-			&rxf_stats->port[adapter->port_num];
+-	struct net_device_stats *net_stats = &adapter->stats.net_stats;
+-	struct be_erx_stats *erx_stats = &hw_stats->erx;
++	struct be_rx_obj *rxo;
++	struct be_tx_obj *txo;
+ 	void *p = NULL;
+-	int i;
++	int i, j, base;
  
- 	pinstance = container_of(workp, struct pmcraid_instance, worker_q);
- 	/* add resources only after host is added into system */
--	if (!atomic_read(&pinstance->expose_resources))
-+	if (!atomic_read_unchecked(&pinstance->expose_resources))
- 		return;
+ 	for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
+ 		switch (et_stats[i].type) {
+ 		case NETSTAT:
+-			p = net_stats;
++			p = &adapter->net_stats;
+ 			break;
+ 		case DRVSTAT:
+-			p = drvr_stats;
+-			break;
+-		case PORTSTAT:
+-			p = port_stats;
+-			break;
+-		case MISCSTAT:
+-			p = rxf_stats;
+-			break;
+-		case ERXSTAT: /* Currently only one ERX stat is provided */
+-			p = (u32 *)erx_stats + adapter->rx_obj.q.id;
++			p = &adapter->drv_stats;
+ 			break;
+ 		}
  
- 	spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
-@@ -4850,7 +4850,7 @@ static int __devinit pmcraid_init_instance(
- 	init_waitqueue_head(&pinstance->reset_wait_q);
+ 		p = (u8 *)p + et_stats[i].offset;
+ 		data[i] = (et_stats[i].size == sizeof(u64)) ?
+-				*(u64 *)p: *(u32 *)p;
++				*(u64 *)p:(*(u32 *)p);
+ 	}
  
- 	atomic_set(&pinstance->outstanding_cmds, 0);
--	atomic_set(&pinstance->expose_resources, 0);
-+	atomic_set_unchecked(&pinstance->expose_resources, 0);
+-	return;
++	base = ETHTOOL_STATS_NUM;
++	for_all_rx_queues(adapter, rxo, j) {
++		for (i = 0; i < ETHTOOL_RXSTATS_NUM; i++) {
++			p = (u8 *)&rxo->stats + et_rx_stats[i].offset;
++			data[base + j * ETHTOOL_RXSTATS_NUM + i] =
++				(et_rx_stats[i].size == sizeof(u64)) ?
++					*(u64 *)p: *(u32 *)p;
++		}
++	}
++
++	base = ETHTOOL_STATS_NUM + adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM;
++	for_all_tx_queues(adapter, txo, j) {
++		for (i = 0; i < ETHTOOL_TXSTATS_NUM; i++) {
++			p = (u8 *)&txo->stats + et_tx_stats[i].offset;
++			data[base + j * ETHTOOL_TXSTATS_NUM + i] =
++				(et_tx_stats[i].size == sizeof(u64)) ?
++					*(u64 *)p: *(u32 *)p;
++		}
++	}
+ }
  
- 	INIT_LIST_HEAD(&pinstance->free_res_q);
- 	INIT_LIST_HEAD(&pinstance->used_res_q);
-@@ -5502,7 +5502,7 @@ static int __devinit pmcraid_probe(
- 	/* Schedule worker thread to handle CCN and take care of adding and
- 	 * removing devices to OS
- 	 */
--	atomic_set(&pinstance->expose_resources, 1);
-+	atomic_set_unchecked(&pinstance->expose_resources, 1);
- 	schedule_work(&pinstance->worker_q);
- 	return rc;
+ static void
+ be_get_stat_strings(struct net_device *netdev, uint32_t stringset,
+ 		uint8_t *data)
+ {
+-	int i;
++	struct be_adapter *adapter = netdev_priv(netdev);
++	int i, j;
++
+ 	switch (stringset) {
+ 	case ETH_SS_STATS:
+ 		for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
+ 			memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN);
+ 			data += ETH_GSTRING_LEN;
+ 		}
++		for (i = 0; i < adapter->num_rx_qs; i++) {
++			for (j = 0; j < ETHTOOL_RXSTATS_NUM; j++) {
++				sprintf(data, "rxq%d: %s", i,
++					et_rx_stats[j].desc);
++				data += ETH_GSTRING_LEN;
++			}
++		}
++		for (i = 0; i < adapter->num_tx_qs; i++) {
++			for (j = 0; j < ETHTOOL_TXSTATS_NUM; j++) {
++				sprintf(data, "txq%d: %s", i,
++					et_tx_stats[j].desc);
++				data += ETH_GSTRING_LEN;
++			}
++		}
++		break;
++	case ETH_SS_TEST:
++		for (i = 0; i < ETHTOOL_TESTS_NUM; i++) {
++			memcpy(data, et_self_tests[i], ETH_GSTRING_LEN);
++			data += ETH_GSTRING_LEN;
++		}
+ 		break;
+ 	}
+ }
  
-diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
-index 3441b3f..6cbe8f7 100644
---- a/drivers/scsi/pmcraid.h
-+++ b/drivers/scsi/pmcraid.h
-@@ -690,7 +690,7 @@ struct pmcraid_instance {
- 	atomic_t outstanding_cmds;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
+ static int be_get_stats_count(struct net_device *netdev)
+ {
+-	return ETHTOOL_STATS_NUM;
++	struct be_adapter *adapter = netdev_priv(netdev);
++
++	return ETHTOOL_STATS_NUM + adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM
++		+ adapter->num_tx_qs * ETHTOOL_TXSTATS_NUM;
+ }
++static int
++be_self_test_count(struct net_device *dev)
++{
++	return ETHTOOL_TESTS_NUM;
++}
++#else
++
++static int be_get_sset_count(struct net_device *netdev, int stringset)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++
++	switch (stringset) {
++	case ETH_SS_TEST:
++		return ETHTOOL_TESTS_NUM;
++	case ETH_SS_STATS:
++		return ETHTOOL_STATS_NUM +
++			adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM +
++			adapter->num_tx_qs * ETHTOOL_TXSTATS_NUM;
++	default:
++		return -EINVAL;
++	}
++}
++#endif
  
- 	/* should add/delete resources to mid-layer now ?*/
--	atomic_t expose_resources;
-+	atomic_unchecked_t expose_resources;
+ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ {
+-	ecmd->speed = SPEED_10000;
++	struct be_adapter *adapter = netdev_priv(netdev);
++	struct be_phy_info phy_info;
++	u8 mac_speed = 0;
++	u16 link_speed = 0;
++	int link_status = LINK_DOWN;
++	int status;
++
++	if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) {
++		status = be_cmd_link_status_query(adapter, &link_status,
++						&mac_speed, &link_speed, 0);
++
++		be_link_status_update(adapter, link_status);
++		/* link_speed is in units of 10 Mbps */
++		if (link_speed) {
++			ecmd->speed = link_speed*10;
++		} else {
++			switch (mac_speed) {
++			case PHY_LINK_SPEED_10MBPS:
++				ecmd->speed = SPEED_10;
++				break;
++			case PHY_LINK_SPEED_100MBPS:
++				ecmd->speed = SPEED_100;
++				break;
++			case PHY_LINK_SPEED_1GBPS:
++				ecmd->speed = SPEED_1000;
++				break;
++			case PHY_LINK_SPEED_10GBPS:
++				ecmd->speed = SPEED_10000;
++				break;
++			case PHY_LINK_SPEED_ZERO:
++				ecmd->speed = 0;
++				break;
++			}
++		}
++
++		status = be_cmd_get_phy_info(adapter, &phy_info);
++		if (!status) {
++			switch (phy_info.interface_type) {
++			case PHY_TYPE_XFP_10GB:
++			case PHY_TYPE_SFP_1GB:
++			case PHY_TYPE_SFP_PLUS_10GB:
++				ecmd->port = PORT_FIBRE;
++				break;
++			default:
++				ecmd->port = PORT_TP;
++				break;
++			}
++
++			switch (phy_info.interface_type) {
++			case PHY_TYPE_KR_10GB:
++			case PHY_TYPE_KX4_10GB:
++			ecmd->transceiver = XCVR_INTERNAL;
++				break;
++			default:
++				ecmd->transceiver = XCVR_EXTERNAL;
++				break;
++			}
++
++			if (phy_info.auto_speeds_supported) {
++				ecmd->supported |= SUPPORTED_Autoneg;
++				ecmd->autoneg = AUTONEG_ENABLE;
++				ecmd->advertising |= ADVERTISED_Autoneg;
++			}
++
++			if (phy_info.misc_params & BE_PAUSE_SYM_EN) {
++				ecmd->supported |= SUPPORTED_Pause;
++				ecmd->advertising |= ADVERTISED_Pause;
++			}
++
++		}
++
++		/* Save for future use */
++		adapter->link_speed = ecmd->speed;
++		adapter->port_type = ecmd->port;
++		adapter->transceiver = ecmd->transceiver;
++		adapter->autoneg = ecmd->autoneg;
++	} else {
++		ecmd->speed = adapter->link_speed;
++		ecmd->port = adapter->port_type;
++		ecmd->transceiver = adapter->transceiver;
++		ecmd->autoneg = adapter->autoneg;
++	}
++
+ 	ecmd->duplex = DUPLEX_FULL;
+-	ecmd->autoneg = AUTONEG_DISABLE;
++	ecmd->phy_address = (adapter->hba_port_num << 4) |
++		(adapter->port_name[adapter->hba_port_num]);
++	switch (ecmd->port) {
++	case PORT_FIBRE:
++		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
++		break;
++	case PORT_TP:
++		ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_TP);
++		break;
++	}
++
++	if (ecmd->autoneg) {
++		ecmd->supported |= SUPPORTED_1000baseT_Full;
++		ecmd->advertising |= (ADVERTISED_10000baseT_Full |
++				ADVERTISED_1000baseT_Full);
++	}
++
+ 	return 0;
+ }
  
- 	/* Tasklet to handle deferred processing */
- 	struct tasklet_struct isr_tasklet[PMCRAID_NUM_MSIX_VECTORS];
-@@ -727,8 +727,8 @@ struct pmcraid_resource_entry {
- 	struct list_head queue;	/* link to "to be exposed" resources */
- 	struct pmcraid_config_table_entry cfg_entry;
- 	struct scsi_device *scsi_dev;	/* Link scsi_device structure */
--	atomic_t read_failures;		/* count of failed READ commands */
--	atomic_t write_failures;	/* count of failed WRITE commands */
-+	atomic_unchecked_t read_failures;		/* count of failed READ commands */
-+	atomic_unchecked_t write_failures;	/* count of failed WRITE commands */
++static int be_set_settings(struct net_device *netdev,
++				struct ethtool_cmd *ecmd)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++	struct be_phy_info phy_info;
++	u16 mac_speed=0;
++	u16 dac_cable_len=0;
++	u16 port_speed = 0;
++	int status;
++
++	status = be_cmd_get_phy_info(adapter, &phy_info);
++	if (status) {
++		dev_warn(&adapter->pdev->dev, "port speed set failed.\n");
++		return status;
++	}
++
++	if (ecmd->autoneg == AUTONEG_ENABLE) {
++		switch(phy_info.interface_type) {
++		case PHY_TYPE_SFP_1GB:
++		case PHY_TYPE_BASET_1GB:
++		case PHY_TYPE_BASEX_1GB:
++		case PHY_TYPE_SGMII:
++			mac_speed = SPEED_AUTONEG_1GB_100MB_10MB;
++			break;
++		case PHY_TYPE_SFP_PLUS_10GB:
++			 dev_warn(&adapter->pdev->dev,
++			"Autoneg not supported on this module. \n");
++			 return -EINVAL;
++		case PHY_TYPE_KR_10GB:
++		case PHY_TYPE_KX4_10GB:
++			 mac_speed = SPEED_AUTONEG_10GB_1GB;
++			 break;
++		case PHY_TYPE_BASET_10GB:
++			 mac_speed = SPEED_AUTONEG_10GB_1GB_100MB;
++			 break;
++		}
++	} else if(ecmd->autoneg == AUTONEG_DISABLE) {
++		if(ecmd->speed == SPEED_10) {
++			mac_speed = SPEED_FORCED_10MB;
++		} else if(ecmd->speed == SPEED_100) {
++			 mac_speed = SPEED_FORCED_100MB;
++		} else if(ecmd->speed == SPEED_1000) {
++			 mac_speed = SPEED_FORCED_1GB;
++		} else if(ecmd->speed == SPEED_10000) {
++			 mac_speed = SPEED_FORCED_10GB;
++		}
++	}
++
++	status = be_cmd_get_port_speed(adapter, adapter->hba_port_num,
++				&dac_cable_len, &port_speed);
++
++	if (!status && port_speed != mac_speed)
++		status = be_cmd_set_port_speed_v1(adapter,
++				adapter->hba_port_num,  mac_speed,
++				dac_cable_len);
++	if (status)
++		dev_warn(&adapter->pdev->dev, "port speed set failed.\n");
++
++	return status;
++
++}
++
+ static void
+ be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
  
- 	/* To indicate add/delete/modify during CCN */
- 	u8 change_detected;
-diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
-index 2150618..7034215 100644
---- a/drivers/scsi/qla2xxx/qla_def.h
-+++ b/drivers/scsi/qla2xxx/qla_def.h
-@@ -2089,7 +2089,7 @@ struct isp_operations {
+-	ring->rx_max_pending = adapter->rx_obj.q.len;
+-	ring->tx_max_pending = adapter->tx_obj.q.len;
++	ring->rx_max_pending = adapter->rx_obj[0].q.len;
++	ring->tx_max_pending = adapter->tx_obj[0].q.len;
  
- 	int (*get_flash_version) (struct scsi_qla_host *, void *);
- 	int (*start_scsi) (srb_t *);
--};
-+} __no_const;
+-	ring->rx_pending = atomic_read(&adapter->rx_obj.q.used);
+-	ring->tx_pending = atomic_read(&adapter->tx_obj.q.used);
++	ring->rx_pending = atomic_read(&adapter->rx_obj[0].q.used);
++	ring->tx_pending = atomic_read(&adapter->tx_obj[0].q.used);
+ }
  
- /* MSI-X Support *************************************************************/
+ static void
+@@ -312,7 +615,7 @@ be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
+ 	struct be_adapter *adapter = netdev_priv(netdev);
  
-diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
-index 81b5f29..2ae1fad 100644
---- a/drivers/scsi/qla4xxx/ql4_def.h
-+++ b/drivers/scsi/qla4xxx/ql4_def.h
-@@ -240,7 +240,7 @@ struct ddb_entry {
- 	atomic_t retry_relogin_timer; /* Min Time between relogins
- 				       * (4000 only) */
- 	atomic_t relogin_timer;	/* Max Time to wait for relogin to complete */
--	atomic_t relogin_retry_count; /* Num of times relogin has been
-+	atomic_unchecked_t relogin_retry_count; /* Num of times relogin has been
- 				       * retried */
+ 	be_cmd_get_flow_control(adapter, &ecmd->tx_pause, &ecmd->rx_pause);
+-	ecmd->autoneg = 0;
++	ecmd->autoneg = adapter->autoneg;
+ }
  
- 	uint16_t port;
-diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
-index af8c323..515dd51 100644
---- a/drivers/scsi/qla4xxx/ql4_init.c
-+++ b/drivers/scsi/qla4xxx/ql4_init.c
-@@ -482,7 +482,7 @@ static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
- 	atomic_set(&ddb_entry->port_down_timer, ha->port_down_retry_count);
- 	atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY);
- 	atomic_set(&ddb_entry->relogin_timer, 0);
--	atomic_set(&ddb_entry->relogin_retry_count, 0);
-+	atomic_set_unchecked(&ddb_entry->relogin_retry_count, 0);
- 	atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
- 	list_add_tail(&ddb_entry->list, &ha->ddb_list);
- 	ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry;
-@@ -1308,7 +1308,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha,
- 		atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
- 		atomic_set(&ddb_entry->port_down_timer,
- 			   ha->port_down_retry_count);
--		atomic_set(&ddb_entry->relogin_retry_count, 0);
-+		atomic_set_unchecked(&ddb_entry->relogin_retry_count, 0);
- 		atomic_set(&ddb_entry->relogin_timer, 0);
- 		clear_bit(DF_RELOGIN, &ddb_entry->flags);
- 		clear_bit(DF_NO_RELOGIN, &ddb_entry->flags);
-diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
-index 83c8b5e..a82b348 100644
---- a/drivers/scsi/qla4xxx/ql4_os.c
-+++ b/drivers/scsi/qla4xxx/ql4_os.c
-@@ -641,13 +641,13 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
- 			    ddb_entry->fw_ddb_device_state ==
- 			    DDB_DS_SESSION_FAILED) {
- 				/* Reset retry relogin timer */
--				atomic_inc(&ddb_entry->relogin_retry_count);
-+				atomic_inc_unchecked(&ddb_entry->relogin_retry_count);
- 				DEBUG2(printk("scsi%ld: index[%d] relogin"
- 					      " timed out-retrying"
- 					      " relogin (%d)\n",
- 					      ha->host_no,
- 					      ddb_entry->fw_ddb_index,
--					      atomic_read(&ddb_entry->
-+					      atomic_read_unchecked(&ddb_entry->
- 							  relogin_retry_count))
- 					);
- 				start_dpc++;
-diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
-index dd098ca..686ce01 100644
---- a/drivers/scsi/scsi.c
-+++ b/drivers/scsi/scsi.c
-@@ -652,7 +652,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
- 	unsigned long timeout;
- 	int rtn = 0;
+ static int
+@@ -334,6 +637,203 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
+ 	return status;
+ }
  
--	atomic_inc(&cmd->device->iorequest_cnt);
-+	atomic_inc_unchecked(&cmd->device->iorequest_cnt);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++static int
++be_phys_id(struct net_device *netdev, u32 data)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++	int status;
++	u32 cur;
++
++	be_cmd_get_beacon_state(adapter, adapter->hba_port_num, &cur);
++
++	if (cur == BEACON_STATE_ENABLED)
++		return 0;
++
++	if (data < 2)
++		data = 2;
++
++	status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
++			BEACON_STATE_ENABLED);
++	set_current_state(TASK_INTERRUPTIBLE);
++	schedule_timeout(data*HZ);
++
++	status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
++			BEACON_STATE_DISABLED);
++
++	return status;
++}
++#else
++static int
++be_set_phys_id(struct net_device *netdev,
++		enum ethtool_phys_id_state state)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++
++	switch (state) {
++	case ETHTOOL_ID_ACTIVE:
++		be_cmd_get_beacon_state(adapter, adapter->hba_port_num,
++					&adapter->beacon_state);
++	return 1;       /* cycle on/off once per second */
++
++	case ETHTOOL_ID_ON:
++		be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
++					BEACON_STATE_ENABLED);
++		break;
++
++	case ETHTOOL_ID_OFF:
++		be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
++					BEACON_STATE_DISABLED);
++		break;
++
++	case ETHTOOL_ID_INACTIVE:
++		be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
++					adapter->beacon_state);
++	}
++
++	return 0;
++}
++#endif
++
++static bool
++be_is_wol_supported(struct be_adapter *adapter)
++{
++	struct pci_dev *pdev = adapter->pdev;
++
++	if (!be_physfn(adapter))
++		return false;
++
++	switch (pdev->subsystem_device) {
++	case OC_SUBSYS_DEVICE_ID1:
++	case OC_SUBSYS_DEVICE_ID2:
++	case OC_SUBSYS_DEVICE_ID3:
++	case OC_SUBSYS_DEVICE_ID4:
++		return false;
++	default:
++		return true;
++	}
++}
++
++static void
++be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++
++	if (be_is_wol_supported(adapter))
++		wol->supported = WAKE_MAGIC;
++	if (adapter->wol)
++		wol->wolopts = WAKE_MAGIC;
++	else
++		wol->wolopts = 0;
++	memset(&wol->sopass, 0, sizeof(wol->sopass));
++}
++
++static int
++be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++
++	if (wol->wolopts & ~WAKE_MAGIC)
++		return -EOPNOTSUPP;
++
++	if (!be_is_wol_supported(adapter)) {
++		dev_warn(&adapter->pdev->dev,
++			"WOL not supported for this subsystemid: %x\n",
++			adapter->pdev->subsystem_device);
++		return -EOPNOTSUPP;
++	}
++
++	if (wol->wolopts & WAKE_MAGIC)
++		adapter->wol = true;
++	else
++		adapter->wol = false;
++
++	return 0;
++}
++
++static int
++be_test_ddr_dma(struct be_adapter *adapter)
++{
++	int ret, i;
++	struct be_dma_mem ddrdma_cmd;
++	u64 pattern[2] = {0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL};
++
++	ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test);
++	ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size,
++					&ddrdma_cmd.dma);
++	if (!ddrdma_cmd.va) {
++		dev_err(&adapter->pdev->dev, "Memory allocation failure\n");
++		return -ENOMEM;
++	}
++
++	for (i = 0; i < 2; i++) {
++		ret = be_cmd_ddr_dma_test(adapter, pattern[i],
++					4096, &ddrdma_cmd);
++		if (ret != 0)
++			goto err;
++	}
++
++err:
++	pci_free_consistent(adapter->pdev, ddrdma_cmd.size,
++			ddrdma_cmd.va, ddrdma_cmd.dma);
++	return ret;
++}
++
++static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type,
++				u64 *status)
++{
++	be_cmd_set_loopback(adapter, adapter->hba_port_num,
++				loopback_type, 1);
++	*status = be_cmd_loopback_test(adapter, adapter->hba_port_num,
++				loopback_type, 1500,
++				2, 0xabc);
++	be_cmd_set_loopback(adapter, adapter->hba_port_num,
++				BE_NO_LOOPBACK, 1);
++	return *status;
++}
++
++static void
++be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++	int link_status;
++	u8 mac_speed = 0;
++	u16 qos_link_speed = 0;
++
++	memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
++
++	if (test->flags & ETH_TEST_FL_OFFLINE) {
++		if (be_loopback_test(adapter, BE_MAC_LOOPBACK,
++						&data[0]) != 0) {
++			test->flags |= ETH_TEST_FL_FAILED;
++		}
++		if (be_loopback_test(adapter, BE_PHY_LOOPBACK,
++						&data[1]) != 0) {
++			test->flags |= ETH_TEST_FL_FAILED;
++		}
++		if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK,
++						&data[2]) != 0) {
++			test->flags |= ETH_TEST_FL_FAILED;
++		}
++	}
++
++	if (be_test_ddr_dma(adapter) != 0) {
++		data[3] = 1;
++		test->flags |= ETH_TEST_FL_FAILED;
++	}
++
++	if (be_cmd_link_status_query(adapter, &link_status, &mac_speed,
++				&qos_link_speed, 0) != 0) {
++		test->flags |= ETH_TEST_FL_FAILED;
++		data[4] = -1;
++	} else if (!mac_speed) {
++		test->flags |= ETH_TEST_FL_FAILED;
++		data[4] = 1;
++	}
++
++}
++
++#ifdef HAVE_ETHTOOL_FLASH
+ static int
+ be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
+ {
+@@ -347,11 +847,73 @@ be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
  
- 	/* check if the device is still usable */
- 	if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
-diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
-index bc3e363..e1a8e50 100644
---- a/drivers/scsi/scsi_debug.c
-+++ b/drivers/scsi/scsi_debug.c
-@@ -1395,6 +1395,8 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
- 	unsigned char arr[SDEBUG_MAX_MSELECT_SZ];
- 	unsigned char *cmd = (unsigned char *)scp->cmnd;
+ 	return be_load_fw(adapter, file_name);
+ }
++#endif
  
-+	pax_track_stack();
+-const struct ethtool_ops be_ethtool_ops = {
++static int
++be_get_eeprom_len(struct net_device *netdev)
++{
++	return BE_READ_SEEPROM_LEN;
++}
++
++static int
++be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
++			uint8_t *data)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++	struct be_dma_mem eeprom_cmd;
++	struct be_cmd_resp_seeprom_read *resp;
++	int status;
++
++	if (!eeprom->len)
++		return -EINVAL;
++
++	eeprom->magic = BE_VENDOR_ID | (adapter->pdev->device<<16);
++
++	memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem));
++	eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read);
++	eeprom_cmd.va = pci_alloc_consistent(adapter->pdev, eeprom_cmd.size,
++				&eeprom_cmd.dma);
++
++	if (!eeprom_cmd.va) {
++		dev_err(&adapter->pdev->dev,
++			"Memory allocation failure. Could not read eeprom\n");
++		return -ENOMEM;
++	}
++
++	status = be_cmd_get_seeprom_data(adapter, &eeprom_cmd);
++
++	if (!status) {
++		resp = (struct be_cmd_resp_seeprom_read *) eeprom_cmd.va;
++		memcpy(data, resp->seeprom_data + eeprom->offset, eeprom->len);
++	}
++	pci_free_consistent(adapter->pdev, eeprom_cmd.size, eeprom_cmd.va,
++			eeprom_cmd.dma);
++
++	return status;
++}
++
++static int be_set_tso(struct net_device *netdev, uint32_t data)
++{
++	if (data) {
++		netdev->features |= NETIF_F_TSO;
++		netdev->features |= NETIF_F_TSO6;
++	} else {
++		netdev->features &= ~NETIF_F_TSO;
++		netdev->features &= ~NETIF_F_TSO6;
++	}
++	return 0;
++}
++
++
++struct ethtool_ops be_ethtool_ops = {
+ 	.get_settings = be_get_settings,
++	.set_settings = be_set_settings,
+ 	.get_drvinfo = be_get_drvinfo,
++	.get_wol = be_get_wol,
++	.set_wol = be_set_wol,
+ 	.get_link = ethtool_op_get_link,
++	.get_eeprom_len = be_get_eeprom_len,
++	.get_eeprom = be_read_eeprom,
+ 	.get_coalesce = be_get_coalesce,
+ 	.set_coalesce = be_set_coalesce,
+ 	.get_ringparam = be_get_ringparam,
+@@ -364,9 +926,21 @@ const struct ethtool_ops be_ethtool_ops = {
+ 	.get_sg = ethtool_op_get_sg,
+ 	.set_sg = ethtool_op_set_sg,
+ 	.get_tso = ethtool_op_get_tso,
+-	.set_tso = ethtool_op_set_tso,
++	.set_tso = be_set_tso,
+ 	.get_strings = be_get_stat_strings,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
++	.phys_id = be_phys_id,
+ 	.get_stats_count = be_get_stats_count,
++	.self_test_count = be_self_test_count,
++#else
++	.set_phys_id = be_set_phys_id,
++	.get_sset_count = be_get_sset_count,
++#endif
+ 	.get_ethtool_stats = be_get_ethtool_stats,
++	.get_regs_len = be_get_reg_len,
++	.get_regs = be_get_regs,
++#ifdef HAVE_ETHTOOL_FLASH
+ 	.flash_device = be_do_flash,
++#endif
++	.self_test = be_self_test
+ };
+diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h
+index a3394b4..f871d8c 100644
+--- a/drivers/net/benet/be_hw.h
++++ b/drivers/net/benet/be_hw.h
+@@ -1,18 +1,18 @@
+ /*
+- * Copyright (C) 2005 - 2009 ServerEngines
++ * Copyright (C) 2005 - 2011 Emulex
+  * All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation.  The full GNU General
++ * as published by the Free Software Foundation. The full GNU General
+  * Public License is included in this distribution in the file called COPYING.
+  *
+  * Contact Information:
+- * linux-drivers@serverengines.com
++ * linux-drivers@emulex.com
+  *
+- * ServerEngines
+- * 209 N. Fair Oaks Ave
+- * Sunnyvale, CA 94085
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
+  */
+ 
+ /********* Mailbox door bell *************/
+@@ -26,24 +26,34 @@
+  * queue entry.
+  */
+ #define MPU_MAILBOX_DB_OFFSET	0x160
+-#define MPU_MAILBOX_DB_RDY_MASK	0x1 	/* bit 0 */
++#define MPU_MAILBOX_DB_RDY_MASK	0x1	/* bit 0 */
+ #define MPU_MAILBOX_DB_HI_MASK	0x2	/* bit 1 */
+ 
+-#define MPU_EP_CONTROL 		0
++#define MPU_EP_CONTROL			0
+ 
+ /********** MPU semphore ******************/
+-#define MPU_EP_SEMAPHORE_OFFSET 	0xac
++#define MPU_EP_SEMAPHORE_OFFSET		0xac
++#define MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET	0x400
+ #define EP_SEMAPHORE_POST_STAGE_MASK	0x0000FFFF
+ #define EP_SEMAPHORE_POST_ERR_MASK	0x1
+ #define EP_SEMAPHORE_POST_ERR_SHIFT	31
+ /* MPU semphore POST stage values */
+-#define POST_STAGE_AWAITING_HOST_RDY 	0x1 /* FW awaiting goahead from host */
+-#define POST_STAGE_HOST_RDY 		0x2 /* Host has given go-ahed to FW */
++#define POST_STAGE_AWAITING_HOST_RDY	0x1 /* FW awaiting goahead from host */
++#define POST_STAGE_HOST_RDY		0x2 /* Host has given go-ahed to FW */
+ #define POST_STAGE_BE_RESET		0x3 /* Host wants to reset chip */
+ #define POST_STAGE_ARMFW_RDY		0xc000	/* FW is done with POST */
+ 
++/* Lancer SLIPORT_CONTROL SLIPORT_STATUS registers */
++#define SLIPORT_STATUS_OFFSET		0x404
++#define SLIPORT_CONTROL_OFFSET		0x408
++
++#define SLIPORT_STATUS_ERR_MASK		0x80000000
++#define SLIPORT_STATUS_RN_MASK		0x01000000
++#define SLIPORT_STATUS_RDY_MASK		0x00800000
++#define SLI_PORT_CONTROL_IP_MASK	0x08000000
++
+ /********* Memory BAR register ************/
+-#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 	0xfc
++#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET	0xfc
+ /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
+  * Disable" may still globally block interrupts in addition to individual
+  * interrupt masks; a mechanism for the device driver to block all interrupts
+@@ -52,13 +62,70 @@
+  */
+ #define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK	(1 << 29) /* bit 29 */
+ 
++/********* Link Status CSR ****************/
++#define PCICFG_PCIE_LINK_STATUS_OFFSET		0xd0
++#define PCIE_LINK_STATUS_SPEED_MASK		0xFF	/* bits 16 - 19 */
++#define PCIE_LINK_STATUS_SPEED_SHIFT		16
++#define PCIE_LINK_STATUS_NEG_WIDTH_MASK		0x3F	/* bits 20 - 25 */
++#define PCIE_LINK_STATUS_NEG_WIDTH_SHIFT	20
++
++/********* Link Capability CSR ************/
++#define PCICFG_PCIE_LINK_CAP_OFFSET		0xcc
++#define PCIE_LINK_CAP_MAX_SPEED_MASK		0xFF	/* bits 0 - 3 */
++#define PCIE_LINK_CAP_MAX_SPEED_SHIFT		0
++#define PCIE_LINK_CAP_MAX_WIDTH_MASK		0x3F	/* bits 4 - 9 */
++#define PCIE_LINK_CAP_MAX_WIDTH_SHIFT		4
++
++/********* PCI Function Capability ************/
++#define BE_FUNCTION_CAPS_UNCLASSIFIED_STATS	0x1
++#define BE_FUNCTION_CAPS_RSS			0x2
++#define BE_FUNCTION_CAPS_PROMISCUOUS		0x4
++#define BE_FUNCTION_CAPS_LEGACY_MODE		0x8
++
++/********* Power managment (WOL) **********/
++#define PCICFG_PM_CONTROL_OFFSET		0x44
++#define PCICFG_PM_CONTROL_MASK			0x108	/* bits 3 & 8 */
++
++/********* Online Control Registers *******/
++#define PCICFG_ONLINE0				0xB0
++#define PCICFG_ONLINE1				0xB4
++
++/********* UE Status and Mask Registers ***/
++#define PCICFG_UE_STATUS_LOW			0xA0
++#define PCICFG_UE_STATUS_HIGH			0xA4
++#define PCICFG_UE_STATUS_LOW_MASK		0xA8
++#define PCICFG_UE_STATUS_HI_MASK		0xAC
++
++/******** SLI_INTF ***********************/
++#define SLI_INTF_REG_OFFSET			0x58
++#define SLI_INTF_VALID_MASK			0xE0000000
++#define SLI_INTF_VALID				0xC0000000
++#define SLI_INTF_HINT2_MASK			0x1F000000
++#define SLI_INTF_HINT2_SHIFT			24
++#define SLI_INTF_HINT1_MASK			0x00FF0000
++#define SLI_INTF_HINT1_SHIFT			16
++#define SLI_INTF_FAMILY_MASK			0x00000F00
++#define SLI_INTF_FAMILY_SHIFT			8
++#define SLI_INTF_IF_TYPE_MASK			0x0000F000
++#define SLI_INTF_IF_TYPE_SHIFT			12
++#define SLI_INTF_REV_MASK			0x000000F0
++#define SLI_INTF_REV_SHIFT			4
++#define SLI_INTF_FT_MASK			0x00000001
++
++/* SLI family */
++#define BE_SLI_FAMILY		0x0
++#define LANCER_A0_SLI_FAMILY	0xA
++
+ /********* ISR0 Register offset **********/
+-#define CEV_ISR0_OFFSET 			0xC18
++#define CEV_ISR0_OFFSET				0xC18
+ #define CEV_ISR_SIZE				4
+ 
+ /********* Event Q door bell *************/
+ #define DB_EQ_OFFSET			DB_CQ_OFFSET
+ #define DB_EQ_RING_ID_MASK		0x1FF	/* bits 0 - 8 */
++#define DB_EQ_RING_ID_EXT_MASK		0x3e00  /* bits 9-13 */
++#define DB_EQ_RING_ID_EXT_MASK_SHIFT	(2) /* qid bits 9-13 placing at 11-15 */
++
+ /* Clear the interrupt for this eq */
+ #define DB_EQ_CLR_SHIFT			(9)	/* bit 9 */
+ /* Must be 1 */
+@@ -69,12 +136,16 @@
+ #define DB_EQ_REARM_SHIFT		(29)	/* bit 29 */
+ 
+ /********* Compl Q door bell *************/
+-#define DB_CQ_OFFSET 			0x120
++#define DB_CQ_OFFSET			0x120
+ #define DB_CQ_RING_ID_MASK		0x3FF	/* bits 0 - 9 */
++#define DB_CQ_RING_ID_EXT_MASK		0x7C00	/* bits 10-14 */
++#define DB_CQ_RING_ID_EXT_MASK_SHIFT	(1)	/* qid bits 10-14
++						 placing at 11-15 */
++
+ /* Number of event entries processed */
+-#define DB_CQ_NUM_POPPED_SHIFT		(16) 	/* bits 16 - 28 */
++#define DB_CQ_NUM_POPPED_SHIFT		(16)	/* bits 16 - 28 */
+ /* Rearm bit */
+-#define DB_CQ_REARM_SHIFT		(29) 	/* bit 29 */
++#define DB_CQ_REARM_SHIFT		(29)	/* bit 29 */
+ 
+ /********** TX ULP door bell *************/
+ #define DB_TXULP1_OFFSET		0x60
+@@ -84,25 +155,103 @@
+ #define DB_TXULP_NUM_POSTED_MASK	0x3FFF	/* bits 16 - 29 */
+ 
+ /********** RQ(erx) door bell ************/
+-#define DB_RQ_OFFSET 			0x100
++#define DB_RQ_OFFSET			0x100
+ #define DB_RQ_RING_ID_MASK		0x3FF	/* bits 0 - 9 */
+ /* Number of rx frags posted */
+ #define DB_RQ_NUM_POSTED_SHIFT		(24)	/* bits 24 - 31 */
+ 
+ /********** MCC door bell ************/
+-#define DB_MCCQ_OFFSET 			0x140
++#define DB_MCCQ_OFFSET			0x140
+ #define DB_MCCQ_RING_ID_MASK		0x7FF	/* bits 0 - 10 */
+ /* Number of entries posted */
+ #define DB_MCCQ_NUM_POSTED_SHIFT	(16)	/* bits 16 - 29 */
+ 
++/********** SRIOV VF PCICFG OFFSET ********/
++#define SRIOV_VF_PCICFG_OFFSET          (4096)
++
++/********** FAT TABLE  ********/
++#define RETRIEVE_FAT	0
++#define QUERY_FAT	1
++
++/* Flashrom related descriptors */
++#define IMAGE_TYPE_FIRMWARE		160
++#define IMAGE_TYPE_BOOTCODE		224
++#define IMAGE_TYPE_OPTIONROM		32
++
++#define NUM_FLASHDIR_ENTRIES		32
++
++#define IMG_TYPE_ISCSI_ACTIVE		0
++#define IMG_TYPE_REDBOOT		1
++#define IMG_TYPE_BIOS			2
++#define IMG_TYPE_PXE_BIOS		3
++#define IMG_TYPE_FCOE_BIOS		8
++#define IMG_TYPE_ISCSI_BACKUP		9
++#define IMG_TYPE_FCOE_FW_ACTIVE		10
++#define IMG_TYPE_FCOE_FW_BACKUP		11
++#define IMG_TYPE_NCSI_FW		13
++#define IMG_TYPE_PHY_FW			99
++#define TN_8022				13
++
++#define ILLEGAL_IOCTL_REQ		2
++#define FLASHROM_OPER_PHY_FLASH		9
++#define FLASHROM_OPER_PHY_SAVE		10
++#define FLASHROM_OPER_FLASH		1
++#define FLASHROM_OPER_SAVE		2
++#define FLASHROM_OPER_REPORT		4
++
++#define FLASH_IMAGE_MAX_SIZE_g2		(1310720) /* Max firmware image size */
++#define FLASH_BIOS_IMAGE_MAX_SIZE_g2	(262144)  /* Max OPTION ROM image sz */
++#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g2	(262144)  /* Max Redboot image sz    */
++#define FLASH_IMAGE_MAX_SIZE_g3		(2097152) /* Max firmware image size */
++#define FLASH_BIOS_IMAGE_MAX_SIZE_g3	(524288)  /* Max OPTION ROM image sz */
++#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3	(1048576)  /* Max Redboot image sz    */
++#define FLASH_NCSI_IMAGE_MAX_SIZE_g3	(262144)
++#define FLASH_PHY_FW_IMAGE_MAX_SIZE_g3	(262144)
++
++#define FLASH_NCSI_MAGIC		(0x16032009)
++#define FLASH_NCSI_DISABLED		(0)
++#define FLASH_NCSI_ENABLED		(1)
++
++#define FLASH_NCSI_BITFILE_HDR_OFFSET	(0x600000)
++
++/* Offsets for components on Flash. */
++#define FLASH_iSCSI_PRIMARY_IMAGE_START_g2	(1048576)
++#define FLASH_iSCSI_BACKUP_IMAGE_START_g2	(2359296)
++#define FLASH_FCoE_PRIMARY_IMAGE_START_g2	(3670016)
++#define FLASH_FCoE_BACKUP_IMAGE_START_g2	(4980736)
++#define FLASH_iSCSI_BIOS_START_g2		(7340032)
++#define FLASH_PXE_BIOS_START_g2			(7864320)
++#define FLASH_FCoE_BIOS_START_g2		(524288)
++#define FLASH_REDBOOT_START_g2			(0)
++
++#define FLASH_NCSI_START_g3			(15990784)
++#define FLASH_iSCSI_PRIMARY_IMAGE_START_g3	(2097152)
++#define FLASH_iSCSI_BACKUP_IMAGE_START_g3	(4194304)
++#define FLASH_FCoE_PRIMARY_IMAGE_START_g3	(6291456)
++#define FLASH_FCoE_BACKUP_IMAGE_START_g3	(8388608)
++#define FLASH_iSCSI_BIOS_START_g3		(12582912)
++#define FLASH_PXE_BIOS_START_g3			(13107200)
++#define FLASH_FCoE_BIOS_START_g3		(13631488)
++#define FLASH_REDBOOT_START_g3			(262144)
++#define FLASH_PHY_FW_START_g3			(1310720)
++
++/************* Rx Packet Type Encoding **************/
++#define BE_UNICAST_PACKET		0
++#define BE_MULTICAST_PACKET		1
++#define BE_BROADCAST_PACKET		2
++#define BE_RSVD_PACKET			3
++
+ /*
+  * BE descriptors: host memory data structures whose formats
+  * are hardwired in BE silicon.
+  */
+ /* Event Queue Descriptor */
+-#define EQ_ENTRY_VALID_MASK 		0x1	/* bit 0 */
+-#define EQ_ENTRY_RES_ID_MASK 		0xFFFF	/* bits 16 - 31 */
+-#define EQ_ENTRY_RES_ID_SHIFT 		16
++#define EQ_ENTRY_VALID_MASK		0x1	/* bit 0 */
++#define EQ_ENTRY_RES_ID_MASK		0xFFFF	/* bits 16 - 31 */
++#define EQ_ENTRY_RES_ID_SHIFT		16
++
++#define BE_MAC_PROMISCUOUS		62	/* Promiscuous mode */
++
+ struct be_eq_entry {
+ 	u32 evt;
+ };
+@@ -126,7 +275,7 @@ struct amap_eth_hdr_wrb {
+ 	u8 event;
+ 	u8 crc;
+ 	u8 forward;
+-	u8 ipsec;
++	u8 lso6;
+ 	u8 mgmt;
+ 	u8 ipcs;
+ 	u8 udpcs;
+@@ -151,7 +300,7 @@ struct be_eth_hdr_wrb {
+  * offset/shift/mask of each field */
+ struct amap_eth_tx_compl {
+ 	u8 wrb_index[16];	/* dword 0 */
+-	u8 ct[2]; 		/* dword 0 */
++	u8 ct[2];		/* dword 0 */
+ 	u8 port[2];		/* dword 0 */
+ 	u8 rsvd0[8];		/* dword 0 */
+ 	u8 status[4];		/* dword 0 */
+@@ -179,10 +328,10 @@ struct be_eth_rx_d {
+ 
+ /* RX Compl Queue Descriptor */
+ 
+-/* Pseudo amap definition for eth_rx_compl in which each bit of the
+- * actual structure is defined as a byte: used to calculate
++/* Pseudo amap definition for BE2 and BE3 legacy mode eth_rx_compl in which
++ * each bit of the actual structure is defined as a byte: used to calculate
+  * offset/shift/mask of each field */
+-struct amap_eth_rx_compl {
++struct amap_eth_rx_compl_v0 {
+ 	u8 vlan_tag[16];	/* dword 0 */
+ 	u8 pktsize[14];		/* dword 0 */
+ 	u8 port;		/* dword 0 */
+@@ -213,39 +362,91 @@ struct amap_eth_rx_compl {
+ 	u8 rsshash[32];		/* dword 3 */
+ } __packed;
+ 
++/* Pseudo amap definition for BE3 native mode eth_rx_compl in which
++ * each bit of the actual structure is defined as a byte: used to calculate
++ * offset/shift/mask of each field */
++struct amap_eth_rx_compl_v1 {
++	u8 vlan_tag[16];	/* dword 0 */
++	u8 pktsize[14];		/* dword 0 */
++	u8 vtp;			/* dword 0 */
++	u8 ip_opt;		/* dword 0 */
++	u8 err;			/* dword 1 */
++	u8 rsshp;		/* dword 1 */
++	u8 ipf;			/* dword 1 */
++	u8 tcpf;		/* dword 1 */
++	u8 udpf;		/* dword 1 */
++	u8 ipcksm;		/* dword 1 */
++	u8 l4_cksm;		/* dword 1 */
++	u8 ip_version;		/* dword 1 */
++	u8 macdst[7];		/* dword 1 */
++	u8 rsvd0;		/* dword 1 */
++	u8 fragndx[10];		/* dword 1 */
++	u8 ct[2];		/* dword 1 */
++	u8 sw;			/* dword 1 */
++	u8 numfrags[3];		/* dword 1 */
++	u8 rss_flush;		/* dword 2 */
++	u8 cast_enc[2];		/* dword 2 */
++	u8 vtm;			/* dword 2 */
++	u8 rss_bank;		/* dword 2 */
++	u8 port[2];		/* dword 2 */
++	u8 vntagp;		/* dword 2 */
++	u8 header_len[8];	/* dword 2 */
++	u8 header_split[2];	/* dword 2 */
++	u8 rsvd1[13];		/* dword 2 */
++	u8 valid;		/* dword 2 */
++	u8 rsshash[32];		/* dword 3 */
++} __packed;
++
+ struct be_eth_rx_compl {
+ 	u32 dw[4];
+ };
+ 
+-/* Flashrom related descriptors */
+-#define IMAGE_TYPE_FIRMWARE		160
+-#define IMAGE_TYPE_BOOTCODE		224
+-#define IMAGE_TYPE_OPTIONROM		32
++struct mgmt_hba_attribs {
++	u8 flashrom_version_string[32];
++	u8 manufacturer_name[32];
++	u32 supported_modes;
++	u32 rsvd0[3];
++	u8 ncsi_ver_string[12];
++	u32 default_extended_timeout;
++	u8 controller_model_number[32];
++	u8 controller_description[64];
++	u8 controller_serial_number[32];
++	u8 ip_version_string[32];
++	u8 firmware_version_string[32];
++	u8 bios_version_string[32];
++	u8 redboot_version_string[32];
++	u8 driver_version_string[32];
++	u8 fw_on_flash_version_string[32];
++	u32 functionalities_supported;
++	u16 max_cdblength;
++	u8 asic_revision;
++	u8 generational_guid[16];
++	u8 hba_port_count;
++	u16 default_link_down_timeout;
++	u8 iscsi_ver_min_max;
++	u8 multifunction_device;
++	u8 cache_valid;
++	u8 hba_status;
++	u8 max_domains_supported;
++	u8 phy_port;
++	u32 firmware_post_status;
++	u32 hba_mtu[8];
++	u32 rsvd1[4];
++};
+ 
+-#define NUM_FLASHDIR_ENTRIES		32
+-
+-#define FLASHROM_TYPE_ISCSI_ACTIVE	0
+-#define FLASHROM_TYPE_BIOS		2
+-#define FLASHROM_TYPE_PXE_BIOS		3
+-#define FLASHROM_TYPE_FCOE_BIOS		8
+-#define FLASHROM_TYPE_ISCSI_BACKUP	9
+-#define FLASHROM_TYPE_FCOE_FW_ACTIVE	10
+-#define FLASHROM_TYPE_FCOE_FW_BACKUP 	11
+-
+-#define FLASHROM_OPER_FLASH		1
+-#define FLASHROM_OPER_SAVE		2
+-
+-#define FLASH_IMAGE_MAX_SIZE            (1310720) /* Max firmware image size */
+-#define FLASH_BIOS_IMAGE_MAX_SIZE       (262144)  /* Max OPTION ROM image sz */
+-
+-/* Offsets for components on Flash. */
+-#define FLASH_iSCSI_PRIMARY_IMAGE_START (1048576)
+-#define FLASH_iSCSI_BACKUP_IMAGE_START  (2359296)
+-#define FLASH_FCoE_PRIMARY_IMAGE_START  (3670016)
+-#define FLASH_FCoE_BACKUP_IMAGE_START   (4980736)
+-#define FLASH_iSCSI_BIOS_START          (7340032)
+-#define FLASH_PXE_BIOS_START            (7864320)
+-#define FLASH_FCoE_BIOS_START           (524288)
++struct mgmt_controller_attrib {
++	struct mgmt_hba_attribs hba_attribs;
++	u16 pci_vendor_id;
++	u16 pci_device_id;
++	u16 pci_sub_vendor_id;
++	u16 pci_sub_system_id;
++	u8 pci_bus_number;
++	u8 pci_device_number;
++	u8 pci_function_number;
++	u8 interface_type;
++	u64 unique_identifier;
++	u32 rsvd0[5];
++};
+ 
+ struct controller_id {
+ 	u32 vendor;
+@@ -254,7 +455,20 @@ struct controller_id {
+ 	u32 subdevice;
+ };
+ 
+-struct flash_file_hdr {
++struct flash_comp {
++	unsigned long offset;
++	int optype;
++	int size;
++};
++
++struct image_hdr {
++	u32 imageid;
++	u32 imageoffset;
++	u32 imagelength;
++	u32 image_checksum;
++	u8 image_version[32];
++};
++struct flash_file_hdr_g2 {
+ 	u8 sign[32];
+ 	u32 cksum;
+ 	u32 antidote;
+@@ -266,6 +480,17 @@ struct flash_file_hdr {
+ 	u8 build[24];
+ };
+ 
++struct flash_file_hdr_g3 {
++	u8 sign[52];
++	u8 ufi_version[4];
++	u32 file_len;
++	u32 cksum;
++	u32 antidote;
++	u32 num_imgs;
++	u8 build[24];
++	u8 rsvd[32];
++};
++
+ struct flash_section_hdr {
+ 	u32 format_rev;
+ 	u32 cksum;
+@@ -299,3 +524,19 @@ struct flash_section_info {
+ 	struct flash_section_hdr fsec_hdr;
+ 	struct flash_section_entry fsec_entry[32];
+ };
++
++struct flash_ncsi_image_hdr {
++	u32 magic;
++	u8 hdr_len;
++	u8 type;
++	u16 hdr_ver;
++	u8 rsvd0[2];
++	u16 load_offset;
++	u32 len;
++	u32 flash_offset;
++	u8 ver[16];
++	u8 name[24];
++	u32 img_cksum;
++	u8 rsvd1[4];
++	u32 hdr_cksum;
++};
+diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
+index 000e377..f501aa3 100644
+--- a/drivers/net/benet/be_main.c
++++ b/drivers/net/benet/be_main.c
+@@ -1,18 +1,18 @@
+ /*
+- * Copyright (C) 2005 - 2009 ServerEngines
++ * Copyright (C) 2005 - 2011 Emulex
+  * All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License version 2
+- * as published by the Free Software Foundation.  The full GNU General
++ * as published by the Free Software Foundation. The full GNU General
+  * Public License is included in this distribution in the file called COPYING.
+  *
+  * Contact Information:
+- * linux-drivers@serverengines.com
++ * linux-drivers@emulex.com
+  *
+- * ServerEngines
+- * 209 N. Fair Oaks Ave
+- * Sunnyvale, CA 94085
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
+  */
+ 
+ #include "be.h"
+@@ -22,23 +22,119 @@
+ MODULE_VERSION(DRV_VER);
+ MODULE_DEVICE_TABLE(pci, be_dev_ids);
+ MODULE_DESCRIPTION(DRV_DESC " " DRV_VER);
+-MODULE_AUTHOR("ServerEngines Corporation");
++MODULE_AUTHOR("Emulex Corporation");
+ MODULE_LICENSE("GPL");
++MODULE_INFO(supported, "external");
+ 
+-static unsigned int rx_frag_size = 2048;
+-module_param(rx_frag_size, uint, S_IRUGO);
+-MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data.");
++static ushort rx_frag_size = 2048;
++static unsigned int num_vfs;
++static unsigned int msix = 1;
++module_param(rx_frag_size, ushort, S_IRUGO);
++module_param(num_vfs, uint, S_IRUGO);
++module_param(msix, uint, S_IRUGO);
++MODULE_PARM_DESC(rx_frag_size, "Size of receive fragment buffer"
++				" - 2048 (default), 4096 or 8192");
++MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize");
++MODULE_PARM_DESC(msix, "Enable and disable the MSI"
++				"x (By default MSIx is enabled)");
++static unsigned int gro = 1;
++module_param(gro, uint, S_IRUGO);
++MODULE_PARM_DESC(gro, "Enable or Disable GRO. Enabled by default");
++
++static unsigned int multi_rxq = true;
++module_param(multi_rxq, uint, S_IRUGO);
++MODULE_PARM_DESC(multi_rxq, "Multi Rx Queue support. Enabled by default");
+ 
+ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
+ 	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
+ 	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) },
+ 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
+ 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
+-	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID3) },
++	/*
++	 * Lancer is not part of Palau 4.0
++	 * { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)},
++	 */
+ 	{ 0 }
+ };
+ MODULE_DEVICE_TABLE(pci, be_dev_ids);
+ 
++/* UE Status Low CSR */
++static char *ue_status_low_desc[] = {
++	"CEV",
++	"CTX",
++	"DBUF",
++	"ERX",
++	"Host",
++	"MPU",
++	"NDMA",
++	"PTC ",
++	"RDMA ",
++	"RXF ",
++	"RXIPS ",
++	"RXULP0 ",
++	"RXULP1 ",
++	"RXULP2 ",
++	"TIM ",
++	"TPOST ",
++	"TPRE ",
++	"TXIPS ",
++	"TXULP0 ",
++	"TXULP1 ",
++	"UC ",
++	"WDMA ",
++	"TXULP2 ",
++	"HOST1 ",
++	"P0_OB_LINK ",
++	"P1_OB_LINK ",
++	"HOST_GPIO ",
++	"MBOX ",
++	"AXGMAC0",
++	"AXGMAC1",
++	"JTAG",
++	"MPU_INTPEND"
++};
++
++/* UE Status High CSR */
++static char *ue_status_hi_desc[] = {
++	"LPCMEMHOST",
++	"MGMT_MAC",
++	"PCS0ONLINE",
++	"MPU_IRAM",
++	"PCS1ONLINE",
++	"PCTL0",
++	"PCTL1",
++	"PMEM",
++	"RR",
++	"TXPB",
++	"RXPP",
++	"XAUI",
++	"TXP",
++	"ARM",
++	"IPC",
++	"HOST2",
++	"HOST3",
++	"HOST4",
++	"HOST5",
++	"HOST6",
++	"HOST7",
++	"HOST8",
++	"HOST9",
++	"NETC",
++	"Unknown",
++	"Unknown",
++	"Unknown",
++	"Unknown",
++	"Unknown",
++	"Unknown",
++	"Unknown",
++	"Unknown"
++};
++
++static inline bool be_multi_rxq(struct be_adapter *adapter)
++{
++	return (adapter->num_rx_qs > 1);
++}
++
+ static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q)
+ {
+ 	struct be_dma_mem *mem = &q->dma_mem;
+@@ -69,6 +165,9 @@ static void be_intr_set(struct be_adapter *adapter, bool enable)
+ 	u32 reg = ioread32(addr);
+ 	u32 enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
+ 
++	if (adapter->eeh_err)
++		return;
++
+ 	if (!enabled && enable)
+ 		reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
+ 	else if (enabled && !enable)
+@@ -84,6 +183,8 @@ static void be_rxq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
+ 	u32 val = 0;
+ 	val |= qid & DB_RQ_RING_ID_MASK;
+ 	val |= posted << DB_RQ_NUM_POSTED_SHIFT;
++
++	wmb();
+ 	iowrite32(val, adapter->db + DB_RQ_OFFSET);
+ }
+ 
+@@ -92,6 +193,8 @@ static void be_txq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
+ 	u32 val = 0;
+ 	val |= qid & DB_TXULP_RING_ID_MASK;
+ 	val |= (posted & DB_TXULP_NUM_POSTED_MASK) << DB_TXULP_NUM_POSTED_SHIFT;
++
++	wmb();
+ 	iowrite32(val, adapter->db + DB_TXULP1_OFFSET);
+ }
+ 
+@@ -100,6 +203,12 @@ static void be_eq_notify(struct be_adapter *adapter, u16 qid,
+ {
+ 	u32 val = 0;
+ 	val |= qid & DB_EQ_RING_ID_MASK;
++	val |= ((qid & DB_EQ_RING_ID_EXT_MASK) <<
++			DB_EQ_RING_ID_EXT_MASK_SHIFT);
++
++	if (adapter->eeh_err)
++		return;
++
+ 	if (arm)
+ 		val |= 1 << DB_EQ_REARM_SHIFT;
+ 	if (clear_int)
+@@ -113,6 +222,12 @@ void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped)
+ {
+ 	u32 val = 0;
+ 	val |= qid & DB_CQ_RING_ID_MASK;
++	val |= ((qid & DB_CQ_RING_ID_EXT_MASK) <<
++			DB_CQ_RING_ID_EXT_MASK_SHIFT);
++
++	if (adapter->eeh_err)
++		return;
++
+ 	if (arm)
+ 		val |= 1 << DB_CQ_REARM_SHIFT;
+ 	val |= num_popped << DB_CQ_NUM_POPPED_SHIFT;
+@@ -124,96 +239,250 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+ 	struct sockaddr *addr = p;
+ 	int status = 0;
++	u8 current_mac[ETH_ALEN];
++	u32 pmac_id = adapter->pmac_id;
+ 
+-	status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id);
++	if (!is_valid_ether_addr(addr->sa_data))
++		return -EADDRNOTAVAIL;
++
++	status = be_cmd_mac_addr_query(adapter, current_mac,
++			MAC_ADDRESS_TYPE_NETWORK, false,
++			adapter->if_handle);
+ 	if (status)
+-		return status;
++		goto err;
++
++	if (!memcmp(addr->sa_data, current_mac, ETH_ALEN))
++		goto done;
+ 
+ 	status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
+-			adapter->if_handle, &adapter->pmac_id);
+-	if (!status)
++			adapter->if_handle, &adapter->pmac_id, 0);
++
++	if (!status) {
++		status = be_cmd_pmac_del(adapter, adapter->if_handle,
++				pmac_id, 0);
+ 		memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
++		goto done;
++	}
+ 
+-	return status;
++err:
++	if (status == MCC_STATUS_UNAUTHORIZED_REQUEST)
++		return -EPERM;
++	else
++		dev_err(&adapter->pdev->dev, "MAC %pM set Failed\n",
++				addr->sa_data);
++done:
++		return status;
++}
++
++static void populate_be2_stats(struct be_adapter *adapter)
++{
++
++	struct be_drv_stats *drvs = &adapter->drv_stats;
++	struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter);
++	struct be_port_rxf_stats_v0 *port_stats =
++		be_port_rxf_stats_from_cmd(adapter);
++	struct be_rxf_stats_v0 *rxf_stats =
++		be_rxf_stats_from_cmd(adapter);
++
++	drvs->rx_pause_frames = port_stats->rx_pause_frames;
++	drvs->rx_crc_errors = port_stats->rx_crc_errors;
++	drvs->rx_control_frames = port_stats->rx_control_frames;
++	drvs->rx_in_range_errors = port_stats->rx_in_range_errors;
++	drvs->rx_frame_too_long = port_stats->rx_frame_too_long;
++	drvs->rx_dropped_runt = port_stats->rx_dropped_runt;
++	drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
++	drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
++	drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
++	drvs->rxpp_fifo_overflow_drop = port_stats->rx_fifo_overflow;
++	drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length;
++	drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
++	drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
++	drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
++	drvs->rx_input_fifo_overflow_drop =
++		port_stats->rx_input_fifo_overflow;
++	drvs->rx_dropped_header_too_small =
++		port_stats->rx_dropped_header_too_small;
++	drvs->rx_address_match_errors =
++		port_stats->rx_address_match_errors;
++	drvs->rx_alignment_symbol_errors =
++		port_stats->rx_alignment_symbol_errors;
++
++	drvs->tx_pauseframes = port_stats->tx_pauseframes;
++	drvs->tx_controlframes = port_stats->tx_controlframes;
++
++	if (adapter->port_num)
++		drvs->jabber_events =
++			rxf_stats->port1_jabber_events;
++	else
++		drvs->jabber_events =
++			rxf_stats->port0_jabber_events;
++	drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
++	drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
++	drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
++	drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
++	drvs->forwarded_packets = rxf_stats->forwarded_packets;
++	drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
++	drvs->rx_drops_no_tpre_descr =
++		rxf_stats->rx_drops_no_tpre_descr;
++	drvs->rx_drops_too_many_frags =
++		rxf_stats->rx_drops_too_many_frags;
++	adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
++}
++
++static void populate_be3_stats(struct be_adapter *adapter)
++{
++	struct be_drv_stats *drvs = &adapter->drv_stats;
++	struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter);
++
++	struct be_rxf_stats_v1 *rxf_stats =
++		be_rxf_stats_from_cmd(adapter);
++	struct be_port_rxf_stats_v1 *port_stats =
++		be_port_rxf_stats_from_cmd(adapter);
++
++	drvs->pmem_fifo_overflow_drop = port_stats->pmem_fifo_overflow_drop;
++	drvs->rx_priority_pause_frames = port_stats->rx_priority_pause_frames;
++	drvs->rx_pause_frames = port_stats->rx_pause_frames;
++	drvs->rx_crc_errors = port_stats->rx_crc_errors;
++	drvs->rx_control_frames = port_stats->rx_control_frames;
++	drvs->rx_in_range_errors = port_stats->rx_in_range_errors;
++	drvs->rx_frame_too_long = port_stats->rx_frame_too_long;
++	drvs->rx_dropped_runt = port_stats->rx_dropped_runt;
++	drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
++	drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
++	drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
++	drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length;
++	drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
++	drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
++	drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
++	drvs->rx_dropped_header_too_small =
++		port_stats->rx_dropped_header_too_small;
++	drvs->rx_input_fifo_overflow_drop =
++		port_stats->rx_input_fifo_overflow_drop;
++	drvs->rx_address_match_errors =
++		port_stats->rx_address_match_errors;
++	drvs->rx_alignment_symbol_errors =
++		port_stats->rx_alignment_symbol_errors;
++	drvs->rxpp_fifo_overflow_drop =
++		port_stats->rxpp_fifo_overflow_drop;
++	drvs->tx_pauseframes = port_stats->tx_pauseframes;
++	drvs->tx_controlframes = port_stats->tx_controlframes;
++	drvs->jabber_events = port_stats->jabber_events;
++	drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
++	drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
++	drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
++	drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
++	drvs->forwarded_packets = rxf_stats->forwarded_packets;
++	drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
++	drvs->rx_drops_no_tpre_descr =
++		rxf_stats->rx_drops_no_tpre_descr;
++	drvs->rx_drops_too_many_frags =
++		rxf_stats->rx_drops_too_many_frags;
++	adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
++}
++
++
++static void accumulate_16bit_val(u32 *acc, u16 val)
++{
++#define lo(x)			(x & 0xFFFF)
++#define hi(x)			(x & 0xFFFF0000)
++	bool wrapped = val < lo(*acc);
++	u32 newacc = hi(*acc) + val;
++
++	if (wrapped)
++		newacc += 65536;
++	ACCESS_ONCE_RW(*acc) = newacc;
++}
++
++void be_parse_stats(struct be_adapter *adapter)
++{
++	struct be_erx_stats_v1 *erx = be_erx_stats_from_cmd(adapter);
++	struct be_rx_obj *rxo;
++	int i;
++
++	if (adapter->generation == BE_GEN3) {
++			populate_be3_stats(adapter);
++	} else {
++		populate_be2_stats(adapter);
++	}
++
++	/* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */
++	for_all_rx_queues(adapter, rxo, i) {
++		/* below erx HW counter can actually wrap around after
++		 * 65535. Driver accumulates a 32-bit value
++		 */
++		accumulate_16bit_val(&rx_stats(rxo)->rx_drops_no_frags,
++				(u16)erx->rx_drops_no_fragments[rxo->q.id]);
++	}
+ }
+ 
+ void netdev_stats_update(struct be_adapter *adapter)
+ {
+-	struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va);
+-	struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
+-	struct be_port_rxf_stats *port_stats =
+-			&rxf_stats->port[adapter->port_num];
+-	struct net_device_stats *dev_stats = &adapter->stats.net_stats;
+-	struct be_erx_stats *erx_stats = &hw_stats->erx;
++	struct be_drv_stats *drvs = &adapter->drv_stats;
++	struct net_device_stats *dev_stats = &adapter->net_stats;
++	struct be_rx_obj *rxo;
++	struct be_tx_obj *txo;
++	unsigned long pkts = 0, bytes = 0, mcast = 0, drops = 0;
++	int i;
+ 
+-	dev_stats->rx_packets = drvr_stats(adapter)->be_rx_pkts;
+-	dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts;
+-	dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes;
+-	dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes;
++	for_all_rx_queues(adapter, rxo, i) {
++		pkts += rx_stats(rxo)->rx_pkts;
++		bytes += rx_stats(rxo)->rx_bytes;
++		mcast += rx_stats(rxo)->rx_mcast_pkts;
++		drops += rx_stats(rxo)->rx_drops_no_frags;
++	}
++	dev_stats->rx_packets = pkts;
++	dev_stats->rx_bytes = bytes;
++	dev_stats->multicast = mcast;
++	dev_stats->rx_dropped = drops;
++
++	pkts = bytes = 0;
++	for_all_tx_queues(adapter, txo, i) {
++		pkts += tx_stats(txo)->be_tx_pkts;
++		bytes += tx_stats(txo)->be_tx_bytes;
++	}
++	dev_stats->tx_packets = pkts;
++	dev_stats->tx_bytes = bytes;
+ 
+ 	/* bad pkts received */
+-	dev_stats->rx_errors = port_stats->rx_crc_errors +
+-		port_stats->rx_alignment_symbol_errors +
+-		port_stats->rx_in_range_errors +
+-		port_stats->rx_out_range_errors +
+-		port_stats->rx_frame_too_long +
+-		port_stats->rx_dropped_too_small +
+-		port_stats->rx_dropped_too_short +
+-		port_stats->rx_dropped_header_too_small +
+-		port_stats->rx_dropped_tcp_length +
+-		port_stats->rx_dropped_runt +
+-		port_stats->rx_tcp_checksum_errs +
+-		port_stats->rx_ip_checksum_errs +
+-		port_stats->rx_udp_checksum_errs;
+-
+-	/*  no space in linux buffers: best possible approximation */
+-	dev_stats->rx_dropped = erx_stats->rx_drops_no_fragments[0];
++	dev_stats->rx_errors = drvs->rx_crc_errors +
++		drvs->rx_alignment_symbol_errors +
++		drvs->rx_in_range_errors +
++		drvs->rx_out_range_errors +
++		drvs->rx_frame_too_long +
++		drvs->rx_dropped_too_small +
++		drvs->rx_dropped_too_short +
++		drvs->rx_dropped_header_too_small +
++		drvs->rx_dropped_tcp_length +
++		drvs->rx_dropped_runt +
++		drvs->rx_tcp_checksum_errs +
++		drvs->rx_ip_checksum_errs +
++		drvs->rx_udp_checksum_errs;
+ 
+ 	/* detailed rx errors */
+-	dev_stats->rx_length_errors = port_stats->rx_in_range_errors +
+-		port_stats->rx_out_range_errors +
+-		port_stats->rx_frame_too_long;
++	dev_stats->rx_length_errors = drvs->rx_in_range_errors +
++		drvs->rx_out_range_errors +
++		drvs->rx_frame_too_long;
+ 
+-	/* receive ring buffer overflow */
+-	dev_stats->rx_over_errors = 0;
+-
+-	dev_stats->rx_crc_errors = port_stats->rx_crc_errors;
++	dev_stats->rx_crc_errors = drvs->rx_crc_errors;
+ 
+ 	/* frame alignment errors */
+-	dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors;
++	dev_stats->rx_frame_errors = drvs->rx_alignment_symbol_errors;
+ 
+ 	/* receiver fifo overrun */
+ 	/* drops_no_pbuf is no per i/f, it's per BE card */
+-	dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow +
+-					port_stats->rx_input_fifo_overflow +
+-					rxf_stats->rx_drops_no_pbuf;
+-	/* receiver missed packetd */
+-	dev_stats->rx_missed_errors = 0;
+-
+-	/*  packet transmit problems */
+-	dev_stats->tx_errors = 0;
+-
+-	/* no space available in linux */
+-	dev_stats->tx_dropped = 0;
+-
+-	dev_stats->multicast = port_stats->rx_multicast_frames;
+-	dev_stats->collisions = 0;
+-
+-	/* detailed tx_errors */
+-	dev_stats->tx_aborted_errors = 0;
+-	dev_stats->tx_carrier_errors = 0;
+-	dev_stats->tx_fifo_errors = 0;
+-	dev_stats->tx_heartbeat_errors = 0;
+-	dev_stats->tx_window_errors = 0;
++	dev_stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop +
++				drvs->rx_input_fifo_overflow_drop +
++				drvs->rx_drops_no_pbuf;
+ }
+ 
+-void be_link_status_update(struct be_adapter *adapter, bool link_up)
++void be_link_status_update(struct be_adapter *adapter, int link_status)
+ {
+ 	struct net_device *netdev = adapter->netdev;
+ 
+ 	/* If link came up or went down */
+-	if (adapter->link_up != link_up) {
+-		if (link_up) {
++	if (adapter->link_status != link_status) {
++		adapter->link_speed = -1;
++		if (link_status == LINK_UP) {
+ 			netif_start_queue(netdev);
+ 			netif_carrier_on(netdev);
+ 			printk(KERN_INFO "%s: Link up\n", netdev->name);
+@@ -222,15 +491,15 @@ void be_link_status_update(struct be_adapter *adapter, bool link_up)
+ 			netif_carrier_off(netdev);
+ 			printk(KERN_INFO "%s: Link down\n", netdev->name);
+ 		}
+-		adapter->link_up = link_up;
++		adapter->link_status = link_status;
+ 	}
+ }
+ 
+ /* Update the EQ delay n BE based on the RX frags consumed / sec */
+-static void be_rx_eqd_update(struct be_adapter *adapter)
++static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo)
+ {
+-	struct be_eq_obj *rx_eq = &adapter->rx_eq;
+-	struct be_drvr_stats *stats = &adapter->stats.drvr_stats;
++	struct be_eq_obj *rx_eq = &rxo->rx_eq;
++	struct be_rx_stats *stats = &rxo->stats;
+ 	ulong now = jiffies;
+ 	u32 eqd;
+ 
+@@ -247,19 +516,17 @@ static void be_rx_eqd_update(struct be_adapter *adapter)
+ 	if ((now - stats->rx_fps_jiffies) < HZ)
+ 		return;
+ 
+-	stats->be_rx_fps = (stats->be_rx_frags - stats->be_prev_rx_frags) /
++	stats->rx_fps = (stats->rx_frags - stats->prev_rx_frags) /
+ 			((now - stats->rx_fps_jiffies) / HZ);
+ 
+ 	stats->rx_fps_jiffies = now;
+-	stats->be_prev_rx_frags = stats->be_rx_frags;
+-	eqd = stats->be_rx_fps / 110000;
++	stats->prev_rx_frags = stats->rx_frags;
++	eqd = stats->rx_fps / 110000;
+ 	eqd = eqd << 3;
+ 	if (eqd > rx_eq->max_eqd)
+ 		eqd = rx_eq->max_eqd;
+ 	if (eqd < rx_eq->min_eqd)
+ 		eqd = rx_eq->min_eqd;
+-	if (eqd < 10)
+-		eqd = 0;
+ 	if (eqd != rx_eq->cur_eqd)
+ 		be_cmd_modify_eqd(adapter, rx_eq->q.id, eqd);
+ 
+@@ -270,7 +537,7 @@ static struct net_device_stats *be_get_stats(struct net_device *dev)
+ {
+ 	struct be_adapter *adapter = netdev_priv(dev);
+ 
+-	return &adapter->stats.net_stats;
++	return &adapter->net_stats;
+ }
+ 
+ static u32 be_calc_rate(u64 bytes, unsigned long ticks)
+@@ -284,9 +551,9 @@ static u32 be_calc_rate(u64 bytes, unsigned long ticks)
+ 	return rate;
+ }
+ 
+-static void be_tx_rate_update(struct be_adapter *adapter)
++static void be_tx_rate_update(struct be_tx_obj *txo)
+ {
+-	struct be_drvr_stats *stats = drvr_stats(adapter);
++	struct be_tx_stats *stats = tx_stats(txo);
+ 	ulong now = jiffies;
+ 
+ 	/* Wrapped around? */
+@@ -305,10 +572,11 @@ static void be_tx_rate_update(struct be_adapter *adapter)
+ 	}
+ }
+ 
+-static void be_tx_stats_update(struct be_adapter *adapter,
++static void be_tx_stats_update(struct be_tx_obj *txo,
+ 			u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped)
+ {
+-	struct be_drvr_stats *stats = drvr_stats(adapter);
++	struct be_tx_stats *stats = tx_stats(txo);
++
+ 	stats->be_tx_reqs++;
+ 	stats->be_tx_wrbs += wrb_cnt;
+ 	stats->be_tx_bytes += copied;
+@@ -318,7 +586,8 @@ static void be_tx_stats_update(struct be_adapter *adapter,
+ }
+ 
+ /* Determine number of WRB entries needed to xmit data in an skb */
+-static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy)
++static u32 wrb_cnt_for_skb(struct be_adapter *adapter, struct sk_buff *skb,
++							bool *dummy)
+ {
+ 	int cnt = (skb->len > skb->data_len);
+ 
+@@ -326,12 +595,13 @@ static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy)
+ 
+ 	/* to account for hdr wrb */
+ 	cnt++;
+-	if (cnt & 1) {
++	if (lancer_chip(adapter) || !(cnt & 1)) {
++		*dummy = false;
++	} else {
+ 		/* add a dummy to make it an even num */
+ 		cnt++;
+ 		*dummy = true;
+-	} else
+-		*dummy = false;
++	}
+ 	BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT);
+ 	return cnt;
+ }
+@@ -343,17 +613,31 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len)
+ 	wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK;
+ }
+ 
+-static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
+-		bool vlan, u32 wrb_cnt, u32 len)
++static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
++		struct sk_buff *skb, u32 wrb_cnt, u32 len)
+ {
++	u16 vlan_tag = 0;
++
+ 	memset(hdr, 0, sizeof(*hdr));
+ 
+ 	AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
+ 
+-	if (skb_shinfo(skb)->gso_segs > 1 && skb_shinfo(skb)->gso_size) {
++	if (skb_is_gso(skb)) {
+ 		AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1);
+ 		AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss,
+ 			hdr, skb_shinfo(skb)->gso_size);
++		if (skb_is_gso_v6(skb) && !lancer_chip(adapter))
++			AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1);
++
++		if (lancer_A0_chip(adapter)) {
++			AMAP_SET_BITS(struct amap_eth_hdr_wrb, ipcs, hdr, 1);
++			if (is_tcp_pkt(skb))
++				AMAP_SET_BITS(struct amap_eth_hdr_wrb,
++								tcpcs, hdr, 1);
++			else if (is_udp_pkt(skb))
++				AMAP_SET_BITS(struct amap_eth_hdr_wrb,
++								udpcs, hdr, 1);
++		}
+ 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ 		if (is_tcp_pkt(skb))
+ 			AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1);
+@@ -361,10 +645,10 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
+ 			AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
+ 	}
+ 
+-	if (vlan && vlan_tx_tag_present(skb)) {
++	if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
+ 		AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
+-		AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag,
+-			hdr, vlan_tx_tag_get(skb));
++		vlan_tag = be_get_tx_vlan_tag(adapter, skb);
++		AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag);
+ 	}
+ 
+ 	AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1);
+@@ -374,14 +658,13 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
+ }
+ 
+ 
+-static int make_tx_wrbs(struct be_adapter *adapter,
++static int make_tx_wrbs(struct be_adapter *adapter, struct be_queue_info *txq,
+ 		struct sk_buff *skb, u32 wrb_cnt, bool dummy_wrb)
+ {
+-	u64 busaddr;
+-	u32 i, copied = 0;
++	dma_addr_t busaddr;
++	int i, copied = 0;
+ 	struct pci_dev *pdev = adapter->pdev;
+ 	struct sk_buff *first_skb = skb;
+-	struct be_queue_info *txq = &adapter->tx_obj.q;
+ 	struct be_eth_wrb *wrb;
+ 	struct be_eth_hdr_wrb *hdr;
+ 
+@@ -389,15 +672,11 @@ static int make_tx_wrbs(struct be_adapter *adapter,
+ 	atomic_add(wrb_cnt, &txq->used);
+ 	queue_head_inc(txq);
+ 
+-	if (skb_dma_map(&pdev->dev, skb, DMA_TO_DEVICE)) {
+-		dev_err(&pdev->dev, "TX DMA mapping failed\n");
+-		return 0;
+-	}
+-
+ 	if (skb->len > skb->data_len) {
+-		int len = skb->len - skb->data_len;
++		int len = skb_headlen(skb);
++		busaddr = pci_map_single(pdev, skb->data, len,
++					 PCI_DMA_TODEVICE);
+ 		wrb = queue_head_node(txq);
+-		busaddr = skb_shinfo(skb)->dma_head;
+ 		wrb_fill(wrb, busaddr, len);
+ 		be_dws_cpu_to_le(wrb, sizeof(*wrb));
+ 		queue_head_inc(txq);
+@@ -407,8 +686,9 @@ static int make_tx_wrbs(struct be_adapter *adapter,
+ 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ 		struct skb_frag_struct *frag =
+ 			&skb_shinfo(skb)->frags[i];
+-
+-		busaddr = skb_shinfo(skb)->dma_maps[i];
++		busaddr = pci_map_page(pdev, frag->page,
++				       frag->page_offset,
++				       frag->size, PCI_DMA_TODEVICE);
+ 		wrb = queue_head_node(txq);
+ 		wrb_fill(wrb, busaddr, frag->size);
+ 		be_dws_cpu_to_le(wrb, sizeof(*wrb));
+@@ -423,8 +703,7 @@ static int make_tx_wrbs(struct be_adapter *adapter,
+ 		queue_head_inc(txq);
+ 	}
+ 
+-	wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false,
+-		wrb_cnt, copied);
++	wrb_fill_hdr(adapter, hdr, first_skb, wrb_cnt, copied);
+ 	be_dws_cpu_to_le(hdr, sizeof(*hdr));
+ 
+ 	return copied;
+@@ -434,19 +713,70 @@ static netdev_tx_t be_xmit(struct sk_buff *skb,
+ 			struct net_device *netdev)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+-	struct be_tx_obj *tx_obj = &adapter->tx_obj;
+-	struct be_queue_info *txq = &tx_obj->q;
++	struct be_tx_obj *txo = &adapter->tx_obj[skb_get_queue_mapping(skb)];
++	struct be_queue_info *txq = &txo->q;
+ 	u32 wrb_cnt = 0, copied = 0;
+ 	u32 start = txq->head;
+ 	bool dummy_wrb, stopped = false;
+ 
+-	wrb_cnt = wrb_cnt_for_skb(skb, &dummy_wrb);
++	if (unlikely((skb_shinfo(skb)->gso_segs > 1) &&
++		skb_shinfo(skb)->gso_size && is_ipv6_ext_hdr(skb))) {
++		tx_stats(txo)->be_ipv6_ext_hdr_tx_drop++;
++		goto tx_drop;
++	}
+ 
+-	copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb);
++	/* If the skb is a large pkt forwarded to this interface
++	 * after being LRO'd on another interface, drop the pkt.
++	 * HW cannot handle such pkts. LRO must be disabled when
++	 * using the server as a router.
++	 */
++	if (!skb_is_gso(skb)) {
++		int eth_hdr_len = ntohs(skb->protocol) == ETH_P_8021Q ?
++						VLAN_ETH_HLEN : ETH_HLEN;
++
++		if ((skb->len - eth_hdr_len) > adapter->netdev->mtu)
++			goto tx_drop;
++	}
++
++	/* The ASIC is calculating checksum for Vlan tagged pkts
++	 * though CSO is disabled.
++	 * To work around this, insert the Vlan tag in the driver
++	 * and donot set the vlan bit, cso bit in the Tx WRB.
++	 */
++	if (unlikely(vlan_tx_tag_present(skb) &&
++		((skb->ip_summed != CHECKSUM_PARTIAL) || (skb->len <= 60)))) {
++		/* Bug 28694: Don't embed the host VLAN tag in SKB
++		 * when UMC mode enabled on that interface
++		 */
++		if (!(adapter->function_mode & UMC_ENABLED)) {
++			skb = skb_share_check(skb, GFP_ATOMIC);
++			if (unlikely(!skb))
++				goto tx_drop;
++
++			skb = be_vlan_put_tag(skb,
++					be_get_tx_vlan_tag(adapter, skb));
++			if (unlikely(!skb))
++				goto tx_drop;
++
++			be_reset_skb_tx_vlan(skb);
++		}
++	}
++
++	/* Bug 12422: the stack can send us skbs with length more than 65535
++	 * BE cannot handle such requests. Hack the extra data out and drop it.
++	 */
++	if (skb->len > 65535) {
++		int err = __pskb_trim(skb, 65535);
++		BUG_ON(err);
++	}
++
++	wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb);
++
++	copied = make_tx_wrbs(adapter, txq, skb, wrb_cnt, dummy_wrb);
+ 	if (copied) {
+ 		/* record the sent skb in the sent_skb table */
+-		BUG_ON(tx_obj->sent_skb_list[start]);
+-		tx_obj->sent_skb_list[start] = skb;
++		BUG_ON(txo->sent_skb_list[start]);
++		txo->sent_skb_list[start] = skb;
+ 
+ 		/* Ensure txq has space for the next skb; Else stop the queue
+ 		 * *BEFORE* ringing the tx doorbell, so that we serialze the
+@@ -454,16 +784,21 @@ static netdev_tx_t be_xmit(struct sk_buff *skb,
+ 		 */
+ 		if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >=
+ 								txq->len) {
+-			netif_stop_queue(netdev);
++			netif_stop_subqueue(netdev, skb_get_queue_mapping(skb));
+ 			stopped = true;
+ 		}
+ 
+ 		be_txq_notify(adapter, txq->id, wrb_cnt);
+ 
+-		be_tx_stats_update(adapter, wrb_cnt, copied,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
++		netdev->trans_start = jiffies;
++#endif
++
++		be_tx_stats_update(txo, wrb_cnt, copied,
+ 				skb_shinfo(skb)->gso_segs, stopped);
+ 	} else {
+ 		txq->head = start;
++tx_drop:
+ 		dev_kfree_skb_any(skb);
+ 	}
+ 	return NETDEV_TX_OK;
+@@ -473,10 +808,12 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+ 	if (new_mtu < BE_MIN_MTU ||
+-			new_mtu > BE_MAX_JUMBO_FRAME_SIZE) {
++			new_mtu > (BE_MAX_JUMBO_FRAME_SIZE -
++					(ETH_HLEN + ETH_FCS_LEN))) {
+ 		dev_info(&adapter->pdev->dev,
+ 			"MTU must be between %d and %d bytes\n",
+-			BE_MIN_MTU, BE_MAX_JUMBO_FRAME_SIZE);
++			BE_MIN_MTU,
++			(BE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN)));
+ 		return -EINVAL;
+ 	}
+ 	dev_info(&adapter->pdev->dev, "MTU changed from %d to %d bytes\n",
+@@ -486,17 +823,19 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu)
+ }
+ 
+ /*
+- * if there are BE_NUM_VLANS_SUPPORTED or lesser number of VLANS configured,
+- * program them in BE.  If more than BE_NUM_VLANS_SUPPORTED are configured,
+- * set the BE in promiscuous VLAN mode.
++ * A max of 64 (BE_NUM_VLANS_SUPPORTED) vlans can be configured in BE.
++ * If the user configures more, place BE in vlan promiscuous mode.
+  */
+-static int be_vid_config(struct be_adapter *adapter)
++static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
+ {
+ 	u16 vtag[BE_NUM_VLANS_SUPPORTED];
+ 	u16 ntags = 0, i;
+-	int status;
++	int status = 0;
+ 
+-	if (adapter->num_vlans <= BE_NUM_VLANS_SUPPORTED)  {
++	/* No need to change the VLAN state if the I/F is in promiscous */
++	if (adapter->promiscuous)
++		return 0;
++	if (adapter->vlans_added <= adapter->max_vlans)  {
+ 		/* Construct VLAN Table to give to HW */
+ 		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ 			if (adapter->vlan_tag[i]) {
+@@ -504,47 +843,46 @@ static int be_vid_config(struct be_adapter *adapter)
+ 				ntags++;
+ 			}
+ 		}
+-		status = be_cmd_vlan_config(adapter, adapter->if_handle,
+-					vtag, ntags, 1, 0);
++		/* Send command only if there is something to be programmed */
++		if (ntags)
++			status = be_cmd_vlan_config(adapter, adapter->if_handle,
++							vtag, ntags, 1, 0);
+ 	} else {
+ 		status = be_cmd_vlan_config(adapter, adapter->if_handle,
+-					NULL, 0, 1, 1);
++							NULL, 0, 1, 1);
+ 	}
++
+ 	return status;
+ }
+ 
+ static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+-	struct be_eq_obj *rx_eq = &adapter->rx_eq;
+-	struct be_eq_obj *tx_eq = &adapter->tx_eq;
+ 
+-	be_eq_notify(adapter, rx_eq->q.id, false, false, 0);
+-	be_eq_notify(adapter, tx_eq->q.id, false, false, 0);
+ 	adapter->vlan_grp = grp;
+-	be_eq_notify(adapter, rx_eq->q.id, true, false, 0);
+-	be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
+ }
+ 
+ static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+ 
+-	adapter->num_vlans++;
++	adapter->vlans_added++;
++
+ 	adapter->vlan_tag[vid] = 1;
+-
+-	be_vid_config(adapter);
++	if (adapter->vlans_added <= (adapter->max_vlans + 1))
++		be_vid_config(adapter, false, 0);
+ }
+ 
+ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+ 
+-	adapter->num_vlans--;
+-	adapter->vlan_tag[vid] = 0;
+-
++	adapter->vlans_added--;
+ 	vlan_group_set_device(adapter->vlan_grp, vid, NULL);
+-	be_vid_config(adapter);
++
++	adapter->vlan_tag[vid] = 0;
++	if (adapter->vlans_added <= adapter->max_vlans)
++		be_vid_config(adapter, false, 0);
+ }
+ 
+ static void be_set_multicast_list(struct net_device *netdev)
+@@ -552,7 +890,7 @@ static void be_set_multicast_list(struct net_device *netdev)
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+ 
+ 	if (netdev->flags & IFF_PROMISC) {
+-		be_cmd_promiscuous_config(adapter, adapter->port_num, 1);
++		be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
+ 		adapter->promiscuous = true;
+ 		goto done;
+ 	}
+@@ -560,81 +898,244 @@ static void be_set_multicast_list(struct net_device *netdev)
+ 	/* BE was previously in promiscous mode; disable it */
+ 	if (adapter->promiscuous) {
+ 		adapter->promiscuous = false;
+-		be_cmd_promiscuous_config(adapter, adapter->port_num, 0);
++		be_cmd_rx_filter(adapter, IFF_PROMISC, OFF);
++
++		if (adapter->vlans_added)
++			be_vid_config(adapter, false, 0);
+ 	}
+ 
+-	if (netdev->flags & IFF_ALLMULTI) {
+-		be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 0);
++	/* Enable multicast promisc if num configured exceeds what we support */
++	if (netdev->flags & IFF_ALLMULTI ||
++			netdev_mc_count(netdev) > BE_MAX_MC) {
++		be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
+ 		goto done;
+ 	}
+ 
+-	be_cmd_multicast_set(adapter, adapter->if_handle, netdev->mc_list,
+-		netdev->mc_count);
++	be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
+ done:
+ 	return;
+ }
+ 
+-static void be_rx_rate_update(struct be_adapter *adapter)
++#ifdef HAVE_SRIOV_CONFIG
++static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
+ {
+-	struct be_drvr_stats *stats = drvr_stats(adapter);
++	struct be_adapter *adapter = netdev_priv(netdev);
++	int status;
++
++	if (adapter->num_vfs == 0)
++		return -EPERM;
++
++	if (!is_valid_ether_addr(mac) || (vf >= adapter->num_vfs))
++		return -EINVAL;
++
++	if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID)
++		status = be_cmd_pmac_del(adapter,
++					adapter->vf_cfg[vf].vf_if_handle,
++					adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
++
++	status = be_cmd_pmac_add(adapter, mac,
++				adapter->vf_cfg[vf].vf_if_handle,
++				&adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
++
++	if (status)
++		dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n",
++				mac, vf);
++	else
++		memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN);
++
++	return status;
++}
++
++static int be_get_vf_config(struct net_device *netdev, int vf,
++			struct ifla_vf_info *vi)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++
++	if (adapter->num_vfs == 0)
++		return -EPERM;
++
++	if (vf >= adapter->num_vfs)
++		return -EINVAL;
++
++	vi->vf = vf;
++	vi->tx_rate = adapter->vf_cfg[vf].vf_tx_rate;
++	vi->vlan = adapter->vf_cfg[vf].vf_vlan_tag & VLAN_VID_MASK;
++	vi->qos = adapter->vf_cfg[vf].vf_vlan_tag >> VLAN_PRIO_SHIFT;
++	memcpy(&vi->mac, adapter->vf_cfg[vf].vf_mac_addr, ETH_ALEN);
++
++	return 0;
++}
++
++/*
++ * Entry point to configure vlan behavior for a VF.
++ * 1. By default a VF is vlan Challenged.
++ * 2. It may or may not have Transparent Tagging enabled.
++ * 3. Vlan privilege for a VF can be toggled using special VID 4095.
++ * 4. When removing the Vlan privilege for a VF there is no need set default vid
++ * 5. Transparent Tagging configured for a VF resets its Vlan privilege
++ * 6. To disable the current Transparet Tagging for a VF:
++ *   6a. run the last iproute command with vlan set to 0.
++ *   6b. programing the default vid will disable Transparent Tagging in ARM/ASIC
++ */
++static int be_set_vf_vlan(struct net_device *netdev,
++			int vf, u16 vlan, u8 qos)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++	int status = 0;
++	u32 en = 0;
++
++	if (adapter->num_vfs == 0)
++		return -EPERM;
++
++	if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7))
++		return -EINVAL;
++
++	status = be_cmd_get_fn_privileges(adapter, &en, vf + 1);
++	if (status)
++		goto sts;
++
++	if (vlan == 4095) {
++		if (en & BE_PRIV_FILTMGMT) {
++			/* Knock off filtering privileges */
++			en &= ~BE_PRIV_FILTMGMT;
++		} else {
++			en |= BE_PRIV_FILTMGMT;
++			/* Transparent Tagging is currently enabled, Reset it */
++			if (adapter->vf_cfg[vf].vf_vlan_tag) {
++				adapter->vf_cfg[vf].vf_vlan_tag = 0;
++				vlan = adapter->vf_cfg[vf].vf_def_vid;
++				be_cmd_set_hsw_config(adapter, vlan, vf + 1,
++					adapter->vf_cfg[vf].vf_if_handle);
++			}
++		}
++
++		adapter->vf_cfg[vf].vf_vlan_tag = 0;
++		status = be_cmd_set_fn_privileges(adapter, en, NULL, vf + 1);
++
++		goto sts;
++	}
++
++	if (vlan || qos) {
++		if (en & BE_PRIV_FILTMGMT) {
++			/* Check privilege and reset it to default */
++			en &= ~BE_PRIV_FILTMGMT;
++			be_cmd_set_fn_privileges(adapter, en, NULL, vf + 1);
++		}
++
++		vlan |= qos << VLAN_PRIO_SHIFT;
++		if (adapter->vf_cfg[vf].vf_vlan_tag != vlan) {
++			/* If this is new value, program it. Else skip. */
++			adapter->vf_cfg[vf].vf_vlan_tag = vlan;
++
++			status = be_cmd_set_hsw_config(adapter, vlan,
++				vf + 1, adapter->vf_cfg[vf].vf_if_handle);
++		}
++
++	} else {
++		/* Reset Transparent Vlan Tagging. */
++		adapter->vf_cfg[vf].vf_vlan_tag = 0;
++		vlan = adapter->vf_cfg[vf].vf_def_vid;
++		status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
++			adapter->vf_cfg[vf].vf_if_handle);
++	}
++
++sts:
++	if (status)
++		dev_info(&adapter->pdev->dev,
++				"VLAN %d config on VF %d failed\n", vlan, vf);
++	return status;
++}
++
++static int be_set_vf_tx_rate(struct net_device *netdev,
++			int vf, int rate)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++	int status = 0;
++
++	if (adapter->num_vfs == 0)
++		return -EPERM;
++
++	if ((vf >= adapter->num_vfs) || (rate < 0))
++		return -EINVAL;
++
++	if (rate > 10000)
++		rate = 10000;
++
++	adapter->vf_cfg[vf].vf_tx_rate = rate;
++	status = be_cmd_set_qos(adapter, rate / 10, vf + 1);
++
++	if (status)
++		dev_info(&adapter->pdev->dev,
++				"tx rate %d on VF %d failed\n", rate, vf);
++	return status;
++}
++#endif /* HAVE_SRIOV_CONFIG */
++
++static void be_rx_rate_update(struct be_rx_obj *rxo)
++{
++	struct be_rx_stats *stats = &rxo->stats;
+ 	ulong now = jiffies;
+ 
+ 	/* Wrapped around */
+-	if (time_before(now, stats->be_rx_jiffies)) {
+-		stats->be_rx_jiffies = now;
++	if (time_before(now, stats->rx_jiffies)) {
++		stats->rx_jiffies = now;
+ 		return;
+ 	}
+ 
+ 	/* Update the rate once in two seconds */
+-	if ((now - stats->be_rx_jiffies) < 2 * HZ)
++	if ((now - stats->rx_jiffies) < 2 * HZ)
+ 		return;
+ 
+-	stats->be_rx_rate = be_calc_rate(stats->be_rx_bytes
+-					  - stats->be_rx_bytes_prev,
+-					 now - stats->be_rx_jiffies);
+-	stats->be_rx_jiffies = now;
+-	stats->be_rx_bytes_prev = stats->be_rx_bytes;
++	stats->rx_rate = be_calc_rate(stats->rx_bytes - stats->rx_bytes_prev,
++				now - stats->rx_jiffies);
++	stats->rx_jiffies = now;
++	stats->rx_bytes_prev = stats->rx_bytes;
+ }
+ 
+-static void be_rx_stats_update(struct be_adapter *adapter,
+-		u32 pktsize, u16 numfrags)
++static void be_rx_stats_update(struct be_rx_obj *rxo,
++		struct be_rx_compl_info *rxcp)
+ {
+-	struct be_drvr_stats *stats = drvr_stats(adapter);
++	struct be_rx_stats *stats = &rxo->stats;
+ 
+-	stats->be_rx_compl++;
+-	stats->be_rx_frags += numfrags;
+-	stats->be_rx_bytes += pktsize;
+-	stats->be_rx_pkts++;
++	stats->rx_compl++;
++	stats->rx_frags += rxcp->num_rcvd;
++	stats->rx_bytes += rxcp->pkt_size;
++	stats->rx_pkts++;
++	if (rxcp->pkt_type == BE_MULTICAST_PACKET)
++		stats->rx_mcast_pkts++;
++	if (rxcp->err)
++		stats->rxcp_err++;
+ }
+ 
+-static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
++static inline bool csum_passed(struct be_rx_compl_info *rxcp)
+ {
+-	u8 l4_cksm, ip_version, ipcksm, tcpf = 0, udpf = 0, ipv6_chk;
+-
+-	l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
+-	ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp);
+-	ip_version = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp);
+-	if (ip_version) {
+-		tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
+-		udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp);
+-	}
+-	ipv6_chk = (ip_version && (tcpf || udpf));
+-
+-	return ((l4_cksm && ipv6_chk && ipcksm) && cso) ? false : true;
++	/* L4 checksum is not reliable for non TCP/UDP packets.
++	 * Also ignore ipcksm for ipv6 pkts */
++	return (rxcp->tcpf || rxcp->udpf) && rxcp->l4_csum &&
++				(rxcp->ip_csum || rxcp->ipv6);
+ }
+ 
+ static struct be_rx_page_info *
+-get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
++get_rx_page_info(struct be_adapter *adapter, struct be_rx_obj *rxo,
++		u16 frag_idx)
+ {
+ 	struct be_rx_page_info *rx_page_info;
+-	struct be_queue_info *rxq = &adapter->rx_obj.q;
++	struct be_queue_info *rxq = &rxo->q;
+ 
+-	rx_page_info = &adapter->rx_obj.page_info_tbl[frag_idx];
+-	BUG_ON(!rx_page_info->page);
++	rx_page_info = &rxo->page_info_tbl[frag_idx];
++	if (!rx_page_info->page) {
++		printk(KERN_EMERG "curr_idx=%d prev_dix=%d rxq->head=%d\n",
++			frag_idx, rxo->prev_frag_idx, rxq->head);
++		BUG_ON(!rx_page_info->page);
++	}
+ 
+-	if (rx_page_info->last_page_user)
++	if (rx_page_info->last_page_user) {
+ 		pci_unmap_page(adapter->pdev, pci_unmap_addr(rx_page_info, bus),
+ 			adapter->big_page_size, PCI_DMA_FROMDEVICE);
++		rx_page_info->last_page_user = false;
++	}
++
++	rxo->prev_frag_idx = frag_idx;
+ 
+ 	atomic_dec(&rxq->used);
+ 	return rx_page_info;
+@@ -642,20 +1143,26 @@ get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
+ 
+ /* Throwaway the data in the Rx completion */
+ static void be_rx_compl_discard(struct be_adapter *adapter,
+-			struct be_eth_rx_compl *rxcp)
++		struct be_rx_obj *rxo,
++		struct be_rx_compl_info *rxcp)
+ {
+-	struct be_queue_info *rxq = &adapter->rx_obj.q;
++	struct be_queue_info *rxq = &rxo->q;
+ 	struct be_rx_page_info *page_info;
+-	u16 rxq_idx, i, num_rcvd;
++	u16 i;
++	bool oob_error;
++	u16 num_rcvd = rxcp->num_rcvd;
+ 
+-	rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
+-	num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
++	oob_error = lancer_A0_chip(adapter) && rxcp->err;
++
++	/* In case of OOB error num_rcvd will be 1 more than actual */
++	if (oob_error && num_rcvd)
++		num_rcvd -= 1;
+ 
+ 	for (i = 0; i < num_rcvd; i++) {
+-		page_info = get_rx_page_info(adapter, rxq_idx);
++		page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
+ 		put_page(page_info->page);
+ 		memset(page_info, 0, sizeof(*page_info));
+-		index_inc(&rxq_idx, rxq->len);
++		index_inc(&rxcp->rxq_idx, rxq->len);
+ 	}
+ }
+ 
+@@ -663,29 +1170,24 @@ static void be_rx_compl_discard(struct be_adapter *adapter,
+  * skb_fill_rx_data forms a complete skb for an ether frame
+  * indicated by rxcp.
+  */
+-static void skb_fill_rx_data(struct be_adapter *adapter,
+-			struct sk_buff *skb, struct be_eth_rx_compl *rxcp)
++static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo,
++			struct sk_buff *skb, struct be_rx_compl_info *rxcp)
+ {
+-	struct be_queue_info *rxq = &adapter->rx_obj.q;
++	struct be_queue_info *rxq = &rxo->q;
+ 	struct be_rx_page_info *page_info;
+-	u16 rxq_idx, i, num_rcvd, j;
+-	u32 pktsize, hdr_len, curr_frag_len, size;
++	u16 i, j;
++	u16 hdr_len, curr_frag_len, remaining;
+ 	u8 *start;
+ 
+-	rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
+-	pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
+-	num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
+-
+-	page_info = get_rx_page_info(adapter, rxq_idx);
+-
++	page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
+ 	start = page_address(page_info->page) + page_info->page_offset;
+ 	prefetch(start);
+ 
+ 	/* Copy data in the first descriptor of this completion */
+-	curr_frag_len = min(pktsize, rx_frag_size);
++	curr_frag_len = min(rxcp->pkt_size, rx_frag_size);
+ 
+ 	/* Copy the header portion into skb_data */
+-	hdr_len = min((u32)BE_HDR_LEN, curr_frag_len);
++	hdr_len = min(BE_HDR_LEN, curr_frag_len);
+ 	memcpy(skb->data, start, hdr_len);
+ 	skb->len = curr_frag_len;
+ 	if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */
+@@ -702,21 +1204,19 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
+ 		skb->data_len = curr_frag_len - hdr_len;
+ 		skb->tail += hdr_len;
+ 	}
+-	memset(page_info, 0, sizeof(*page_info));
++	page_info->page = NULL;
+ 
+-	if (pktsize <= rx_frag_size) {
+-		BUG_ON(num_rcvd != 1);
+-		goto done;
++	if (rxcp->pkt_size <= rx_frag_size) {
++		BUG_ON(rxcp->num_rcvd != 1);
++		return;
+ 	}
+ 
+ 	/* More frags present for this completion */
+-	size = pktsize;
+-	for (i = 1, j = 0; i < num_rcvd; i++) {
+-		size -= curr_frag_len;
+-		index_inc(&rxq_idx, rxq->len);
+-		page_info = get_rx_page_info(adapter, rxq_idx);
+-
+-		curr_frag_len = min(size, rx_frag_size);
++	index_inc(&rxcp->rxq_idx, rxq->len);
++	remaining = rxcp->pkt_size - curr_frag_len;
++	for (i = 1, j = 0; i < rxcp->num_rcvd; i++) {
++		page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
++		curr_frag_len = min(remaining, rx_frag_size);
+ 
+ 		/* Coalesce all frags from the same physical page in one slot */
+ 		if (page_info->page_offset == 0) {
+@@ -735,99 +1235,122 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
+ 		skb->len += curr_frag_len;
+ 		skb->data_len += curr_frag_len;
+ 
+-		memset(page_info, 0, sizeof(*page_info));
++		remaining -= curr_frag_len;
++		index_inc(&rxcp->rxq_idx, rxq->len);
++		page_info->page = NULL;
+ 	}
+ 	BUG_ON(j > MAX_SKB_FRAGS);
+-
+-done:
+-	be_rx_stats_update(adapter, pktsize, num_rcvd);
+-	return;
+ }
+ 
+-/* Process the RX completion indicated by rxcp when GRO is disabled */
++/* Process the RX completion indicated by rxcp when LRO is disabled */
+ static void be_rx_compl_process(struct be_adapter *adapter,
+-			struct be_eth_rx_compl *rxcp)
++			struct be_rx_obj *rxo,
++			struct be_rx_compl_info *rxcp)
+ {
+ 	struct sk_buff *skb;
+-	u32 vlanf, vid;
+-	u8 vtm;
+ 
+-	vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
+-	vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
+-
+-	/* vlanf could be wrongly set in some cards.
+-	 * ignore if vtm is not set */
+-	if ((adapter->cap == 0x400) && !vtm)
+-		vlanf = 0;
+-
+-	skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
+-	if (!skb) {
++	skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN);
++	if (unlikely(!skb)) {
+ 		if (net_ratelimit())
+ 			dev_warn(&adapter->pdev->dev, "skb alloc failed\n");
+-		be_rx_compl_discard(adapter, rxcp);
++		be_rx_compl_discard(adapter, rxo, rxcp);
+ 		return;
+ 	}
+ 
+-	skb_reserve(skb, NET_IP_ALIGN);
++	skb_fill_rx_data(adapter, rxo, skb, rxcp);
+ 
+-	skb_fill_rx_data(adapter, skb, rxcp);
+-
+-	if (do_pkt_csum(rxcp, adapter->rx_csum))
+-		skb->ip_summed = CHECKSUM_NONE;
+-	else
++	if (likely(adapter->rx_csum && csum_passed(rxcp)))
+ 		skb->ip_summed = CHECKSUM_UNNECESSARY;
++	else
++		skb->ip_summed = CHECKSUM_NONE;
+ 
+ 	skb->truesize = skb->len + sizeof(struct sk_buff);
++	if (unlikely(rxcp->vlanf) &&
++			unlikely(!vlan_configured(adapter))) {
++		__vlan_put_tag(skb, rxcp->vlan_tag);
++	}
+ 	skb->protocol = eth_type_trans(skb, adapter->netdev);
+ 	skb->dev = adapter->netdev;
+ 
+-	if (vlanf) {
+-		if (!adapter->vlan_grp || adapter->num_vlans == 0) {
+-			kfree_skb(skb);
+-			return;
+-		}
+-		vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
+-		vid = be16_to_cpu(vid);
+-		vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid);
+-	} else {
++	if (unlikely(rxcp->vlanf) &&
++			vlan_configured(adapter))
++		vlan_hwaccel_receive_skb(skb, adapter->vlan_grp,
++				rxcp->vlan_tag);
++	else
+ 		netif_receive_skb(skb);
++
++	return;
++}
++
++/* Process the RX completion indicated by rxcp when LRO is enabled */
++static void be_rx_compl_process_lro(struct be_adapter *adapter,
++			struct be_rx_obj *rxo,
++			struct be_rx_compl_info *rxcp)
++{
++	struct be_rx_page_info *page_info;
++	struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME];
++	struct be_queue_info *rxq = &rxo->q;
++	u16 remaining, curr_frag_len;
++	u16 i, j;
++
++	remaining = rxcp->pkt_size;
++	for (i = 0, j = -1; i < rxcp->num_rcvd; i++) {
++		page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
++
++		curr_frag_len = min(remaining, rx_frag_size);
++
++		/* Coalesce all frags from the same physical page in one slot */
++		if (i == 0 || page_info->page_offset == 0) {
++			/* First frag or Fresh page */
++			j++;
++			rx_frags[j].page = page_info->page;
++			rx_frags[j].page_offset = page_info->page_offset;
++			rx_frags[j].size = 0;
++		} else {
++			put_page(page_info->page);
++		}
++		rx_frags[j].size += curr_frag_len;
++
++		remaining -= curr_frag_len;
++		index_inc(&rxcp->rxq_idx, rxq->len);
++		memset(page_info, 0, sizeof(*page_info));
++	}
++	BUG_ON(j > MAX_SKB_FRAGS);
++
++	if (likely(!rxcp->vlanf)) {
++		lro_receive_frags(&rxo->lro_mgr, rx_frags, rxcp->pkt_size,
++				rxcp->pkt_size, NULL, 0);
++	} else {
++		lro_vlan_hwaccel_receive_frags(&rxo->lro_mgr, rx_frags,
++			rxcp->pkt_size, rxcp->pkt_size, adapter->vlan_grp,
++			rxcp->vlan_tag, NULL, 0);
+ 	}
+ 
+ 	return;
+ }
+ 
+ /* Process the RX completion indicated by rxcp when GRO is enabled */
+-static void be_rx_compl_process_gro(struct be_adapter *adapter,
+-			struct be_eth_rx_compl *rxcp)
++void be_rx_compl_process_gro(struct be_adapter *adapter,
++			struct be_rx_obj *rxo,
++			struct be_rx_compl_info *rxcp)
+ {
++#ifdef NETIF_F_GRO
+ 	struct be_rx_page_info *page_info;
+ 	struct sk_buff *skb = NULL;
+-	struct be_queue_info *rxq = &adapter->rx_obj.q;
+-	struct be_eq_obj *eq_obj =  &adapter->rx_eq;
+-	u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
+-	u16 i, rxq_idx = 0, vid, j;
+-	u8 vtm;
+-
+-	num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
+-	pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
+-	vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
+-	rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
+-	vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
+-
+-	/* vlanf could be wrongly set in some cards.
+-	 * ignore if vtm is not set */
+-	if ((adapter->cap == 0x400) && !vtm)
+-		vlanf = 0;
++	struct be_queue_info *rxq = &rxo->q;
++	struct be_eq_obj *eq_obj =  &rxo->rx_eq;
++	u16 remaining, curr_frag_len;
++	u16 i, j;
+ 
+ 	skb = napi_get_frags(&eq_obj->napi);
+ 	if (!skb) {
+-		be_rx_compl_discard(adapter, rxcp);
++		be_rx_compl_discard(adapter, rxo, rxcp);
+ 		return;
+ 	}
+ 
+-	remaining = pkt_size;
+-	for (i = 0, j = -1; i < num_rcvd; i++) {
+-		page_info = get_rx_page_info(adapter, rxq_idx);
++	remaining = rxcp->pkt_size;
++	for (i = 0, j = -1; i < rxcp->num_rcvd; i++) {
++		page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
+ 
+ 		curr_frag_len = min(remaining, rx_frag_size);
+ 
+@@ -845,55 +1368,129 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
+ 		skb_shinfo(skb)->frags[j].size += curr_frag_len;
+ 
+ 		remaining -= curr_frag_len;
+-		index_inc(&rxq_idx, rxq->len);
++		index_inc(&rxcp->rxq_idx, rxq->len);
+ 		memset(page_info, 0, sizeof(*page_info));
+ 	}
+ 	BUG_ON(j > MAX_SKB_FRAGS);
+ 
+ 	skb_shinfo(skb)->nr_frags = j + 1;
+-	skb->len = pkt_size;
+-	skb->data_len = pkt_size;
+-	skb->truesize += pkt_size;
++	skb->len = rxcp->pkt_size;
++	skb->data_len = rxcp->pkt_size;
++	skb->truesize += rxcp->pkt_size;
+ 	skb->ip_summed = CHECKSUM_UNNECESSARY;
+ 
+-	if (likely(!vlanf)) {
++	if (likely(!rxcp->vlanf))
+ 		napi_gro_frags(&eq_obj->napi);
+-	} else {
+-		vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
+-		vid = be16_to_cpu(vid);
++	else
++		vlan_gro_frags(&eq_obj->napi,
++				adapter->vlan_grp, rxcp->vlan_tag);
++#endif
+ 
+-		if (!adapter->vlan_grp || adapter->num_vlans == 0)
+-			return;
+-
+-		vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid);
+-	}
+-
+-	be_rx_stats_update(adapter, pkt_size, num_rcvd);
+ 	return;
+ }
+ 
+-static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
++static void be_parse_rx_compl_v1(struct be_adapter *adapter,
++				struct be_eth_rx_compl *compl,
++				struct be_rx_compl_info *rxcp)
+ {
+-	struct be_eth_rx_compl *rxcp = queue_tail_node(&adapter->rx_obj.cq);
++	rxcp->pkt_size =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, pktsize, compl);
++	rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtp, compl);
++	rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, err, compl);
++	rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tcpf, compl);
++	rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, udpf, compl);
++	rxcp->ip_csum =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ipcksm, compl);
++	rxcp->l4_csum =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, l4_cksm, compl);
++	rxcp->ipv6 =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ip_version, compl);
++	rxcp->rxq_idx =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, fragndx, compl);
++	rxcp->num_rcvd =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl);
++	rxcp->pkt_type =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl);
++	if (rxcp->vlanf) {
++		rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm,
++				compl);
++		rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1,
++						vlan_tag, compl);
++	}
++	rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, port, compl);
++}
+ 
+-	if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0)
++static void be_parse_rx_compl_v0(struct be_adapter *adapter,
++				struct be_eth_rx_compl *compl,
++				struct be_rx_compl_info *rxcp)
++{
++	rxcp->pkt_size =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, pktsize, compl);
++	rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtp, compl);
++	rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, err, compl);
++	rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, tcpf, compl);
++	rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, udpf, compl);
++	rxcp->ip_csum =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ipcksm, compl);
++	rxcp->l4_csum =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, l4_cksm, compl);
++	rxcp->ipv6 =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ip_version, compl);
++	rxcp->rxq_idx =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, fragndx, compl);
++	rxcp->num_rcvd =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl);
++	rxcp->pkt_type =
++		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl);
++	if (rxcp->vlanf) {
++		rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm,
++				compl);
++		rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0,
++						vlan_tag, compl);
++	}
++	rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl);
++}
++
++static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
++{
++	struct be_eth_rx_compl *compl = queue_tail_node(&rxo->cq);
++	struct be_rx_compl_info *rxcp = &rxo->rxcp;
++	struct be_adapter *adapter = rxo->adapter;
++
++	/* For checking the valid bit it is Ok to use either definition as the
++	 * valid bit is at the same position in both v0 and v1 Rx compl */
++	if (compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] == 0)
+ 		return NULL;
+ 
+-	be_dws_le_to_cpu(rxcp, sizeof(*rxcp));
++	rmb();
++	be_dws_le_to_cpu(compl, sizeof(*compl));
+ 
+-	queue_tail_inc(&adapter->rx_obj.cq);
++	if (adapter->be3_native)
++		be_parse_rx_compl_v1(adapter, compl, rxcp);
++	else
++		be_parse_rx_compl_v0(adapter, compl, rxcp);
++
++	if (rxcp->vlanf) {
++		/* vlanf could be wrongly set in some cards.
++		 * ignore if vtm is not set */
++		if ((adapter->function_mode & FLEX10_MODE) && !rxcp->vtm)
++			rxcp->vlanf = 0;
++
++		if (!lancer_chip(adapter))
++			rxcp->vlan_tag = swab16(rxcp->vlan_tag);
++
++		if ((adapter->pvid  == (rxcp->vlan_tag & VLAN_VID_MASK)) &&
++			!adapter->vlan_tag[rxcp->vlan_tag])
++			rxcp->vlanf = 0;
++	}
++
++	/* As the compl has been parsed, reset it; we wont touch it again */
++	compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0;
++
++	queue_tail_inc(&rxo->cq);
+ 	return rxcp;
+ }
+ 
+-/* To reset the valid bit, we need to reset the whole word as
+- * when walking the queue the valid entries are little-endian
+- * and invalid entries are host endian
+- */
+-static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp)
+-{
+-	rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0;
+-}
+-
+ static inline struct page *be_alloc_pages(u32 size)
+ {
+ 	gfp_t alloc_flags = GFP_ATOMIC;
+@@ -907,11 +1504,12 @@ static inline struct page *be_alloc_pages(u32 size)
+  * Allocate a page, split it to fragments of size rx_frag_size and post as
+  * receive buffers to BE
+  */
+-static void be_post_rx_frags(struct be_adapter *adapter)
++static void be_post_rx_frags(struct be_rx_obj *rxo)
+ {
+-	struct be_rx_page_info *page_info_tbl = adapter->rx_obj.page_info_tbl;
+-	struct be_rx_page_info *page_info = NULL;
+-	struct be_queue_info *rxq = &adapter->rx_obj.q;
++	struct be_adapter *adapter = rxo->adapter;
++	struct be_rx_page_info *page_info_tbl = rxo->page_info_tbl;
++	struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL;
++	struct be_queue_info *rxq = &rxo->q;
+ 	struct page *pagep = NULL;
+ 	struct be_eth_rx_d *rxd;
+ 	u64 page_dmaaddr = 0, frag_dmaaddr;
+@@ -922,7 +1520,7 @@ static void be_post_rx_frags(struct be_adapter *adapter)
+ 		if (!pagep) {
+ 			pagep = be_alloc_pages(adapter->big_page_size);
+ 			if (unlikely(!pagep)) {
+-				drvr_stats(adapter)->be_ethrx_post_fail++;
++				rxo->stats.rx_post_fail++;
+ 				break;
+ 			}
+ 			page_dmaaddr = pci_map_page(adapter->pdev, pagep, 0,
+@@ -941,7 +1539,6 @@ static void be_post_rx_frags(struct be_adapter *adapter)
+ 		rxd = queue_head_node(rxq);
+ 		rxd->fragpa_lo = cpu_to_le32(frag_dmaaddr & 0xFFFFFFFF);
+ 		rxd->fragpa_hi = cpu_to_le32(upper_32_bits(frag_dmaaddr));
+-		queue_head_inc(rxq);
+ 
+ 		/* Any space left in the current big page for another frag? */
+ 		if ((page_offset + rx_frag_size + rx_frag_size) >
+@@ -949,17 +1546,24 @@ static void be_post_rx_frags(struct be_adapter *adapter)
+ 			pagep = NULL;
+ 			page_info->last_page_user = true;
+ 		}
++
++		prev_page_info = page_info;
++		queue_head_inc(rxq);
+ 		page_info = &page_info_tbl[rxq->head];
+ 	}
+ 	if (pagep)
+-		page_info->last_page_user = true;
++		prev_page_info->last_page_user = true;
+ 
++	/* Ensure that posting buffers is the last thing done by this
++	 * routine to avoid racing between rx bottom-half and
++	 * be_worker (process) contexts.
++	 */
+ 	if (posted) {
+ 		atomic_add(posted, &rxq->used);
+ 		be_rxq_notify(adapter, rxq->id, posted);
+ 	} else if (atomic_read(&rxq->used) == 0) {
+ 		/* Let be_worker replenish when memory is available */
+-		adapter->rx_post_starved = true;
++		rxo->rx_post_starved = true;
+ 	}
+ 
+ 	return;
+@@ -972,6 +1576,7 @@ static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
+ 	if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0)
+ 		return NULL;
+ 
++	rmb();
+ 	be_dws_le_to_cpu(txcp, sizeof(*txcp));
+ 
+ 	txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0;
+@@ -980,11 +1585,14 @@ static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
+ 	return txcp;
+ }
+ 
+-static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
++static u16 be_tx_compl_process(struct be_adapter *adapter,
++		struct be_tx_obj *txo, u16 last_index)
+ {
+-	struct be_queue_info *txq = &adapter->tx_obj.q;
+-	struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
++	struct be_queue_info *txq = &txo->q;
++	struct be_eth_wrb *wrb;
++	struct sk_buff **sent_skbs = txo->sent_skb_list;
+ 	struct sk_buff *sent_skb;
++	u64 busaddr;
+ 	u16 cur_index, num_wrbs = 0;
+ 
+ 	cur_index = txq->tail;
+@@ -992,15 +1600,31 @@ static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
+ 	BUG_ON(!sent_skb);
+ 	sent_skbs[cur_index] = NULL;
+ 
+-	do {
++	wrb = queue_tail_node(txq);
++	be_dws_le_to_cpu(wrb, sizeof(*wrb));
++	busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo;
++	if (busaddr != 0) {
++		pci_unmap_single(adapter->pdev, busaddr,
++				 wrb->frag_len, PCI_DMA_TODEVICE);
++	}
++	num_wrbs++;
++	queue_tail_inc(txq);
++
++	while (cur_index != last_index) {
+ 		cur_index = txq->tail;
++		wrb = queue_tail_node(txq);
++		be_dws_le_to_cpu(wrb, sizeof(*wrb));
++		busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo;
++		if (busaddr != 0) {
++			pci_unmap_page(adapter->pdev, busaddr,
++				       wrb->frag_len, PCI_DMA_TODEVICE);
++		}
+ 		num_wrbs++;
+ 		queue_tail_inc(txq);
+-	} while (cur_index != last_index);
++	}
+ 
+-	atomic_sub(num_wrbs, &txq->used);
+-	skb_dma_unmap(&adapter->pdev->dev, sent_skb, DMA_TO_DEVICE);
+ 	kfree_skb(sent_skb);
++	return num_wrbs;
+ }
+ 
+ static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
+@@ -1010,13 +1634,15 @@ static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
+ 	if (!eqe->evt)
+ 		return NULL;
+ 
++	rmb();
+ 	eqe->evt = le32_to_cpu(eqe->evt);
+ 	queue_tail_inc(&eq_obj->q);
+ 	return eqe;
+ }
+ 
+ static int event_handle(struct be_adapter *adapter,
+-			struct be_eq_obj *eq_obj)
++			struct be_eq_obj *eq_obj,
++			bool rearm)
+ {
+ 	struct be_eq_entry *eqe;
+ 	u16 num = 0;
+@@ -1029,7 +1655,10 @@ static int event_handle(struct be_adapter *adapter,
+ 	/* Deal with any spurious interrupts that come
+ 	 * without events
+ 	 */
+-	be_eq_notify(adapter, eq_obj->q.id, true, true, num);
++	if (!num)
++		rearm = true;
++
++	be_eq_notify(adapter, eq_obj->q.id, rearm, true, num);
+ 	if (num)
+ 		napi_schedule(&eq_obj->napi);
+ 
+@@ -1053,49 +1682,55 @@ static void be_eq_clean(struct be_adapter *adapter,
+ 		be_eq_notify(adapter, eq_obj->q.id, false, true, num);
+ }
+ 
+-static void be_rx_q_clean(struct be_adapter *adapter)
++static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo)
+ {
+ 	struct be_rx_page_info *page_info;
+-	struct be_queue_info *rxq = &adapter->rx_obj.q;
+-	struct be_queue_info *rx_cq = &adapter->rx_obj.cq;
+-	struct be_eth_rx_compl *rxcp;
++	struct be_queue_info *rxq = &rxo->q;
++	struct be_queue_info *rx_cq = &rxo->cq;
++	struct be_rx_compl_info *rxcp;
+ 	u16 tail;
+ 
+ 	/* First cleanup pending rx completions */
+-	while ((rxcp = be_rx_compl_get(adapter)) != NULL) {
+-		be_rx_compl_discard(adapter, rxcp);
+-		be_rx_compl_reset(rxcp);
++	while ((rxcp = be_rx_compl_get(rxo)) != NULL) {
++		be_rx_compl_discard(adapter, rxo, rxcp);
+ 		be_cq_notify(adapter, rx_cq->id, true, 1);
+ 	}
+ 
+ 	/* Then free posted rx buffer that were not used */
+ 	tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len;
+ 	for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) {
+-		page_info = get_rx_page_info(adapter, tail);
++		page_info = get_rx_page_info(adapter, rxo, tail);
+ 		put_page(page_info->page);
+ 		memset(page_info, 0, sizeof(*page_info));
+ 	}
+ 	BUG_ON(atomic_read(&rxq->used));
++	rxq->tail = rxq->head = 0;
+ }
+ 
+-static void be_tx_compl_clean(struct be_adapter *adapter)
++static void be_tx_compl_clean(struct be_adapter *adapter,
++				struct be_tx_obj *txo)
+ {
+-	struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
+-	struct be_queue_info *txq = &adapter->tx_obj.q;
++	struct be_queue_info *tx_cq = &txo->cq;
++	struct be_queue_info *txq = &txo->q;
+ 	struct be_eth_tx_compl *txcp;
+-	u16 end_idx, cmpl = 0, timeo = 0;
++	u16 end_idx, cmpl = 0, timeo = 0, num_wrbs = 0;
++	struct sk_buff **sent_skbs = txo->sent_skb_list;
++	struct sk_buff *sent_skb;
++	bool dummy_wrb;
+ 
+ 	/* Wait for a max of 200ms for all the tx-completions to arrive. */
+ 	do {
+ 		while ((txcp = be_tx_compl_get(tx_cq))) {
+ 			end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
+ 					wrb_index, txcp);
+-			be_tx_compl_process(adapter, end_idx);
++			num_wrbs += be_tx_compl_process(adapter, txo, end_idx);
+ 			cmpl++;
+ 		}
+ 		if (cmpl) {
+ 			be_cq_notify(adapter, tx_cq->id, false, cmpl);
++			atomic_sub(num_wrbs, &txq->used);
+ 			cmpl = 0;
++			num_wrbs = 0;
+ 		}
+ 
+ 		if (atomic_read(&txq->used) == 0 || ++timeo > 200)
+@@ -1107,6 +1742,17 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
+ 	if (atomic_read(&txq->used))
+ 		dev_err(&adapter->pdev->dev, "%d pending tx-completions\n",
+ 			atomic_read(&txq->used));
++
++	/* free posted tx for which compls will never arrive */
++	while (atomic_read(&txq->used)) {
++		sent_skb = sent_skbs[txq->tail];
++		end_idx = txq->tail;
++		index_adv(&end_idx,
++			wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1,
++			txq->len);
++		num_wrbs = be_tx_compl_process(adapter, txo, end_idx);
++		atomic_sub(num_wrbs, &txq->used);
++	}
+ }
+ 
+ static void be_mcc_queues_destroy(struct be_adapter *adapter)
+@@ -1145,8 +1791,9 @@ static int be_mcc_queues_create(struct be_adapter *adapter)
+ 		goto mcc_cq_destroy;
+ 
+ 	/* Ask BE to create MCC queue */
+-	if (be_cmd_mccq_create(adapter, q, cq))
++	if (be_cmd_mccq_create(adapter, q, cq)) {
+ 		goto mcc_q_free;
++	}
+ 
+ 	return 0;
+ 
+@@ -1163,16 +1810,20 @@ err:
+ static void be_tx_queues_destroy(struct be_adapter *adapter)
+ {
+ 	struct be_queue_info *q;
++	struct be_tx_obj *txo;
++	u8 i;
+ 
+-	q = &adapter->tx_obj.q;
+-	if (q->created)
+-		be_cmd_q_destroy(adapter, q, QTYPE_TXQ);
+-	be_queue_free(adapter, q);
++	for_all_tx_queues(adapter, txo, i) {
++		q = &txo->q;
++		if (q->created)
++			be_cmd_q_destroy(adapter, q, QTYPE_TXQ);
++		be_queue_free(adapter, q);
+ 
+-	q = &adapter->tx_obj.cq;
+-	if (q->created)
+-		be_cmd_q_destroy(adapter, q, QTYPE_CQ);
+-	be_queue_free(adapter, q);
++		q = &txo->cq;
++		if (q->created)
++			be_cmd_q_destroy(adapter, q, QTYPE_CQ);
++		be_queue_free(adapter, q);
++	}
+ 
+ 	/* Clear any residual events */
+ 	be_eq_clean(adapter, &adapter->tx_eq);
+@@ -1183,168 +1834,210 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
+ 	be_queue_free(adapter, q);
+ }
+ 
++/* One TX event queue is shared by all TX compl qs */
+ static int be_tx_queues_create(struct be_adapter *adapter)
+ {
+ 	struct be_queue_info *eq, *q, *cq;
++	struct be_tx_obj *txo;
++	u8 i, tc_id;
+ 
+ 	adapter->tx_eq.max_eqd = 0;
+ 	adapter->tx_eq.min_eqd = 0;
+ 	adapter->tx_eq.cur_eqd = 96;
+ 	adapter->tx_eq.enable_aic = false;
+-	/* Alloc Tx Event queue */
++
+ 	eq = &adapter->tx_eq.q;
+-	if (be_queue_alloc(adapter, eq, EVNT_Q_LEN, sizeof(struct be_eq_entry)))
++	if (be_queue_alloc(adapter, eq, EVNT_Q_LEN,
++		sizeof(struct be_eq_entry)))
+ 		return -1;
+ 
+-	/* Ask BE to create Tx Event queue */
+ 	if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd))
+-		goto tx_eq_free;
+-	/* Alloc TX eth compl queue */
+-	cq = &adapter->tx_obj.cq;
+-	if (be_queue_alloc(adapter, cq, TX_CQ_LEN,
++		goto err;
++	adapter->tx_eq.eq_idx = adapter->eq_next_idx++;
++
++	for_all_tx_queues(adapter, txo, i) {
++		cq = &txo->cq;
++		if (be_queue_alloc(adapter, cq, TX_CQ_LEN,
+ 			sizeof(struct be_eth_tx_compl)))
+-		goto tx_eq_destroy;
++			goto err;
+ 
+-	/* Ask BE to create Tx eth compl queue */
+-	if (be_cmd_cq_create(adapter, cq, eq, false, false, 3))
+-		goto tx_cq_free;
++		if (be_cmd_cq_create(adapter, cq, eq, false, false, 3))
++			goto err;
+ 
+-	/* Alloc TX eth queue */
+-	q = &adapter->tx_obj.q;
+-	if (be_queue_alloc(adapter, q, TX_Q_LEN, sizeof(struct be_eth_wrb)))
+-		goto tx_cq_destroy;
++		q = &txo->q;
++		if (be_queue_alloc(adapter, q, TX_Q_LEN,
++			sizeof(struct be_eth_wrb)))
++			goto err;
+ 
+-	/* Ask BE to create Tx eth queue */
+-	if (be_cmd_txq_create(adapter, q, cq))
+-		goto tx_q_free;
++		if (be_cmd_txq_create(adapter, q, cq, &tc_id))
++			goto err;
++		
++		if (adapter->flags & BE_FLAGS_DCBX)
++			adapter->tc_txq_map[tc_id] = i;
++	}
+ 	return 0;
+ 
+-tx_q_free:
+-	be_queue_free(adapter, q);
+-tx_cq_destroy:
+-	be_cmd_q_destroy(adapter, cq, QTYPE_CQ);
+-tx_cq_free:
+-	be_queue_free(adapter, cq);
+-tx_eq_destroy:
+-	be_cmd_q_destroy(adapter, eq, QTYPE_EQ);
+-tx_eq_free:
+-	be_queue_free(adapter, eq);
++err:
++	be_tx_queues_destroy(adapter);
+ 	return -1;
+ }
+ 
+ static void be_rx_queues_destroy(struct be_adapter *adapter)
+ {
+ 	struct be_queue_info *q;
++	struct be_rx_obj *rxo;
++	int i;
+ 
+-	q = &adapter->rx_obj.q;
+-	if (q->created) {
+-		be_cmd_q_destroy(adapter, q, QTYPE_RXQ);
+-		be_rx_q_clean(adapter);
+-	}
+-	be_queue_free(adapter, q);
++	for_all_rx_queues(adapter, rxo, i) {
++		be_queue_free(adapter, &rxo->q);
++
++		q = &rxo->cq;
++		if (q->created)
++			be_cmd_q_destroy(adapter, q, QTYPE_CQ);
++		be_queue_free(adapter, q);
+ 
+-	q = &adapter->rx_obj.cq;
+-	if (q->created)
+-		be_cmd_q_destroy(adapter, q, QTYPE_CQ);
+-	be_queue_free(adapter, q);
++		q = &rxo->rx_eq.q;
++		if (q->created)
++			be_cmd_q_destroy(adapter, q, QTYPE_EQ);
++		be_queue_free(adapter, q);
+ 
+-	/* Clear any residual events */
+-	be_eq_clean(adapter, &adapter->rx_eq);
++		kfree(rxo->page_info_tbl);
++	}
++}
+ 
+-	q = &adapter->rx_eq.q;
+-	if (q->created)
+-		be_cmd_q_destroy(adapter, q, QTYPE_EQ);
+-	be_queue_free(adapter, q);
++/* Is BE in a multi-channel mode */
++static inline bool be_is_mc(struct be_adapter *adapter) {
++	return (adapter->function_mode & FLEX10_MODE ||
++		adapter->function_mode & VNIC_MODE ||
++		adapter->function_mode & UMC_ENABLED);
++}
++
++static u32 be_num_rxqs_want(struct be_adapter *adapter)
++{
++	if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
++		adapter->num_vfs == 0 && be_physfn(adapter) &&
++		!be_is_mc(adapter)) {
++		return 1 + MAX_RSS_QS; /* one default non-RSS queue */
++	} else {
++		dev_warn(&adapter->pdev->dev,
++			"No support for multiple RX queues\n");
++		return 1;
++	}
+ }
+ 
+ static int be_rx_queues_create(struct be_adapter *adapter)
+ {
+ 	struct be_queue_info *eq, *q, *cq;
+-	int rc;
++	struct be_rx_obj *rxo;
++	int rc, i;
+ 
++	adapter->num_rx_qs = min(be_num_rxqs_want(adapter),
++				msix_enabled(adapter) ?
++					adapter->num_msix_vec - 1 : 1);
++	if (adapter->num_rx_qs != MAX_RX_QS)
++		dev_warn(&adapter->pdev->dev,
++			"Could create only %d receive queues",
++			adapter->num_rx_qs);
++
++	adapter->max_rx_coal = gro ? BE_INIT_FRAGS_PER_FRAME : 1;
+ 	adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
+-	adapter->rx_eq.max_eqd = BE_MAX_EQD;
+-	adapter->rx_eq.min_eqd = 0;
+-	adapter->rx_eq.cur_eqd = 0;
+-	adapter->rx_eq.enable_aic = true;
++	for_all_rx_queues(adapter, rxo, i) {
++		rxo->adapter = adapter;
++		rxo->rx_eq.max_eqd = BE_MAX_EQD;
++		rxo->rx_eq.enable_aic = true;
+ 
+-	/* Alloc Rx Event queue */
+-	eq = &adapter->rx_eq.q;
+-	rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN,
+-				sizeof(struct be_eq_entry));
+-	if (rc)
+-		return rc;
++		/* EQ */
++		eq = &rxo->rx_eq.q;
++		rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN,
++					sizeof(struct be_eq_entry));
++		if (rc)
++			goto err;
+ 
+-	/* Ask BE to create Rx Event queue */
+-	rc = be_cmd_eq_create(adapter, eq, adapter->rx_eq.cur_eqd);
+-	if (rc)
+-		goto rx_eq_free;
++		rc = be_cmd_eq_create(adapter, eq, rxo->rx_eq.cur_eqd);
++		if (rc)
++			goto err;
+ 
+-	/* Alloc RX eth compl queue */
+-	cq = &adapter->rx_obj.cq;
+-	rc = be_queue_alloc(adapter, cq, RX_CQ_LEN,
+-			sizeof(struct be_eth_rx_compl));
+-	if (rc)
+-		goto rx_eq_destroy;
++		rxo->rx_eq.eq_idx = adapter->eq_next_idx++;
+ 
+-	/* Ask BE to create Rx eth compl queue */
+-	rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3);
+-	if (rc)
+-		goto rx_cq_free;
++		/* CQ */
++		cq = &rxo->cq;
++		rc = be_queue_alloc(adapter, cq, RX_CQ_LEN,
++				sizeof(struct be_eth_rx_compl));
++		if (rc)
++			goto err;
+ 
+-	/* Alloc RX eth queue */
+-	q = &adapter->rx_obj.q;
+-	rc = be_queue_alloc(adapter, q, RX_Q_LEN, sizeof(struct be_eth_rx_d));
+-	if (rc)
+-		goto rx_cq_destroy;
++		rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3);
++		if (rc)
++			goto err;
+ 
+-	/* Ask BE to create Rx eth queue */
+-	rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size,
+-		BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, false);
+-	if (rc)
+-		goto rx_q_free;
++		/* Rx Q - will be created in be_open() */
++		q = &rxo->q;
++		rc = be_queue_alloc(adapter, q, RX_Q_LEN,
++				sizeof(struct be_eth_rx_d));
++		if (rc)
++			goto err;
++
++		rxo->page_info_tbl = kzalloc(sizeof(struct be_rx_page_info) *
++					RX_Q_LEN, GFP_KERNEL);
++		if (!rxo->page_info_tbl)
++			goto err;
++	}
+ 
+ 	return 0;
+-rx_q_free:
+-	be_queue_free(adapter, q);
+-rx_cq_destroy:
+-	be_cmd_q_destroy(adapter, cq, QTYPE_CQ);
+-rx_cq_free:
+-	be_queue_free(adapter, cq);
+-rx_eq_destroy:
+-	be_cmd_q_destroy(adapter, eq, QTYPE_EQ);
+-rx_eq_free:
+-	be_queue_free(adapter, eq);
+-	return rc;
++err:
++	be_rx_queues_destroy(adapter);
++	return -1;
+ }
+ 
+-/* There are 8 evt ids per func. Retruns the evt id's bit number */
+-static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
++static bool event_peek(struct be_eq_obj *eq_obj)
+ {
+-	return eq_id - 8 * be_pci_func(adapter);
++	struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q);
++	if (!eqe->evt)
++		return false;
++	else
++		return true;
+ }
+ 
+ static irqreturn_t be_intx(int irq, void *dev)
+ {
+ 	struct be_adapter *adapter = dev;
+-	int isr;
++	struct be_rx_obj *rxo;
++	int isr, i, tx = 0 , rx = 0;
+ 
+-	isr = ioread32(adapter->csr + CEV_ISR0_OFFSET +
+-			be_pci_func(adapter) * CEV_ISR_SIZE);
+-	if (!isr)
+-		return IRQ_NONE;
++	if (lancer_chip(adapter)) {
++		if (event_peek(&adapter->tx_eq))
++			tx = event_handle(adapter, &adapter->tx_eq, false);
++		for_all_rx_queues(adapter, rxo, i) {
++			if (event_peek(&rxo->rx_eq))
++				rx |= event_handle(adapter, &rxo->rx_eq, true);
++		}
+ 
+-	event_handle(adapter, &adapter->tx_eq);
+-	event_handle(adapter, &adapter->rx_eq);
++		if (!(tx || rx))
++			return IRQ_NONE;
++	} else {
++		isr = ioread32(adapter->csr + CEV_ISR0_OFFSET +
++			(adapter->tx_eq.q.id / 8) * CEV_ISR_SIZE);
++		if (!isr)
++			return IRQ_NONE;
++
++		if ((1 << adapter->tx_eq.eq_idx & isr))
++			event_handle(adapter, &adapter->tx_eq, false);
++
++		for_all_rx_queues(adapter, rxo, i) {
++			if ((1 << rxo->rx_eq.eq_idx & isr))
++				event_handle(adapter, &rxo->rx_eq, true);
++		}
++	}
+ 
+ 	return IRQ_HANDLED;
+ }
+ 
+ static irqreturn_t be_msix_rx(int irq, void *dev)
+ {
+-	struct be_adapter *adapter = dev;
++	struct be_rx_obj *rxo = dev;
++	struct be_adapter *adapter = rxo->adapter;
+ 
+-	event_handle(adapter, &adapter->rx_eq);
++	event_handle(adapter, &rxo->rx_eq, true);
+ 
+ 	return IRQ_HANDLED;
+ }
+@@ -1353,48 +2046,72 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev)
+ {
+ 	struct be_adapter *adapter = dev;
+ 
+-	event_handle(adapter, &adapter->tx_eq);
++	event_handle(adapter, &adapter->tx_eq, false);
+ 
+ 	return IRQ_HANDLED;
+ }
+ 
+ static inline bool do_gro(struct be_adapter *adapter,
+-			struct be_eth_rx_compl *rxcp)
++			struct be_rx_compl_info *rxcp)
+ {
+-	int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp);
+-	int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
+-
+-	if (err)
+-		drvr_stats(adapter)->be_rxcp_err++;
+-
+-	return (tcp_frame && !err) ? true : false;
++	return (!rxcp->tcpf || rxcp->err || adapter->max_rx_coal <= 1 ||
++		(rxcp->vlanf && !vlan_configured(adapter))) ?
++		false : true;
+ }
+ 
+ int be_poll_rx(struct napi_struct *napi, int budget)
+ {
+ 	struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi);
+-	struct be_adapter *adapter =
+-		container_of(rx_eq, struct be_adapter, rx_eq);
+-	struct be_queue_info *rx_cq = &adapter->rx_obj.cq;
+-	struct be_eth_rx_compl *rxcp;
++	struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq);
++	struct be_adapter *adapter = rxo->adapter;
++	struct be_queue_info *rx_cq = &rxo->cq;
++	struct be_rx_compl_info *rxcp;
+ 	u32 work_done;
++	bool flush_lro = false;
+ 
++	rxo->stats.rx_polls++;
+ 	for (work_done = 0; work_done < budget; work_done++) {
+-		rxcp = be_rx_compl_get(adapter);
++		rxcp = be_rx_compl_get(rxo);
+ 		if (!rxcp)
+ 			break;
+ 
+-		if (do_gro(adapter, rxcp))
+-			be_rx_compl_process_gro(adapter, rxcp);
+-		else
+-			be_rx_compl_process(adapter, rxcp);
++		/* Is it a flush compl that has no data */
++		if (unlikely(rxcp->num_rcvd == 0))
++			continue;
+ 
+-		be_rx_compl_reset(rxcp);
++		if (unlikely(rxcp->port != adapter->port_num)) {
++			be_rx_compl_discard(adapter, rxo, rxcp);
++			be_rx_stats_update(rxo, rxcp);
++			continue;
++		}
++
++		if (likely((lancer_A0_chip(adapter) && !rxcp->err) ||
++					!lancer_A0_chip(adapter))) {
++			if (do_gro(adapter, rxcp)) {
++				if (adapter->gro_supported) {
++					be_rx_compl_process_gro(adapter, rxo,
++									rxcp);
++				} else {
++					be_rx_compl_process_lro(adapter, rxo,
++									rxcp);
++					flush_lro = true;
++				}
++			} else {
++				be_rx_compl_process(adapter, rxo, rxcp);
++			}
++		} else if (lancer_A0_chip(adapter) && rxcp->err) {
++			be_rx_compl_discard(adapter, rxo, rxcp);
++		}
++
++		be_rx_stats_update(rxo, rxcp);
+ 	}
+ 
++	if (flush_lro)
++		lro_flush_all(&rxo->lro_mgr);
++
+ 	/* Refill the queue */
+-	if (atomic_read(&adapter->rx_obj.q.used) < RX_FRAGS_REFILL_WM)
+-		be_post_rx_frags(adapter);
++	if (work_done && atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM)
++		be_post_rx_frags(rxo);
+ 
+ 	/* All consumed */
+ 	if (work_done < budget) {
+@@ -1404,40 +2121,13 @@ int be_poll_rx(struct napi_struct *napi, int budget)
+ 		/* More to be consumed; continue with interrupts disabled */
+ 		be_cq_notify(adapter, rx_cq->id, false, work_done);
+ 	}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
++	adapter->netdev->last_rx = jiffies;
++#endif
+ 	return work_done;
+ }
+ 
+-void be_process_tx(struct be_adapter *adapter)
+-{
+-	struct be_queue_info *txq = &adapter->tx_obj.q;
+-	struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
+-	struct be_eth_tx_compl *txcp;
+-	u32 num_cmpl = 0;
+-	u16 end_idx;
+-
+-	while ((txcp = be_tx_compl_get(tx_cq))) {
+-		end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
+-					wrb_index, txcp);
+-		be_tx_compl_process(adapter, end_idx);
+-		num_cmpl++;
+-	}
+-
+-	if (num_cmpl) {
+-		be_cq_notify(adapter, tx_cq->id, true, num_cmpl);
+-
+-		/* As Tx wrbs have been freed up, wake up netdev queue if
+-		 * it was stopped due to lack of tx wrbs.
+-		 */
+-		if (netif_queue_stopped(adapter->netdev) &&
+-			atomic_read(&txq->used) < txq->len / 2) {
+-			netif_wake_queue(adapter->netdev);
+-		}
+-
+-		drvr_stats(adapter)->be_tx_events++;
+-		drvr_stats(adapter)->be_tx_compl += num_cmpl;
+-	}
+-}
+-
+ /* As TX and MCC share the same EQ check for both TX and MCC completions.
+  * For TX/MCC we don't honour budget; consume everything
+  */
+@@ -1446,96 +2136,264 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
+ 	struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi);
+ 	struct be_adapter *adapter =
+ 		container_of(tx_eq, struct be_adapter, tx_eq);
++	struct be_tx_obj *txo;
++	struct be_eth_tx_compl *txcp;
++	int tx_compl, mcc_compl, status = 0;
++	u8 i;
++	u16 num_wrbs;
++
++	for_all_tx_queues(adapter, txo, i) {
++		tx_compl = 0;
++		num_wrbs = 0;
++		while ((txcp = be_tx_compl_get(&txo->cq))) {
++			num_wrbs += be_tx_compl_process(adapter, txo,
++				AMAP_GET_BITS(struct amap_eth_tx_compl,
++					wrb_index, txcp));
++			tx_compl++;
++		}
++		if (tx_compl) {
++			be_cq_notify(adapter, txo->cq.id, true, tx_compl);
++
++			atomic_sub(num_wrbs, &txo->q.used);
++
++			/* As Tx wrbs have been freed up, wake up netdev queue
++			 * if it was stopped due to lack of tx wrbs.  */
++			if (__netif_subqueue_stopped(adapter->netdev, i) &&
++				atomic_read(&txo->q.used) < txo->q.len / 2) {
++				netif_wake_subqueue(adapter->netdev, i);
++			}
++
++			adapter->drv_stats.be_tx_events++;
++			txo->stats.be_tx_compl += tx_compl;
++		}
++	}
++
++	mcc_compl = be_process_mcc(adapter, &status);
++
++	if (mcc_compl) {
++		struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
++		be_cq_notify(adapter, mcc_obj->cq.id, true, mcc_compl);
++	}
+ 
+ 	napi_complete(napi);
+ 
+-	be_process_tx(adapter);
+-
+-	be_process_mcc(adapter);
+-
++	be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
+ 	return 1;
+ }
+ 
++void be_detect_dump_ue(struct be_adapter *adapter)
++{
++	u32 ue_status_lo, ue_status_hi, ue_status_lo_mask, ue_status_hi_mask;
++	u32 i;
++
++	pci_read_config_dword(adapter->pdev,
++				PCICFG_UE_STATUS_LOW, &ue_status_lo);
++	pci_read_config_dword(adapter->pdev,
++				PCICFG_UE_STATUS_HIGH, &ue_status_hi);
++	pci_read_config_dword(adapter->pdev,
++				PCICFG_UE_STATUS_LOW_MASK, &ue_status_lo_mask);
++	pci_read_config_dword(adapter->pdev,
++				PCICFG_UE_STATUS_HI_MASK, &ue_status_hi_mask);
++
++	ue_status_lo = (ue_status_lo & (~ue_status_lo_mask));
++	ue_status_hi = (ue_status_hi & (~ue_status_hi_mask));
++
++	if (ue_status_lo || ue_status_hi) {
++		adapter->ue_detected = true;
++		adapter->eeh_err = true;
++		dev_err(&adapter->pdev->dev, "UE Detected!!\n");
++	}
++
++	if (ue_status_lo) {
++		for (i = 0; ue_status_lo; ue_status_lo >>= 1, i++) {
++			if (ue_status_lo & 1)
++				dev_err(&adapter->pdev->dev,
++				"UE: %s bit set\n", ue_status_low_desc[i]);
++		}
++	}
++	if (ue_status_hi) {
++		for (i = 0; ue_status_hi; ue_status_hi >>= 1, i++) {
++			if (ue_status_hi & 1)
++				dev_err(&adapter->pdev->dev,
++				"UE: %s bit set\n", ue_status_hi_desc[i]);
++		}
++	}
++
++}
++
+ static void be_worker(struct work_struct *work)
+ {
+ 	struct be_adapter *adapter =
+ 		container_of(work, struct be_adapter, work.work);
++	struct be_rx_obj *rxo;
++	struct be_tx_obj *txo;
++	int i;
+ 
+-	be_cmd_get_stats(adapter, &adapter->stats.cmd);
++	if (!adapter->ue_detected && !lancer_chip(adapter))
++		be_detect_dump_ue(adapter);
+ 
+-	/* Set EQ delay */
+-	be_rx_eqd_update(adapter);
++	/* when interrupts are not yet enabled, just reap any pending
++	* mcc completions */
++	if (!netif_running(adapter->netdev)) {
++		int mcc_compl, status = 0;
+ 
+-	be_tx_rate_update(adapter);
+-	be_rx_rate_update(adapter);
++		mcc_compl = be_process_mcc(adapter, &status);
+ 
+-	if (adapter->rx_post_starved) {
+-		adapter->rx_post_starved = false;
+-		be_post_rx_frags(adapter);
++		if (mcc_compl) {
++			struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
++			be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl);
++		}
++
++		goto reschedule;
++	}
++
++	if (!adapter->stats_cmd_sent)
++		be_cmd_get_stats(adapter, &adapter->stats_cmd);
++
++	for_all_tx_queues(adapter, txo, i)
++		be_tx_rate_update(txo);
++
++	for_all_rx_queues(adapter, rxo, i) {
++		be_rx_rate_update(rxo);
++		be_rx_eqd_update(adapter, rxo);
++
++		if (rxo->rx_post_starved) {
++			rxo->rx_post_starved = false;
++			be_post_rx_frags(rxo);
++		}
+ 	}
+ 
++reschedule:
++	adapter->work_counter++;
+ 	schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
+ }
+ 
++static void be_msix_disable(struct be_adapter *adapter)
++{
++	if (msix_enabled(adapter)) {
++		pci_disable_msix(adapter->pdev);
++		adapter->num_msix_vec = 0;
++	}
++}
++
+ static void be_msix_enable(struct be_adapter *adapter)
+ {
+-	int i, status;
++#define BE_MIN_MSIX_VECTORS	(1 + 1) /* Rx + Tx */
++	int i, status, num_vec;
+ 
+-	for (i = 0; i < BE_NUM_MSIX_VECTORS; i++)
++	num_vec = be_num_rxqs_want(adapter) + 1;
++
++	for (i = 0; i < num_vec; i++)
+ 		adapter->msix_entries[i].entry = i;
+ 
+-	status = pci_enable_msix(adapter->pdev, adapter->msix_entries,
+-		BE_NUM_MSIX_VECTORS);
+-	if (status == 0)
+-		adapter->msix_enabled = true;
++	status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec);
++	if (status == 0) {
++		goto done;
++	} else if (status >= BE_MIN_MSIX_VECTORS) {
++		num_vec = status;
++		if (pci_enable_msix(adapter->pdev, adapter->msix_entries,
++				num_vec) == 0)
++			goto done;
++	}
+ 	return;
++done:
++	adapter->num_msix_vec = num_vec;
++	return;
++}
++
++static void be_sriov_enable(struct be_adapter *adapter)
++{
++	be_check_sriov_fn_type(adapter);
++#ifdef CONFIG_PCI_IOV
++	if (be_physfn(adapter) && num_vfs) {
++		int status, pos;
++		u16 nvfs;
++
++		pos = pci_find_ext_capability(adapter->pdev,
++						PCI_EXT_CAP_ID_SRIOV);
++		pci_read_config_word(adapter->pdev,
++					pos + PCI_SRIOV_TOTAL_VF, &nvfs);
++		adapter->num_vfs = num_vfs;
++		if (num_vfs > nvfs) {
++			dev_info(&adapter->pdev->dev,
++					"Device supports %d VFs and not %d\n",
++					nvfs, num_vfs);
++			adapter->num_vfs = nvfs;
++		}
++
++		status = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
++		if (status)
++			adapter->num_vfs = 0;
++	}
++#endif
++}
++
++static void be_sriov_disable(struct be_adapter *adapter)
++{
++#ifdef CONFIG_PCI_IOV
++	if (adapter->num_vfs > 0) {
++		pci_disable_sriov(adapter->pdev);
++		adapter->num_vfs = 0;
++	}
++#endif
+ }
+ 
+-static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id)
++static inline int be_msix_vec_get(struct be_adapter *adapter,
++				struct be_eq_obj *eq_obj)
+ {
+-	return adapter->msix_entries[
+-			be_evt_bit_get(adapter, eq_id)].vector;
++	return adapter->msix_entries[eq_obj->eq_idx].vector;
+ }
+ 
+ static int be_request_irq(struct be_adapter *adapter,
+ 		struct be_eq_obj *eq_obj,
+-		void *handler, char *desc)
++		void *handler, char *desc, void *context)
+ {
+ 	struct net_device *netdev = adapter->netdev;
+ 	int vec;
+ 
+ 	sprintf(eq_obj->desc, "%s-%s", netdev->name, desc);
+-	vec = be_msix_vec_get(adapter, eq_obj->q.id);
+-	return request_irq(vec, handler, 0, eq_obj->desc, adapter);
++	vec = be_msix_vec_get(adapter, eq_obj);
++	return request_irq(vec, handler, 0, eq_obj->desc, context);
+ }
+ 
+-static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj)
++static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj,
++			void *context)
+ {
+-	int vec = be_msix_vec_get(adapter, eq_obj->q.id);
+-	free_irq(vec, adapter);
++	int vec = be_msix_vec_get(adapter, eq_obj);
++	free_irq(vec, context);
+ }
+ 
+ static int be_msix_register(struct be_adapter *adapter)
+ {
+-	int status;
++	struct be_rx_obj *rxo;
++	int status, i;
++	char qname[10];
+ 
+-	status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx");
++	status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx",
++				adapter);
+ 	if (status)
+ 		goto err;
+ 
+-	status = be_request_irq(adapter, &adapter->rx_eq, be_msix_rx, "rx");
+-	if (status)
+-		goto free_tx_irq;
++	for_all_rx_queues(adapter, rxo, i) {
++		sprintf(qname, "rxq%d", i);
++		status = be_request_irq(adapter, &rxo->rx_eq, be_msix_rx,
++				qname, rxo);
++		if (status)
++			goto err_msix;
++	}
+ 
+ 	return 0;
+ 
+-free_tx_irq:
+-	be_free_irq(adapter, &adapter->tx_eq);
++err_msix:
++	be_free_irq(adapter, &adapter->tx_eq, adapter);
++
++	for (i--, rxo = &adapter->rx_obj[i]; i >= 0; i--, rxo--)
++		be_free_irq(adapter, &rxo->rx_eq, rxo);
++
+ err:
+ 	dev_warn(&adapter->pdev->dev,
+ 		"MSIX Request IRQ failed - err %d\n", status);
+-	pci_disable_msix(adapter->pdev);
+-	adapter->msix_enabled = false;
++	be_msix_disable(adapter);
+ 	return status;
+ }
+ 
+@@ -1544,10 +2402,13 @@ static int be_irq_register(struct be_adapter *adapter)
+ 	struct net_device *netdev = adapter->netdev;
+ 	int status;
+ 
+-	if (adapter->msix_enabled) {
++	if (msix_enabled(adapter)) {
+ 		status = be_msix_register(adapter);
+ 		if (status == 0)
+ 			goto done;
++		/* INTx is not supported for VF */
++		if (!be_physfn(adapter))
++			return status;
+ 	}
+ 
+ 	/* INTx */
+@@ -1567,87 +2428,363 @@ done:
+ static void be_irq_unregister(struct be_adapter *adapter)
+ {
+ 	struct net_device *netdev = adapter->netdev;
++	struct be_rx_obj *rxo;
++	int i;
+ 
+ 	if (!adapter->isr_registered)
+ 		return;
+ 
+ 	/* INTx */
+-	if (!adapter->msix_enabled) {
++	if (!msix_enabled(adapter)) {
+ 		free_irq(netdev->irq, adapter);
+ 		goto done;
+ 	}
+ 
+ 	/* MSIx */
+-	be_free_irq(adapter, &adapter->tx_eq);
+-	be_free_irq(adapter, &adapter->rx_eq);
++	be_free_irq(adapter, &adapter->tx_eq, adapter);
++
++	for_all_rx_queues(adapter, rxo, i)
++		be_free_irq(adapter, &rxo->rx_eq, rxo);
++
+ done:
+ 	adapter->isr_registered = false;
+-	return;
+ }
+ 
+-static int be_open(struct net_device *netdev)
++static u16 be_select_queue(struct net_device *netdev,
++			struct sk_buff *skb)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+-	struct be_eq_obj *rx_eq = &adapter->rx_eq;
++	u8 prio;
++
++	if (adapter->num_tx_qs == 1)
++		return 0;
++
++	prio = (vlan_tx_tag_get(skb) & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
++	return adapter->tc_txq_map[adapter->prio_tc_map[prio]];
++}
++
++static void be_rx_queues_clear(struct be_adapter *adapter)
++{
++	struct be_queue_info *q;
++	struct be_rx_obj *rxo;
++	int i;
++
++	for_all_rx_queues(adapter, rxo, i) {
++		q = &rxo->q;
++		if (q->created) {
++			be_cmd_rxq_destroy(adapter, q);
++			/* After the rxq is invalidated, wait for a grace time
++			 * of 1ms for all dma to end and the flush compl to
++			 * arrive
++			 */
++			mdelay(1);
++			be_rx_q_clean(adapter, rxo);
++		}
++
++		/* Clear any residual events */
++		q = &rxo->rx_eq.q;
++		if (q->created)
++			be_eq_clean(adapter, &rxo->rx_eq);
++	}
++}
++
++static int be_close(struct net_device *netdev)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++	struct be_rx_obj *rxo;
++	struct be_tx_obj *txo;
+ 	struct be_eq_obj *tx_eq = &adapter->tx_eq;
+-	bool link_up;
+-	int status;
++	int vec, i;
++
++	be_async_mcc_disable(adapter);
++
++	netif_stop_queue(netdev);
++	netif_carrier_off(netdev);
++	adapter->link_status = LINK_DOWN;
++
++	if (!lancer_chip(adapter))
++		be_intr_set(adapter, false);
++
++	for_all_rx_queues(adapter, rxo, i)
++		napi_disable(&rxo->rx_eq.napi);
++
++	napi_disable(&tx_eq->napi);
++
++	if (lancer_chip(adapter)) {
++		be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0);
++		for_all_rx_queues(adapter, rxo, i)
++			 be_cq_notify(adapter, rxo->cq.id, false, 0);
++		for_all_tx_queues(adapter, txo, i)
++			 be_cq_notify(adapter, txo->cq.id, false, 0);
++	}
++
++	if (msix_enabled(adapter)) {
++		vec = be_msix_vec_get(adapter, tx_eq);
++		synchronize_irq(vec);
++
++		for_all_rx_queues(adapter, rxo, i) {
++			vec = be_msix_vec_get(adapter, &rxo->rx_eq);
++			synchronize_irq(vec);
++		}
++	} else {
++		synchronize_irq(netdev->irq);
++	}
++	be_irq_unregister(adapter);
++
++	/* Wait for all pending tx completions to arrive so that
++	 * all tx skbs are freed.
++	 */
++	for_all_tx_queues(adapter, txo, i)
++		be_tx_compl_clean(adapter, txo);
++
++	be_rx_queues_clear(adapter);
++	return 0;
++}
++
++static int be_rx_queues_setup(struct be_adapter *adapter)
++{
++	struct be_rx_obj *rxo;
++	int rc, i;
++	u8 rsstable[MAX_RSS_QS];
++
++	for_all_rx_queues(adapter, rxo, i) {
++		rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id,
++			rx_frag_size, BE_MAX_JUMBO_FRAME_SIZE,
++			adapter->if_handle,
++			(i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id);
++		if (rc)
++			return rc;
++	}
++
++	if (be_multi_rxq(adapter)) {
++		for_all_rss_queues(adapter, rxo, i)
++			rsstable[i] = rxo->rss_id;
++
++		rc = be_cmd_rss_config(adapter, rsstable,
++			adapter->num_rx_qs - 1);
++		if (rc)
++			return rc;
++	}
+ 
+ 	/* First time posting */
+-	be_post_rx_frags(adapter);
++	for_all_rx_queues(adapter, rxo, i) {
++		be_post_rx_frags(rxo);
++		napi_enable(&rxo->rx_eq.napi);
++	}
++	return 0;
++}
++
++static int be_open(struct net_device *netdev)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++	struct be_eq_obj *tx_eq = &adapter->tx_eq;
++	struct be_rx_obj *rxo;
++	int link_status;
++	int status, i;
++	u8 mac_speed;
++	u16 link_speed;
++
++	status = be_rx_queues_setup(adapter);
++	if (status)
++		goto err;
+ 
+-	napi_enable(&rx_eq->napi);
+ 	napi_enable(&tx_eq->napi);
+ 
+ 	be_irq_register(adapter);
+ 
+-	be_intr_set(adapter, true);
++	if (!lancer_chip(adapter))
++		be_intr_set(adapter, true);
+ 
+ 	/* The evt queues are created in unarmed state; arm them */
+-	be_eq_notify(adapter, rx_eq->q.id, true, false, 0);
++	for_all_rx_queues(adapter, rxo, i) {
++		be_eq_notify(adapter, rxo->rx_eq.q.id, true, false, 0);
++		be_cq_notify(adapter, rxo->cq.id, true, 0);
++	}
+ 	be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
+ 
+-	/* Rx compl queue may be in unarmed state; rearm it */
+-	be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0);
++	/* Now that interrupts are on we can process async mcc */
++	be_async_mcc_enable(adapter);
+ 
+-	status = be_cmd_link_status_query(adapter, &link_up);
++	status = be_cmd_link_status_query(adapter, &link_status, &mac_speed,
++			&link_speed, 0);
+ 	if (status)
+-		goto ret_sts;
+-	be_link_status_update(adapter, link_up);
++		goto err;
++	be_link_status_update(adapter, link_status);
+ 
+-	status = be_vid_config(adapter);
++	status = be_vid_config(adapter, false, 0);
+ 	if (status)
+-		goto ret_sts;
++		goto err;
+ 
+-	status = be_cmd_set_flow_control(adapter,
+-					adapter->tx_fc, adapter->rx_fc);
+-	if (status)
+-		goto ret_sts;
++	if (be_physfn(adapter)) {
++		status = be_cmd_set_flow_control(adapter,
++				adapter->tx_fc, adapter->rx_fc);
++		if (status)
++			goto err;
++	}
++
++	return 0;
++err:
++	be_close(adapter->netdev);
++	return -EIO;
++}
++
++static int be_setup_wol(struct be_adapter *adapter, bool enable)
++{
++	struct be_dma_mem cmd;
++	int status = 0;
++	u8 mac[ETH_ALEN];
++
++	memset(mac, 0, ETH_ALEN);
++
++	cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
++	cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
++	if (cmd.va == NULL)
++		return -1;
++	memset(cmd.va, 0, cmd.size);
++
++	if (enable) {
++		status = pci_write_config_dword(adapter->pdev,
++			PCICFG_PM_CONTROL_OFFSET, PCICFG_PM_CONTROL_MASK);
++		if (status) {
++			dev_err(&adapter->pdev->dev,
++				"Could not enable Wake-on-lan\n");
++			pci_free_consistent(adapter->pdev, cmd.size, cmd.va,
++					cmd.dma);
++			return status;
++		}
++		status = be_cmd_enable_magic_wol(adapter,
++				adapter->netdev->dev_addr, &cmd);
++		pci_enable_wake(adapter->pdev, PCI_D3hot, 1);
++		pci_enable_wake(adapter->pdev, PCI_D3cold, 1);
++	} else {
++		status = be_cmd_enable_magic_wol(adapter, mac, &cmd);
++		pci_enable_wake(adapter->pdev, PCI_D3hot, 0);
++		pci_enable_wake(adapter->pdev, PCI_D3cold, 0);
++	}
++
++	pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
++	return status;
++}
++
++/*
++ * Generate a seed MAC address from the PF MAC Address using jhash.
++ * MAC Address for VFs are assigned incrementally starting from the seed.
++ * These addresses are programmed in the ASIC by the PF and the VF driver
++ * queries for the MAC address during its probe.
++ */
++static inline int be_vf_eth_addr_config(struct be_adapter *adapter)
++{
++	u32 vf = 0;
++	int status = 0;
++	u8 mac[ETH_ALEN];
++
++	be_vf_eth_addr_generate(adapter, mac);
++
++	for (vf = 0; vf < adapter->num_vfs; vf++) {
++		status = be_cmd_pmac_add(adapter, mac,
++					adapter->vf_cfg[vf].vf_if_handle,
++					&adapter->vf_cfg[vf].vf_pmac_id,
++					vf + 1);
++		if (status)
++			dev_err(&adapter->pdev->dev,
++				"Mac address add failed for VF %d\n", vf);
++		else
++			memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN);
+ 
+-	schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
+-ret_sts:
++		mac[5] += 1;
++	}
+ 	return status;
+ }
+ 
++static inline void be_vf_eth_addr_rem(struct be_adapter *adapter)
++{
++	u32 vf;
++
++	for (vf = 0; vf < adapter->num_vfs; vf++) {
++		if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID)
++			be_cmd_pmac_del(adapter,
++					adapter->vf_cfg[vf].vf_if_handle,
++					adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
++	}
++}
++
++static int be_num_txqs_want(struct be_adapter *adapter)
++{
++	if (adapter->num_vfs > 0 || be_is_mc(adapter) ||
++		lancer_chip(adapter) || !be_physfn(adapter) ||
++		adapter->generation == BE_GEN2)
++		return 1;
++	else
++		return MAX_TX_QS;
++}
++
+ static int be_setup(struct be_adapter *adapter)
+ {
+ 	struct net_device *netdev = adapter->netdev;
+-	u32 cap_flags, en_flags;
+-	int status;
+-
+-	cap_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+-			BE_IF_FLAGS_MCAST_PROMISCUOUS |
+-			BE_IF_FLAGS_PROMISCUOUS |
+-			BE_IF_FLAGS_PASS_L3L4_ERRORS;
+-	en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+-			BE_IF_FLAGS_PASS_L3L4_ERRORS;
++	int status, fw_num_txqs, num_txqs;
++	u32 cap_flags, en_flags, vf = 0;
++	u8 mac[ETH_ALEN];
++
++	num_txqs = be_num_txqs_want(adapter);
++	if (num_txqs > 1) {
++		be_cmd_req_pg_pfc(adapter, &fw_num_txqs);
++		num_txqs = min(num_txqs, fw_num_txqs);
++	}
++	adapter->num_tx_qs = num_txqs;
++	if (adapter->num_tx_qs != MAX_TX_QS)
++		netif_set_real_num_tx_queues(adapter->netdev,
++			adapter->num_tx_qs);
++
++	be_cmd_req_native_mode(adapter);
++
++	cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED |
++				BE_IF_FLAGS_BROADCAST |
++				BE_IF_FLAGS_MULTICAST;
++
++	if (be_physfn(adapter)) {
++		if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) {
++			cap_flags |= BE_IF_FLAGS_RSS;
++			en_flags |= BE_IF_FLAGS_RSS;
++		}
++		cap_flags |= BE_IF_FLAGS_MCAST_PROMISCUOUS |
++				BE_IF_FLAGS_PROMISCUOUS;
++		if (!lancer_A0_chip(adapter)) {
++			cap_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS;
++			en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS;
++		}
++	}
+ 
+ 	status = be_cmd_if_create(adapter, cap_flags, en_flags,
+ 			netdev->dev_addr, false/* pmac_invalid */,
+-			&adapter->if_handle, &adapter->pmac_id);
++			&adapter->if_handle, &adapter->pmac_id, 0);
+ 	if (status != 0)
+ 		goto do_none;
+ 
++	if (be_physfn(adapter)) {
++		while (vf < adapter->num_vfs) {
++			cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED |
++					BE_IF_FLAGS_BROADCAST;
++			status = be_cmd_if_create(adapter, cap_flags,
++					en_flags, mac, true,
++					&adapter->vf_cfg[vf].vf_if_handle,
++					NULL, vf+1);
++			if (status) {
++				dev_err(&adapter->pdev->dev,
++				"Interface Create failed for VF %d\n", vf);
++				goto if_destroy;
++			}
++			adapter->vf_cfg[vf].vf_pmac_id = BE_INVALID_PMAC_ID;
++			vf++;
++		}
++	} else {
++		status = be_cmd_mac_addr_query(adapter, mac,
++			MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle);
++		if (!status) {
++			memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
++			memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
++		}
++	}
++
+ 	status = be_tx_queues_create(adapter);
+ 	if (status != 0)
+ 		goto if_destroy;
+@@ -1656,10 +2793,15 @@ static int be_setup(struct be_adapter *adapter)
+ 	if (status != 0)
+ 		goto tx_qs_destroy;
+ 
++	/* Allow all priorities by default. A GRP5 evt may modify this */
++	adapter->vlan_prio_bmap = 0xff;
++
+ 	status = be_mcc_queues_create(adapter);
+ 	if (status != 0)
+ 		goto rx_qs_destroy;
+ 
++	adapter->link_speed = -1;
++
+ 	return 0;
+ 
+ rx_qs_destroy:
+@@ -1667,158 +2809,392 @@ rx_qs_destroy:
+ tx_qs_destroy:
+ 	be_tx_queues_destroy(adapter);
+ if_destroy:
+-	be_cmd_if_destroy(adapter, adapter->if_handle);
++	if (be_physfn(adapter)) {
++		for (vf = 0; vf < adapter->num_vfs; vf++)
++			if (adapter->vf_cfg[vf].vf_if_handle)
++				be_cmd_if_destroy(adapter,
++					adapter->vf_cfg[vf].vf_if_handle,
++					vf + 1);
++	}
++	be_cmd_if_destroy(adapter, adapter->if_handle, 0);
+ do_none:
+ 	return status;
+ }
+ 
+ static int be_clear(struct be_adapter *adapter)
+ {
++	int vf;
++
++	if (be_physfn(adapter) && adapter->num_vfs)
++		be_vf_eth_addr_rem(adapter);
++
+ 	be_mcc_queues_destroy(adapter);
+ 	be_rx_queues_destroy(adapter);
+ 	be_tx_queues_destroy(adapter);
++	adapter->eq_next_idx = 0;
+ 
+-	be_cmd_if_destroy(adapter, adapter->if_handle);
++	if (be_physfn(adapter)) {
++		for (vf = 0; vf < adapter->num_vfs; vf++)
++			if (adapter->vf_cfg[vf].vf_if_handle)
++				be_cmd_if_destroy(adapter,
++				adapter->vf_cfg[vf].vf_if_handle, vf + 1);
++	}
++	be_cmd_if_destroy(adapter, adapter->if_handle, 0);
+ 
++	/* tell fw we're done with firing cmds */
++	be_cmd_fw_clean(adapter);
+ 	return 0;
+ }
+ 
+-static int be_close(struct net_device *netdev)
++static void be_cpy_drv_ver(struct be_adapter *adapter, void *va)
++{
++	struct mgmt_controller_attrib *attrib =
++		(struct mgmt_controller_attrib *) ((u8*) va +
++				sizeof(struct be_cmd_resp_hdr));
++
++	memcpy(attrib->hba_attribs.driver_version_string,
++			DRV_VER, sizeof(DRV_VER));
++	attrib->pci_bus_number = adapter->pdev->bus->number;
++	attrib->pci_device_number = PCI_SLOT(adapter->pdev->devfn);
++	return;
++}
++
++#define IOCTL_COOKIE "SERVERENGINES CORP"
++static int be_do_ioctl(struct net_device *netdev,
++			struct ifreq *ifr, int cmd)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
+-	struct be_eq_obj *rx_eq = &adapter->rx_eq;
+-	struct be_eq_obj *tx_eq = &adapter->tx_eq;
+-	int vec;
++	struct be_cmd_req_hdr req;
++	struct be_cmd_resp_hdr *resp;
++	void *data = ifr->ifr_data;
++	void *ioctl_ptr;
++	void *va;
++	dma_addr_t dma;
++	u32 req_size;
++	int status, ret = 0;
++	u8 cookie[32];
++
++	switch (cmd) {
++	case SIOCDEVPRIVATE:
++		if (copy_from_user(cookie, data, strlen(IOCTL_COOKIE)))
++			return -EFAULT;
++
++		if (memcmp(cookie, IOCTL_COOKIE, strlen(IOCTL_COOKIE)))
++			return -EINVAL;
+ 
+-	cancel_delayed_work_sync(&adapter->work);
++		ioctl_ptr = (u8 *)data + strlen(IOCTL_COOKIE);
++		if (copy_from_user(&req, ioctl_ptr,
++				sizeof(struct be_cmd_req_hdr)))
++			return -EFAULT;
+ 
+-	netif_stop_queue(netdev);
+-	netif_carrier_off(netdev);
+-	adapter->link_up = false;
++		req_size = le32_to_cpu(req.request_length);
++		if (req_size > 65536)
++			return -EINVAL;
+ 
+-	be_intr_set(adapter, false);
++		req_size += sizeof(struct be_cmd_req_hdr);
++		va = pci_alloc_consistent(adapter->pdev, req_size, &dma);
++		if (!va)
++			return -ENOMEM;
++		if (copy_from_user(va, ioctl_ptr, req_size)) {
++			ret = -EFAULT;
++			break;
++		}
+ 
+-	if (adapter->msix_enabled) {
+-		vec = be_msix_vec_get(adapter, tx_eq->q.id);
+-		synchronize_irq(vec);
+-		vec = be_msix_vec_get(adapter, rx_eq->q.id);
+-		synchronize_irq(vec);
+-	} else {
+-		synchronize_irq(netdev->irq);
++		status = be_cmd_pass_ext_ioctl(adapter, dma, req_size, va);
++		if (status == -1) {
++			ret = -EIO;
++			break;
++		}
++
++		resp = (struct be_cmd_resp_hdr *) va;
++		if (!status) {
++			if (req.opcode == OPCODE_COMMON_GET_CNTL_ATTRIBUTES)
++				be_cpy_drv_ver(adapter, va);
++		}
++
++		if (copy_to_user(ioctl_ptr, va, req_size)) {
++			ret = -EFAULT;
++			break;
++		}
++		break;
++	default:
++		return -EOPNOTSUPP;
+ 	}
+-	be_irq_unregister(adapter);
+ 
+-	napi_disable(&rx_eq->napi);
+-	napi_disable(&tx_eq->napi);
++	if (va)
++		pci_free_consistent(adapter->pdev, req_size, va, dma);
++
++	return ret;
++}
++
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void be_netpoll(struct net_device *netdev)
++{
++	struct be_adapter *adapter = netdev_priv(netdev);
++	struct be_rx_obj *rxo;
++	int i;
+ 
+-	/* Wait for all pending tx completions to arrive so that
+-	 * all tx skbs are freed.
+-	 */
+-	be_tx_compl_clean(adapter);
++	event_handle(adapter, &adapter->tx_eq, false);
++	for_all_rx_queues(adapter, rxo, i)
++		event_handle(adapter, &rxo->rx_eq, true);
++
++	return;
++}
++#endif
++
++static int be_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
++				void **ip_hdr, void **tcpudp_hdr,
++				u64 *hdr_flags, void *priv)
++{
++	struct ethhdr *eh;
++	struct vlan_ethhdr *veh;
++	struct iphdr *iph;
++	u8 *va = page_address(frag->page) + frag->page_offset;
++	unsigned long ll_hlen;
++
++	prefetch(va);
++	eh = (struct ethhdr *)va;
++	*mac_hdr = eh;
++	ll_hlen = ETH_HLEN;
++	if (eh->h_proto != htons(ETH_P_IP)) {
++		if (eh->h_proto == htons(ETH_P_8021Q)) {
++			veh = (struct vlan_ethhdr *)va;
++			if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
++				return -1;
++
++			ll_hlen += VLAN_HLEN;
++		} else {
++			return -1;
++		}
++	}
++	*hdr_flags = LRO_IPV4;
++	iph = (struct iphdr *)(va + ll_hlen);
++	*ip_hdr = iph;
++	if (iph->protocol != IPPROTO_TCP)
++		return -1;
++	*hdr_flags |= LRO_TCP;
++	*tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2);
+ 
+ 	return 0;
+ }
+ 
+-#define FW_FILE_HDR_SIGN 	"ServerEngines Corp. "
++static void be_lro_init(struct be_adapter *adapter, struct net_device *netdev)
++{
++	struct net_lro_mgr *lro_mgr;
++	struct be_rx_obj *rxo;
++	int i;
++
++	for_all_rx_queues(adapter, rxo, i) {
++		lro_mgr = &rxo->lro_mgr;
++		lro_mgr->dev = netdev;
++		lro_mgr->features = LRO_F_NAPI;
++		lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
++		lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
++		lro_mgr->max_desc = BE_MAX_LRO_DESCRIPTORS;
++		lro_mgr->lro_arr = rxo->lro_desc;
++		lro_mgr->get_frag_header = be_get_frag_header;
++		lro_mgr->max_aggr = BE_MAX_FRAGS_PER_FRAME;
++	}
++
++#ifdef NETIF_F_GRO
++	netdev->features |= NETIF_F_GRO;
++	adapter->gro_supported = true;
++#endif
++}
++
++#define FW_FILE_HDR_SIGN	"ServerEngines Corp. "
+ char flash_cookie[2][16] =	{"*** SE FLAS",
+ 				"H DIRECTORY *** "};
+-static int be_flash_image(struct be_adapter *adapter,
++
++static bool be_flash_redboot(struct be_adapter *adapter,
++			const u8 *p, u32 img_start, int image_size,
++			int hdr_size)
++{
++	u32 crc_offset;
++	u8 flashed_crc[4];
++	int status;
++
++	crc_offset = hdr_size + img_start + image_size - 4;
++
++	p += crc_offset;
++
++	status = be_cmd_get_flash_crc(adapter, flashed_crc,
++			(image_size - 4));
++	if (status) {
++		dev_err(&adapter->pdev->dev,
++		"could not get crc from flash, not flashing redboot\n");
++		return false;
++	}
++
++	/*update redboot only if crc does not match*/
++	if (!memcmp(flashed_crc, p, 4))
++		return false;
++	else
++		return true;
++}
++
++static bool phy_flashing_required(struct be_adapter *adapter)
++{
++	int status = 0;
++	struct be_phy_info phy_info;
++
++	status = be_cmd_get_phy_info(adapter, &phy_info);
++	if (status)
++		return false;
++	if ((phy_info.phy_type == TN_8022) &&
++		(phy_info.interface_type == PHY_TYPE_BASET_10GB)) {
++		return true;
++	}
++	return false;
++}
++
++static int be_flash_data(struct be_adapter *adapter,
+ 			const struct firmware *fw,
+-			struct be_dma_mem *flash_cmd, u32 flash_type)
++			struct be_dma_mem *flash_cmd, int num_of_images)
++
+ {
+-	int status;
+-	u32 flash_op, image_offset = 0, total_bytes, image_size = 0;
++	int status = 0, i, filehdr_size = 0;
++	u32 total_bytes = 0, flash_op;
+ 	int num_bytes;
+ 	const u8 *p = fw->data;
+ 	struct be_cmd_write_flashrom *req = flash_cmd->va;
++	struct flash_comp *pflashcomp;
++	int num_comp;
+ 
+-	switch (flash_type) {
+-	case FLASHROM_TYPE_ISCSI_ACTIVE:
+-		image_offset = FLASH_iSCSI_PRIMARY_IMAGE_START;
+-		image_size = FLASH_IMAGE_MAX_SIZE;
+-		break;
+-	case FLASHROM_TYPE_ISCSI_BACKUP:
+-		image_offset = FLASH_iSCSI_BACKUP_IMAGE_START;
+-		image_size = FLASH_IMAGE_MAX_SIZE;
+-		break;
+-	case FLASHROM_TYPE_FCOE_FW_ACTIVE:
+-		image_offset = FLASH_FCoE_PRIMARY_IMAGE_START;
+-		image_size = FLASH_IMAGE_MAX_SIZE;
+-		break;
+-	case FLASHROM_TYPE_FCOE_FW_BACKUP:
+-		image_offset = FLASH_FCoE_BACKUP_IMAGE_START;
+-		image_size = FLASH_IMAGE_MAX_SIZE;
+-		break;
+-	case FLASHROM_TYPE_BIOS:
+-		image_offset = FLASH_iSCSI_BIOS_START;
+-		image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
+-		break;
+-	case FLASHROM_TYPE_FCOE_BIOS:
+-		image_offset = FLASH_FCoE_BIOS_START;
+-		image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
+-		break;
+-	case FLASHROM_TYPE_PXE_BIOS:
+-		image_offset = FLASH_PXE_BIOS_START;
+-		image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
+-		break;
+-	default:
+-		return 0;
++	struct flash_comp gen3_flash_types[10] = {
++		{ FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
++			FLASH_IMAGE_MAX_SIZE_g3},
++		{ FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
++			FLASH_REDBOOT_IMAGE_MAX_SIZE_g3},
++		{ FLASH_iSCSI_BIOS_START_g3, IMG_TYPE_BIOS,
++			FLASH_BIOS_IMAGE_MAX_SIZE_g3},
++		{ FLASH_PXE_BIOS_START_g3, IMG_TYPE_PXE_BIOS,
++			FLASH_BIOS_IMAGE_MAX_SIZE_g3},
++		{ FLASH_FCoE_BIOS_START_g3, IMG_TYPE_FCOE_BIOS,
++			FLASH_BIOS_IMAGE_MAX_SIZE_g3},
++		{ FLASH_iSCSI_BACKUP_IMAGE_START_g3, IMG_TYPE_ISCSI_BACKUP,
++			FLASH_IMAGE_MAX_SIZE_g3},
++		{ FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE,
++			FLASH_IMAGE_MAX_SIZE_g3},
++		{ FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
++			FLASH_IMAGE_MAX_SIZE_g3},
++		{ FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
++			FLASH_NCSI_IMAGE_MAX_SIZE_g3},
++		{ FLASH_PHY_FW_START_g3, IMG_TYPE_PHY_FW,
++			FLASH_PHY_FW_IMAGE_MAX_SIZE_g3}
++	};
++	struct flash_comp gen2_flash_types[8] = {
++		{ FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
++			FLASH_IMAGE_MAX_SIZE_g2},
++		{ FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT,
++			FLASH_REDBOOT_IMAGE_MAX_SIZE_g2},
++		{ FLASH_iSCSI_BIOS_START_g2, IMG_TYPE_BIOS,
++			FLASH_BIOS_IMAGE_MAX_SIZE_g2},
++		{ FLASH_PXE_BIOS_START_g2, IMG_TYPE_PXE_BIOS,
++			FLASH_BIOS_IMAGE_MAX_SIZE_g2},
++		{ FLASH_FCoE_BIOS_START_g2, IMG_TYPE_FCOE_BIOS,
++			FLASH_BIOS_IMAGE_MAX_SIZE_g2},
++		{ FLASH_iSCSI_BACKUP_IMAGE_START_g2, IMG_TYPE_ISCSI_BACKUP,
++			FLASH_IMAGE_MAX_SIZE_g2},
++		{ FLASH_FCoE_PRIMARY_IMAGE_START_g2, IMG_TYPE_FCOE_FW_ACTIVE,
++			FLASH_IMAGE_MAX_SIZE_g2},
++		{ FLASH_FCoE_BACKUP_IMAGE_START_g2, IMG_TYPE_FCOE_FW_BACKUP,
++			 FLASH_IMAGE_MAX_SIZE_g2}
++	};
++	if (adapter->generation == BE_GEN3) {
++		pflashcomp = gen3_flash_types;
++		filehdr_size = sizeof(struct flash_file_hdr_g3);
++		num_comp = ARRAY_SIZE(gen3_flash_types);
++	} else {
++		pflashcomp = gen2_flash_types;
++		filehdr_size = sizeof(struct flash_file_hdr_g2);
++		num_comp = ARRAY_SIZE(gen2_flash_types);
+ 	}
++	for (i = 0; i < num_comp; i++) {
++		if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
++				memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
++			continue;
++		if (pflashcomp[i].optype == IMG_TYPE_PHY_FW) {
++			if (!phy_flashing_required(adapter))
++				continue;
++		}
++		if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
++			(!be_flash_redboot(adapter, fw->data,
++			pflashcomp[i].offset, pflashcomp[i].size, filehdr_size +
++			(num_of_images * sizeof(struct image_hdr)))))
++			continue;
+ 
+-	p += sizeof(struct flash_file_hdr) + image_offset;
+-	if (p + image_size > fw->data + fw->size)
+-		return -1;
+-
+-	total_bytes = image_size;
+-
+-	while (total_bytes) {
+-		if (total_bytes > 32*1024)
+-			num_bytes = 32*1024;
+-		else
+-			num_bytes = total_bytes;
+-		total_bytes -= num_bytes;
+-
+-		if (!total_bytes)
+-			flash_op = FLASHROM_OPER_FLASH;
+-		else
+-			flash_op = FLASHROM_OPER_SAVE;
+-		memcpy(req->params.data_buf, p, num_bytes);
+-		p += num_bytes;
+-		status = be_cmd_write_flashrom(adapter, flash_cmd,
+-				flash_type, flash_op, num_bytes);
+-		if (status) {
+-			dev_err(&adapter->pdev->dev,
+-			"cmd to write to flash rom failed. type/op %d/%d\n",
+-			flash_type, flash_op);
++		p = fw->data;
++		p += filehdr_size + pflashcomp[i].offset
++			+ (num_of_images * sizeof(struct image_hdr));
++		if (p + pflashcomp[i].size > fw->data + fw->size)
+ 			return -1;
++		total_bytes = pflashcomp[i].size;
++		while (total_bytes) {
++			if (total_bytes > 32*1024)
++				num_bytes = 32*1024;
++			else
++				num_bytes = total_bytes;
++			total_bytes -= num_bytes;
++			if (!total_bytes) {
++				if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
++					flash_op = FLASHROM_OPER_PHY_FLASH;
++				else
++					flash_op = FLASHROM_OPER_FLASH;
++			} else {
++				if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
++					flash_op = FLASHROM_OPER_PHY_SAVE;
++				else
++					flash_op = FLASHROM_OPER_SAVE;
++			}
++			memcpy(req->params.data_buf, p, num_bytes);
++			p += num_bytes;
++			status = be_cmd_write_flashrom(adapter, flash_cmd,
++				pflashcomp[i].optype, flash_op, num_bytes);
++			if (status) {
++				if ((status == ILLEGAL_IOCTL_REQ) &&
++					(pflashcomp[i].optype ==
++						IMG_TYPE_PHY_FW))
++					break;
++				dev_err(&adapter->pdev->dev,
++					"cmd to write to flash rom failed.\n");
++				return -1;
++			}
++			yield();
+ 		}
+-		yield();
+ 	}
+-
+ 	return 0;
+ }
+ 
++static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr)
++{
++	if (fhdr == NULL)
++		return 0;
++	if (fhdr->build[0] == '3')
++		return BE_GEN3;
++	else if (fhdr->build[0] == '2')
++		return BE_GEN2;
++	else
++		return 0;
++}
++
+ int be_load_fw(struct be_adapter *adapter, u8 *func)
+ {
+ 	char fw_file[ETHTOOL_FLASH_MAX_FILENAME];
+ 	const struct firmware *fw;
+-	struct flash_file_hdr *fhdr;
+-	struct flash_section_info *fsec = NULL;
++	struct flash_file_hdr_g2 *fhdr;
++	struct flash_file_hdr_g3 *fhdr3;
++	struct image_hdr *img_hdr_ptr = NULL;
+ 	struct be_dma_mem flash_cmd;
+-	int status;
++	int status, i = 0, num_imgs = 0;
+ 	const u8 *p;
+-	bool entry_found = false;
+-	int flash_type;
+-	char fw_ver[FW_VER_LEN];
+-	char fw_cfg;
+ 
+-	status = be_cmd_get_fw_ver(adapter, fw_ver);
+-	if (status)
+-		return status;
++	if (!netif_running(adapter->netdev)) {
++		dev_err(&adapter->pdev->dev,
++			"Firmware load not allowed (interface is down)\n");
++		return -1;
++	}
+ 
+-	fw_cfg = *(fw_ver + 2);
+-	if (fw_cfg == '0')
+-		fw_cfg = '1';
+ 	strcpy(fw_file, func);
+ 
+ 	status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
+@@ -1826,34 +3202,9 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
+ 		goto fw_exit;
+ 
+ 	p = fw->data;
+-	fhdr = (struct flash_file_hdr *) p;
+-	if (memcmp(fhdr->sign, FW_FILE_HDR_SIGN, strlen(FW_FILE_HDR_SIGN))) {
+-		dev_err(&adapter->pdev->dev,
+-			"Firmware(%s) load error (signature did not match)\n",
+-				fw_file);
+-		status = -1;
+-		goto fw_exit;
+-	}
+-
++	fhdr = (struct flash_file_hdr_g2 *) p;
+ 	dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
+ 
+-	p += sizeof(struct flash_file_hdr);
+-	while (p < (fw->data + fw->size)) {
+-		fsec = (struct flash_section_info *)p;
+-		if (!memcmp(flash_cookie, fsec->cookie, sizeof(flash_cookie))) {
+-			entry_found = true;
+-			break;
+-		}
+-		p += 32;
+-	}
+-
+-	if (!entry_found) {
+-		status = -1;
+-		dev_err(&adapter->pdev->dev,
+-			"Flash cookie not found in firmware image\n");
+-		goto fw_exit;
+-	}
+-
+ 	flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024;
+ 	flash_cmd.va = pci_alloc_consistent(adapter->pdev, flash_cmd.size,
+ 					&flash_cmd.dma);
+@@ -1864,12 +3215,25 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
+ 		goto fw_exit;
+ 	}
+ 
+-	for (flash_type = FLASHROM_TYPE_ISCSI_ACTIVE;
+-		flash_type <= FLASHROM_TYPE_FCOE_FW_BACKUP; flash_type++) {
+-		status = be_flash_image(adapter, fw, &flash_cmd,
+-				flash_type);
+-		if (status)
+-			break;
++	if ((adapter->generation == BE_GEN3) &&
++			(get_ufigen_type(fhdr) == BE_GEN3)) {
++		fhdr3 = (struct flash_file_hdr_g3 *) fw->data;
++		num_imgs = le32_to_cpu(fhdr3->num_imgs);
++		for (i = 0; i < num_imgs; i++) {
++			img_hdr_ptr = (struct image_hdr *) (fw->data +
++					(sizeof(struct flash_file_hdr_g3) +
++					 i * sizeof(struct image_hdr)));
++			if (le32_to_cpu(img_hdr_ptr->imageid) == 1)
++				status = be_flash_data(adapter, fw, &flash_cmd,
++							num_imgs);
++		}
++	} else if ((adapter->generation == BE_GEN2) &&
++			(get_ufigen_type(fhdr) == BE_GEN2)) {
++		status = be_flash_data(adapter, fw, &flash_cmd, 0);
++	} else {
++		dev_err(&adapter->pdev->dev,
++			"UFI and Interface are not compatible for flashing\n");
++		status = -1;
+ 	}
+ 
+ 	pci_free_consistent(adapter->pdev, flash_cmd.size, flash_cmd.va,
+@@ -1879,14 +3243,14 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
+ 		goto fw_exit;
+ 	}
+ 
+-	dev_info(&adapter->pdev->dev, "Firmware flashed succesfully\n");
++	dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
+ 
+ fw_exit:
+ 	release_firmware(fw);
+ 	return status;
+ }
+ 
+-static struct net_device_ops be_netdev_ops = {
++static net_device_ops_no_const be_netdev_ops = {
+ 	.ndo_open		= be_open,
+ 	.ndo_stop		= be_close,
+ 	.ndo_start_xmit		= be_xmit,
+@@ -1898,15 +3262,32 @@ static struct net_device_ops be_netdev_ops = {
+ 	.ndo_vlan_rx_register	= be_vlan_register,
+ 	.ndo_vlan_rx_add_vid	= be_vlan_add_vid,
+ 	.ndo_vlan_rx_kill_vid	= be_vlan_rem_vid,
++#ifdef HAVE_SRIOV_CONFIG
++	.ndo_set_vf_mac		= be_set_vf_mac,
++	.ndo_set_vf_vlan	= be_set_vf_vlan,
++	.ndo_set_vf_tx_rate	= be_set_vf_tx_rate,
++	.ndo_get_vf_config	= be_get_vf_config,
++#endif
++	.ndo_do_ioctl		= be_do_ioctl,
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	.ndo_poll_controller	= be_netpoll,
++#endif
+ };
+ 
+-static void be_netdev_init(struct net_device *netdev)
++static int be_netdev_init(struct net_device *netdev)
+ {
+ 	struct be_adapter *adapter = netdev_priv(netdev);
++	struct be_rx_obj *rxo;
++	int i, status = 0;
+ 
+ 	netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
+-		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM |
+-		NETIF_F_GRO;
++		NETIF_F_HW_VLAN_TX | NETIF_F_HW_CSUM | NETIF_F_TSO6;
++
++	netdev->vlan_features |=  NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
++						NETIF_F_HW_CSUM;
++
++	netdev->features |= NETIF_F_VLAN_SG | NETIF_F_VLAN_TSO |
++						NETIF_F_VLAN_CSUM;
+ 
+ 	netdev->flags |= IFF_MULTICAST;
+ 
+@@ -1918,17 +3299,30 @@ static void be_netdev_init(struct net_device *netdev)
+ 
+ 	netif_set_gso_max_size(netdev, 65535);
+ 
++	if (adapter->flags & BE_FLAGS_DCBX)
++		be_netdev_ops.ndo_select_queue = be_select_queue;	
+ 	BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
+-
++		
+ 	SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
+ 
+-	netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx,
+-		BE_NAPI_WEIGHT);
+-	netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc,
++	be_lro_init(adapter, netdev);
++
++	for_all_rx_queues(adapter, rxo, i) {
++		status = be_netif_napi_add(netdev, &rxo->rx_eq.napi, be_poll_rx,
++			BE_NAPI_WEIGHT);
++		if (status) {
++			dev_err(&adapter->pdev->dev, "dummy netdev alloc fail"
++				"for rxo:%d\n", i);
++			return status;
++		}
++	}
++	status = be_netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc,
+ 		BE_NAPI_WEIGHT);
++	if (status)
++		dev_err(&adapter->pdev->dev, "dummy netdev alloc fail"
++				"for tx\n");
+ 
+-	netif_carrier_off(netdev);
+-	netif_stop_queue(netdev);
++	return status;
+ }
+ 
+ static void be_unmap_pci_bars(struct be_adapter *adapter)
+@@ -1937,37 +3331,62 @@ static void be_unmap_pci_bars(struct be_adapter *adapter)
+ 		iounmap(adapter->csr);
+ 	if (adapter->db)
+ 		iounmap(adapter->db);
+-	if (adapter->pcicfg)
++	if (adapter->pcicfg && be_physfn(adapter))
+ 		iounmap(adapter->pcicfg);
+ }
+ 
+ static int be_map_pci_bars(struct be_adapter *adapter)
+ {
++	struct pci_dev *pdev = adapter->pdev;
+ 	u8 __iomem *addr;
+-	int pcicfg_reg;
++	int pcicfg_reg, db_reg;
+ 
+-	addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2),
+-			pci_resource_len(adapter->pdev, 2));
+-	if (addr == NULL)
+-		return -ENOMEM;
+-	adapter->csr = addr;
++	if (lancer_chip(adapter)) {
++		addr = ioremap_nocache(pci_resource_start(pdev, 0),
++			pci_resource_len(adapter->pdev, 0));
++		if (addr == NULL)
++			return -ENOMEM;
++		adapter->db = addr;
++		return 0;
++	}
+ 
+-	addr = ioremap_nocache(pci_resource_start(adapter->pdev, 4),
+-			128 * 1024);
+-	if (addr == NULL)
+-		goto pci_map_err;
+-	adapter->db = addr;
++	if (be_physfn(adapter)) {
++		addr = ioremap_nocache(pci_resource_start(pdev, 2),
++				pci_resource_len(pdev, 2));
++		if (addr == NULL)
++			return -ENOMEM;
++		adapter->csr = addr;
++		adapter->netdev->mem_start = pci_resource_start(pdev, 2);
++		adapter->netdev->mem_end = pci_resource_start(pdev, 2) +
++					pci_resource_len(pdev, 2);
++	}
+ 
+-	if (adapter->generation == BE_GEN2)
++	if (adapter->generation == BE_GEN2) {
+ 		pcicfg_reg = 1;
+-	else
++		db_reg = 4;
++	} else {
+ 		pcicfg_reg = 0;
++		if (be_physfn(adapter))
++			db_reg = 4;
++		else
++			db_reg = 0;
++	}
+ 
+-	addr = ioremap_nocache(pci_resource_start(adapter->pdev, pcicfg_reg),
+-			pci_resource_len(adapter->pdev, pcicfg_reg));
++	addr = ioremap_nocache(pci_resource_start(pdev, db_reg),
++				pci_resource_len(pdev, db_reg));
+ 	if (addr == NULL)
+ 		goto pci_map_err;
+-	adapter->pcicfg = addr;
++	adapter->db = addr;
++
++	if (be_physfn(adapter)) {
++		addr = ioremap_nocache(
++				pci_resource_start(pdev, pcicfg_reg),
++				pci_resource_len(pdev, pcicfg_reg));
++		if (addr == NULL)
++			goto pci_map_err;
++		adapter->pcicfg = addr;
++	} else
++		adapter->pcicfg = adapter->db + SRIOV_VF_PCICFG_OFFSET;
+ 
+ 	return 0;
+ pci_map_err:
+@@ -1985,40 +3404,69 @@ static void be_ctrl_cleanup(struct be_adapter *adapter)
+ 	if (mem->va)
+ 		pci_free_consistent(adapter->pdev, mem->size,
+ 			mem->va, mem->dma);
++
++	mem = &adapter->rx_filter;
++	if (mem->va)
++		pci_free_consistent(adapter->pdev, mem->size,
++			mem->va, mem->dma);
+ }
+ 
+ static int be_ctrl_init(struct be_adapter *adapter)
+ {
+ 	struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced;
+ 	struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem;
++	struct be_dma_mem *rx_filter = &adapter->rx_filter;
+ 	int status;
+ 
+ 	status = be_map_pci_bars(adapter);
+ 	if (status)
+-		return status;
++		goto done;
+ 
+ 	mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16;
+ 	mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev,
+ 				mbox_mem_alloc->size, &mbox_mem_alloc->dma);
+ 	if (!mbox_mem_alloc->va) {
+-		be_unmap_pci_bars(adapter);
+-		return -1;
++		status = -ENOMEM;
++		goto unmap_pci_bars;
+ 	}
++
+ 	mbox_mem_align->size = sizeof(struct be_mcc_mailbox);
+ 	mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
+ 	mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
+ 	memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
+-	spin_lock_init(&adapter->mbox_lock);
++
++	rx_filter->size = sizeof(struct be_cmd_req_rx_filter);
++	rx_filter->va = pci_alloc_consistent(adapter->pdev, rx_filter->size,
++			&rx_filter->dma);
++	if (rx_filter->va == NULL) {
++		status = -ENOMEM;
++		goto free_mbox;
++	}
++	memset(rx_filter->va, 0, rx_filter->size);
++
++	mutex_init(&adapter->mbox_lock);
+ 	spin_lock_init(&adapter->mcc_lock);
+ 	spin_lock_init(&adapter->mcc_cq_lock);
+ 
++	init_completion(&adapter->flash_compl);
++
++	PCI_SAVE_STATE(adapter->pdev);
+ 	return 0;
++
++free_mbox:
++	pci_free_consistent(adapter->pdev, mbox_mem_alloc->size,
++		mbox_mem_alloc->va, mbox_mem_alloc->dma);
++
++unmap_pci_bars:
++	be_unmap_pci_bars(adapter);
++
++done:
++	return status;
+ }
+ 
+ static void be_stats_cleanup(struct be_adapter *adapter)
+ {
+-	struct be_stats_obj *stats = &adapter->stats;
+-	struct be_dma_mem *cmd = &stats->cmd;
++	struct be_dma_mem *cmd = &adapter->stats_cmd;
+ 
+ 	if (cmd->va)
+ 		pci_free_consistent(adapter->pdev, cmd->size,
+@@ -2027,10 +3475,12 @@ static void be_stats_cleanup(struct be_adapter *adapter)
+ 
+ static int be_stats_init(struct be_adapter *adapter)
+ {
+-	struct be_stats_obj *stats = &adapter->stats;
+-	struct be_dma_mem *cmd = &stats->cmd;
++	struct be_dma_mem *cmd = &adapter->stats_cmd;
+ 
+-	cmd->size = sizeof(struct be_cmd_req_get_stats);
++	if (adapter->generation == BE_GEN2)
++		cmd->size = sizeof(struct be_cmd_req_get_stats_v0);
++	else
++		cmd->size = sizeof(struct be_cmd_req_get_stats_v1);
+ 	cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma);
+ 	if (cmd->va == NULL)
+ 		return -1;
+@@ -2041,9 +3491,17 @@ static int be_stats_init(struct be_adapter *adapter)
+ static void __devexit be_remove(struct pci_dev *pdev)
+ {
+ 	struct be_adapter *adapter = pci_get_drvdata(pdev);
++
+ 	if (!adapter)
+ 		return;
+ 
++	cancel_delayed_work_sync(&adapter->work);
++
++#ifdef CONFIG_PALAU
++	be_sysfs_remove_group(adapter);
++#endif
++
++	/* be_close() gets called if the device is open by unregister */
+ 	unregister_netdev(adapter->netdev);
+ 
+ 	be_clear(adapter);
+@@ -2052,36 +3510,203 @@ static void __devexit be_remove(struct pci_dev *pdev)
+ 
+ 	be_ctrl_cleanup(adapter);
+ 
+-	if (adapter->msix_enabled) {
+-		pci_disable_msix(adapter->pdev);
+-		adapter->msix_enabled = false;
+-	}
++	kfree(adapter->vf_cfg);
++	be_sriov_disable(adapter);
++
++	be_msix_disable(adapter);
+ 
+ 	pci_set_drvdata(pdev, NULL);
+ 	pci_release_regions(pdev);
+ 	pci_disable_device(pdev);
+-
++	be_netif_napi_del(adapter->netdev);
+ 	free_netdev(adapter->netdev);
+ }
+ 
+-static int be_hw_up(struct be_adapter *adapter)
++static void be_pcie_slot_check(struct be_adapter *adapter)
++{
++	u32 curr, max, width, max_wd, speed, max_sp;
++
++	pci_read_config_dword(adapter->pdev, PCICFG_PCIE_LINK_STATUS_OFFSET,
++		&curr);
++	width = (curr >> PCIE_LINK_STATUS_NEG_WIDTH_SHIFT) &
++			PCIE_LINK_STATUS_NEG_WIDTH_MASK;
++	speed = (curr >> PCIE_LINK_STATUS_SPEED_SHIFT) &
++			PCIE_LINK_STATUS_SPEED_MASK;
++
++	pci_read_config_dword(adapter->pdev, PCICFG_PCIE_LINK_CAP_OFFSET,
++		&max);
++	max_wd = (max >> PCIE_LINK_CAP_MAX_WIDTH_SHIFT) &
++			PCIE_LINK_CAP_MAX_WIDTH_MASK;
++	max_sp = (max >> PCIE_LINK_CAP_MAX_SPEED_SHIFT) &
++			PCIE_LINK_CAP_MAX_SPEED_MASK;
++
++	if (width < max_wd || speed < max_sp)
++		dev_warn(&adapter->pdev->dev,
++			"Found network device in a Gen%s x%d PCIe slot. It "
++			"should be in a Gen2 x%d slot for best performance\n",
++			speed < max_sp ? "1" : "2", width, max_wd);
++}
++
++static int be_get_ioctl_version(char *fw_version) {
++	char *str[4];
++	int i;
++	int val[4];
++	char *endptr;
++
++	if(!fw_version)
++		return 0;
++	for(i=0; i<3; i++) {
++		str[i] = strsep(&fw_version, ".");
++		val[i] = simple_strtol(str[i], &endptr, 10);
++	}
++
++	if (val[0]>4 || (val[0]>3 && val[2]>143))
++		return 1;
++	return 0;
++}
++
++static int be_get_port_names(struct be_adapter *adapter)
+ {
+ 	int status;
++	int ver;
+ 
+-	status = be_cmd_POST(adapter);
++	status = be_cmd_get_fw_ver(adapter,
++			  adapter->fw_ver, NULL);
+ 	if (status)
+ 		return status;
++	ver = be_get_ioctl_version(adapter->fw_ver);
++	if (ver && (adapter->generation == BE_GEN3))
++	status = be_cmd_query_port_names_v1(adapter,
++				adapter->port_name);
++	else
++	status = be_cmd_query_port_names_v0(adapter,
++				adapter->port_name);
++	return status;
++}
+ 
+-	status = be_cmd_reset_function(adapter);
++static int be_get_config(struct be_adapter *adapter)
++{
++	int status;
++	u8 mac[ETH_ALEN];
++
++	status = be_cmd_query_fw_cfg(adapter, &adapter->port_num,
++				&adapter->function_mode,
++				&adapter->function_caps);
+ 	if (status)
+ 		return status;
+ 
+-	status = be_cmd_get_fw_ver(adapter, adapter->fw_ver);
++	status = be_cmd_get_cntl_attributes(adapter);
+ 	if (status)
+ 		return status;
+ 
+-	status = be_cmd_query_fw_cfg(adapter,
+-				&adapter->port_num, &adapter->cap);
++	memset(mac, 0, ETH_ALEN);
++	be_pcie_slot_check(adapter);
++
++	if (be_physfn(adapter)) {
++		status = be_cmd_mac_addr_query(adapter, mac,
++			MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0);
++
++		if (status)
++			return status;
++
++		if (!is_valid_ether_addr(mac))
++			return -EADDRNOTAVAIL;
++
++		memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
++		memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
++	}
++
++	if (adapter->function_mode & FLEX10_MODE)
++		adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/8;
++	else
++		adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
++
++	return 0;
++}
++
++static int be_dev_family_check(struct be_adapter *adapter)
++{
++	struct pci_dev *pdev = adapter->pdev;
++	u32 sli_intf = 0, if_type;
++
++	switch (pdev->device) {
++	case BE_DEVICE_ID1:
++	case OC_DEVICE_ID1:
++		adapter->generation = BE_GEN2;
++		break;
++	case BE_DEVICE_ID2:
++	case OC_DEVICE_ID2:
++		adapter->generation = BE_GEN3;
++		break;
++	case OC_DEVICE_ID3:
++		pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf);
++		if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
++						SLI_INTF_IF_TYPE_SHIFT;
++
++		if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) ||
++			if_type != 0x02) {
++			dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n");
++			return -EINVAL;
++		}
++		if (num_vfs > 0) {
++			dev_err(&pdev->dev, "VFs not supported\n");
++			return -EINVAL;
++		}
++		adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >>
++					 SLI_INTF_FAMILY_SHIFT);
++		adapter->generation = BE_GEN3;
++		break;
++	default:
++		adapter->generation = 0;
++	}
++	return 0;
++}
++
++static int lancer_wait_ready(struct be_adapter *adapter)
++{
++#define SLIPORT_READY_TIMEOUT 500
++	u32 sliport_status;
++	int status = 0, i;
++
++	for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) {
++		sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
++		if (sliport_status & SLIPORT_STATUS_RDY_MASK)
++			break;
++
++		msleep(20);
++	}
++
++	if (i == SLIPORT_READY_TIMEOUT)
++		status = -1;
++
++	return status;
++}
++
++static int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
++{
++	int status;
++	u32 sliport_status, err, reset_needed;
++	status = lancer_wait_ready(adapter);
++	if (!status) {
++		sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
++		err = sliport_status & SLIPORT_STATUS_ERR_MASK;
++		reset_needed = sliport_status & SLIPORT_STATUS_RN_MASK;
++		if (err && reset_needed) {
++			iowrite32(SLI_PORT_CONTROL_IP_MASK,
++					adapter->db + SLIPORT_CONTROL_OFFSET);
++
++			/* check adapter has corrected the error */
++			status = lancer_wait_ready(adapter);
++			sliport_status = ioread32(adapter->db +
++							SLIPORT_STATUS_OFFSET);
++			sliport_status &= (SLIPORT_STATUS_ERR_MASK |
++						SLIPORT_STATUS_RN_MASK);
++			if (status || sliport_status)
++				status = -1;
++		} else if (err || reset_needed) {
++			status = -1;
++		}
++	}
+ 	return status;
+ }
+ 
+@@ -2091,7 +3716,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ 	int status = 0;
+ 	struct be_adapter *adapter;
+ 	struct net_device *netdev;
+-	u8 mac[ETH_ALEN];
++	u32 en;
+ 
+ 	status = pci_enable_device(pdev);
+ 	if (status)
+@@ -2102,31 +3727,22 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ 		goto disable_dev;
+ 	pci_set_master(pdev);
+ 
+-	netdev = alloc_etherdev(sizeof(struct be_adapter));
++	netdev = alloc_etherdev_mq(sizeof(struct be_adapter), MAX_TX_QS);
+ 	if (netdev == NULL) {
+ 		status = -ENOMEM;
+ 		goto rel_reg;
+ 	}
+ 	adapter = netdev_priv(netdev);
+ 
+-	switch (pdev->device) {
+-	case BE_DEVICE_ID1:
+-	case OC_DEVICE_ID1:
+-		adapter->generation = BE_GEN2;
+-		break;
+-	case BE_DEVICE_ID2:
+-	case OC_DEVICE_ID2:
+-		adapter->generation = BE_GEN3;
+-		break;
+-	default:
+-		adapter->generation = 0;
+-	}
+-
+ 	adapter->pdev = pdev;
++
++	status = be_dev_family_check(adapter);
++	if (status)
++		goto free_netdev;
++
+ 	pci_set_drvdata(pdev, adapter);
+ 	adapter->netdev = netdev;
+-
+-	be_msix_enable(adapter);
++	SET_NETDEV_DEV(netdev, &pdev->dev);
+ 
+ 	status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+ 	if (!status) {
+@@ -2139,46 +3755,150 @@ static int __devinit be_probe(struct pci_dev *pdev,
+ 		}
+ 	}
+ 
++	be_sriov_enable(adapter);
++	if (adapter->num_vfs > 0) {
++		adapter->vf_cfg = kcalloc(adapter->num_vfs,
++					sizeof(struct be_vf_cfg), GFP_KERNEL);
++
++		if (!adapter->vf_cfg)
++			goto free_netdev;
++	}
++
+ 	status = be_ctrl_init(adapter);
+ 	if (status)
+-		goto free_netdev;
++		goto free_vf_cfg;
++
++	if (lancer_chip(adapter)) {
++		status = lancer_test_and_set_rdy_state(adapter);
++		if (status) {
++			dev_err(&pdev->dev, "Adapter in non recoverable error\n");
++			goto ctrl_clean;
++		}
++	}
++
++	/* sync up with fw's ready state */
++	if (be_physfn(adapter)) {
++		status = be_cmd_POST(adapter);
++		if (status)
++			goto ctrl_clean;
++	}
++
++	/* tell fw we're ready to fire cmds */
++	status = be_cmd_fw_init(adapter);
++	if (status)
++		goto ctrl_clean;
++
++	status = be_cmd_reset_function(adapter);
++	if (status)
++		goto ctrl_clean;
+ 
+ 	status = be_stats_init(adapter);
+ 	if (status)
+ 		goto ctrl_clean;
+ 
+-	status = be_hw_up(adapter);
++	status = be_get_config(adapter);
+ 	if (status)
+ 		goto stats_clean;
+ 
+-	status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK,
+-			true /* permanent */, 0);
+-	if (status)
+-		goto stats_clean;
+-	memcpy(netdev->dev_addr, mac, ETH_ALEN);
++	/* This bit is zero in normal boot case, but in crash kernel case this
++	   is not cleared. clear this bit here, until we are ready with the irqs
++	   i.e in be_open call.*/
++	if (!lancer_chip(adapter))
++		be_intr_set(adapter, false);
++
++	if (msix)
++		be_msix_enable(adapter);
+ 
+ 	INIT_DELAYED_WORK(&adapter->work, be_worker);
+-	be_netdev_init(netdev);
+-	SET_NETDEV_DEV(netdev, &adapter->pdev->dev);
+ 
+ 	status = be_setup(adapter);
+ 	if (status)
+-		goto stats_clean;
++		goto msix_disable;
++
++	/* Initilize the link status to -1 */
++	adapter->link_status = -1;
++
++	status = be_netdev_init(netdev);
++	if (status)
++		goto unsetup;
++
+ 	status = register_netdev(netdev);
+ 	if (status != 0)
+ 		goto unsetup;
+ 
+-	dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
++	be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
++
++	if (be_physfn(adapter) && adapter->num_vfs) {
++		u8 mac_speed;
++		int link_status;
++		u16 def_vlan, vf, lnk_speed;
++
++		status = be_vf_eth_addr_config(adapter);
++		if (status)
++			goto unreg_netdev;
++
++		for (vf = 0; vf < adapter->num_vfs; vf++) {
++			status = be_cmd_get_hsw_config(adapter, &def_vlan,
++				vf + 1, adapter->vf_cfg[vf].vf_if_handle);
++			if (!status)
++				adapter->vf_cfg[vf].vf_def_vid = def_vlan;
++			else
++				goto unreg_netdev;
++
++			status = be_cmd_link_status_query(adapter, &link_status,
++					&mac_speed, &lnk_speed, vf + 1);
++			if (!status)
++				adapter->vf_cfg[vf].vf_tx_rate = lnk_speed * 10;
++			else
++				goto unreg_netdev;
++		}
++	}
++	if (be_physfn(adapter)) {
++		/* Temp fix ofr bug# 23034. Till ARM
++		 * f/w fixes privilege lvl */
++		be_get_port_names(adapter);
++	}
++
++	/* Enable Vlan capability based on privileges.
++	 * PF will have Vlan capability anyway. */
++	be_cmd_get_fn_privileges(adapter, &en, 0);
++
++	if ((en & (BE_PRIV_FILTMGMT | BE_PRIV_VHADM | BE_PRIV_DEVCFG)) ||
++		be_physfn(adapter))
++		netdev->features |= NETIF_F_HW_VLAN_FILTER;
++	else
++		netdev->features |= NETIF_F_VLAN_CHALLENGED;
++
++	dev_info(&pdev->dev, "%s: numa node %d\n", netdev->name,
++						dev_to_node(&pdev->dev));
++	dev_info(&pdev->dev, "%s %s \"%s\" port %d\n", nic_name(pdev),
++			(adapter->port_num > 1 ? "1Gbps NIC" : "10Gbps NIC"),
++			adapter->model_number, adapter->hba_port_num);
++
++
++#ifdef CONFIG_PALAU
++	be_sysfs_create_group(adapter);
++#endif
++	schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
+ 	return 0;
+ 
++unreg_netdev:
++	unregister_netdev(netdev);
+ unsetup:
+ 	be_clear(adapter);
++msix_disable:
++	be_msix_disable(adapter);
+ stats_clean:
+ 	be_stats_cleanup(adapter);
+ ctrl_clean:
+ 	be_ctrl_cleanup(adapter);
++free_vf_cfg:
++	kfree(adapter->vf_cfg);
+ free_netdev:
+-	free_netdev(adapter->netdev);
++	be_sriov_disable(adapter);
++	be_netif_napi_del(netdev);
++	free_netdev(netdev);
++	pci_set_drvdata(pdev, NULL);
+ rel_reg:
+ 	pci_release_regions(pdev);
+ disable_dev:
+@@ -2193,6 +3913,10 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
+ 	struct be_adapter *adapter = pci_get_drvdata(pdev);
+ 	struct net_device *netdev =  adapter->netdev;
+ 
++	cancel_delayed_work_sync(&adapter->work);
++	if (adapter->wol)
++		be_setup_wol(adapter, true);
++
+ 	netif_device_detach(netdev);
+ 	if (netif_running(netdev)) {
+ 		rtnl_lock();
+@@ -2202,6 +3926,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
+ 	be_cmd_get_flow_control(adapter, &adapter->tx_fc, &adapter->rx_fc);
+ 	be_clear(adapter);
+ 
++	be_msix_disable(adapter);
+ 	pci_save_state(pdev);
+ 	pci_disable_device(pdev);
+ 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+@@ -2223,6 +3948,12 @@ static int be_resume(struct pci_dev *pdev)
+ 	pci_set_power_state(pdev, 0);
+ 	pci_restore_state(pdev);
+ 
++	be_msix_enable(adapter);
++	/* tell fw we're ready to fire cmds */
++	status = be_cmd_fw_init(adapter);
++	if (status)
++		return status;
++
+ 	be_setup(adapter);
+ 	if (netif_running(netdev)) {
+ 		rtnl_lock();
+@@ -2230,28 +3961,152 @@ static int be_resume(struct pci_dev *pdev)
+ 		rtnl_unlock();
+ 	}
+ 	netif_device_attach(netdev);
++
++	if (adapter->wol)
++		be_setup_wol(adapter, false);
++
++	schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
+ 	return 0;
+ }
+ 
++/*
++ * An FLR will stop BE from DMAing any data.
++ */
++static void be_shutdown(struct pci_dev *pdev)
++{
++	struct be_adapter *adapter = pci_get_drvdata(pdev);
++
++	if (!adapter)
++		return;
++
++	cancel_delayed_work_sync(&adapter->work);
++
++	netif_device_detach(adapter->netdev);
++
++	if (adapter->wol)
++		be_setup_wol(adapter, true);
++
++	be_cmd_reset_function(adapter);
++
++	pci_disable_device(pdev);
++}
++
++static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev,
++				pci_channel_state_t state)
++{
++	struct be_adapter *adapter = pci_get_drvdata(pdev);
++	struct net_device *netdev =  adapter->netdev;
++
++	dev_err(&adapter->pdev->dev, "EEH error detected\n");
++
++	adapter->eeh_err = true;
++
++	netif_device_detach(netdev);
++
++	if (netif_running(netdev)) {
++		rtnl_lock();
++		be_close(netdev);
++		rtnl_unlock();
++	}
++	be_clear(adapter);
++
++	if (state == pci_channel_io_perm_failure)
++		return PCI_ERS_RESULT_DISCONNECT;
++
++	pci_disable_device(pdev);
++
++	return PCI_ERS_RESULT_NEED_RESET;
++}
++
++static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
++{
++	struct be_adapter *adapter = pci_get_drvdata(pdev);
++	int status;
++
++	dev_info(&adapter->pdev->dev, "EEH reset\n");
++	adapter->eeh_err = false;
++
++	status = pci_enable_device(pdev);
++	if (status)
++		return PCI_ERS_RESULT_DISCONNECT;
++
++	pci_set_master(pdev);
++	pci_set_power_state(pdev, 0);
++	pci_restore_state(pdev);
++
++	/* Check if card is ok and fw is ready */
++	status = be_cmd_POST(adapter);
++	if (status)
++		return PCI_ERS_RESULT_DISCONNECT;
++
++	return PCI_ERS_RESULT_RECOVERED;
++}
++
++static void be_eeh_resume(struct pci_dev *pdev)
++{
++	int status = 0;
++	struct be_adapter *adapter = pci_get_drvdata(pdev);
++	struct net_device *netdev =  adapter->netdev;
++
++	dev_info(&adapter->pdev->dev, "EEH resume\n");
++
++	pci_save_state(pdev);
++
++	/* tell fw we're ready to fire cmds */
++	status = be_cmd_fw_init(adapter);
++	if (status)
++		goto err;
++
++	status = be_setup(adapter);
++	if (status)
++		goto err;
++
++	if (netif_running(netdev)) {
++		status = be_open(netdev);
++		if (status)
++			goto err;
++	}
++	netif_device_attach(netdev);
++	return;
++err:
++	dev_err(&adapter->pdev->dev, "EEH resume failed\n");
++	return;
++}
++
++static struct pci_error_handlers be_eeh_handlers = {
++	.error_detected = be_eeh_err_detected,
++	.slot_reset = be_eeh_reset,
++	.resume = be_eeh_resume,
++};
++
+ static struct pci_driver be_driver = {
+ 	.name = DRV_NAME,
+ 	.id_table = be_dev_ids,
+ 	.probe = be_probe,
+ 	.remove = be_remove,
+ 	.suspend = be_suspend,
+-	.resume = be_resume
++	.resume = be_resume,
++	.shutdown = be_shutdown,
++	.err_handler = &be_eeh_handlers
+ };
+ 
+ static int __init be_init_module(void)
+ {
+-	if (rx_frag_size != 8192 && rx_frag_size != 4096
+-		&& rx_frag_size != 2048) {
++	if (rx_frag_size != 8192 && rx_frag_size != 4096 &&
++	    rx_frag_size != 2048) {
+ 		printk(KERN_WARNING DRV_NAME
+ 			" : Module param rx_frag_size must be 2048/4096/8192."
+ 			" Using 2048\n");
+ 		rx_frag_size = 2048;
+ 	}
+ 
++	if (!msix && num_vfs > 0) {
++		printk(KERN_WARNING DRV_NAME
++			" : MSIx required for num_vfs > 0. Ignoring msix=0\n");
++		msix = 1;
++	}
++
++
+ 	return pci_register_driver(&be_driver);
+ }
+ module_init(be_init_module);
+diff --git a/drivers/net/benet/be_misc.c b/drivers/net/benet/be_misc.c
+new file mode 100644
+index 0000000..4ab499f
+--- /dev/null
++++ b/drivers/net/benet/be_misc.c
+@@ -0,0 +1,106 @@
++/*
++ * Copyright (C) 2005 - 2011 Emulex
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation. The full GNU General
++ * Public License is included in this distribution in the file called COPYING.
++ *
++ * Contact Information:
++ * linux-drivers@emulex.com
++ *
++ * Emulex
++ * 3333 Susan Street
++ * Costa Mesa, CA 92626
++ */
++#include "be.h"
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
++static ssize_t
++flash_fw_store(struct class_device *cd, const char *buf, size_t len)
++{
++	struct be_adapter *adapter =
++		netdev_priv(container_of(cd, struct net_device, class_dev));
++	char file_name[ETHTOOL_FLASH_MAX_FILENAME];
++	int status;
++
++	if (!capable(CAP_NET_ADMIN))
++		return -EPERM;
++
++	file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
++	strncpy(file_name, buf, (ETHTOOL_FLASH_MAX_FILENAME - 1));
++
++	/* Removing new-line char given by sysfs */
++	file_name[strlen(file_name) - 1] = '\0';
++
++	status = be_load_fw(adapter, file_name);
++	if (!status)
++		return len;
++	else
++		return status;
++}
++
++static CLASS_DEVICE_ATTR(flash_fw, S_IWUSR, NULL, flash_fw_store);
++
++static struct attribute *benet_attrs[] = {
++	&class_device_attr_flash_fw.attr,
++	NULL,
++};
++#else
++
++static ssize_t
++flash_fw_store(struct device *dev, struct device_attribute *attr,
++		const char *buf, size_t len)
++{
++	struct be_adapter *adapter =
++		netdev_priv(container_of(dev, struct net_device, dev));
++	char file_name[ETHTOOL_FLASH_MAX_FILENAME];
++	int status;
++
++	if (!capable(CAP_NET_ADMIN))
++		return -EPERM;
++
++	file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
++	strncpy(file_name, buf, (ETHTOOL_FLASH_MAX_FILENAME - 1));
++
++	/* Removing new-line char given by sysfs */
++	file_name[strlen(file_name) - 1] = '\0';
++
++	status = be_load_fw(adapter, file_name);
++	if (!status)
++		return len;
++	else
++		return status;
++}
++
++static DEVICE_ATTR(flash_fw, S_IWUSR, NULL, flash_fw_store);
++
++static struct attribute *benet_attrs[] = {
++	&dev_attr_flash_fw.attr,
++	NULL,
++};
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
++#define CLASS_DEV		class_dev
++#else
++#define CLASS_DEV		dev
++#endif
++
++static struct attribute_group benet_attr_group = {.attrs = benet_attrs };
++
++void be_sysfs_create_group(struct be_adapter *adapter)
++{
++	int status;
++
++	status = sysfs_create_group(&adapter->netdev->CLASS_DEV.kobj,
++			&benet_attr_group);
++	if (status)
++		dev_err(&adapter->pdev->dev, "Could not create sysfs group\n");
++}
++
++void be_sysfs_remove_group(struct be_adapter *adapter)
++{
++	sysfs_remove_group(&adapter->netdev->CLASS_DEV.kobj, &benet_attr_group);
++}
+diff --git a/drivers/net/benet/be_proc.c b/drivers/net/benet/be_proc.c
+new file mode 100644
+index 0000000..0bfdb3b
+--- /dev/null
++++ b/drivers/net/benet/be_proc.c
+@@ -0,0 +1,513 @@
++/*
++ * Copyright (C) 2005 - 2011 ServerEngines
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation.  The full GNU General
++ * Public License is included in this distribution in the file called COPYING.
++ *
++ * Contact Information:
++ * linux-drivers@serverengines.com
++ *
++ * ServerEngines
++ * 209 N. Fair Oaks Ave
++ * Sunnyvale, CA 94085
++ */
++#include <linux/proc_fs.h>
++#include "be.h"
++
++char *be_adpt_name[] = {
++	"driver/be2net0",
++	"driver/be2net1",
++	"driver/be2net2",
++	"driver/be2net3",
++	"driver/be2net4",
++	"driver/be2net5",
++	"driver/be2net6",
++	"driver/be2net7"
++};
++
++#define MAX_BE_DEVICES 8
++struct proc_dir_entry *be_proc_dir[MAX_BE_DEVICES];
++
++/*File to read Eth Ring Information */
++#define BE_ETH_RING_FILE "eth_ring"
++#define BE_DRVR_STAT_FILE    "drvr_stat"
++
++/*
++ * this file enables user to read a 32 bit CSR register.
++ * to read 32 bit value of a register at offset 0x1234,
++ * first write the offset 0x1234 (echo "0x1234") in 
++ * the file and then read the value from this file.
++ * the written offset is latched until another value is written
++ */
++#define BE_CSR_R_FILE    "csrr"
++/*
++ * this file enables user to write to a 32 bit CSR register.
++ * to write a value 0xdeadbeef to a register at offset 0x1234,
++ * write 0x1234 0xdeadbeef (echo "0x1234 0xdeadbeeb") to 
++ * the file.
++ */
++#define BE_CSR_W_FILE	"csrw"
++
++#define BE_PROC_MODE          0600
++
++static char read_eth_ring_buf[4096];
++static int read_eth_ring_count;
++
++/*
++ * Get Various Eth Ring Properties
++ */
++static int proc_eth_read_ring(char *page, char **start,
++			      off_t off, int count, int *eof, void *data)
++{
++	int i, n;
++	char *p = read_eth_ring_buf;
++	struct be_adapter *adapter = (struct be_adapter *) data;
++
++	if (off == 0) {
++		/* Reset read_eth_ring_count */
++		read_eth_ring_count = 0;
++
++		n = sprintf(p, "                    PhyAddr  VirtAddr  Size  TotalEntries  ProducerIndex  ConsumerIndex  NumUsed\n");
++		p += n;
++		read_eth_ring_count += n;
++
++		n = sprintf(p, "                    -------  --------  ----  ------------  -------------  -------------  -------\n");
++		p += n;
++		read_eth_ring_count += n;
++
++		n = sprintf(p, "%s", "EthSendRing");
++		p += n;
++		read_eth_ring_count += n;
++
++		n = sprintf(p, "         %7lx  %8p  %4u  %12u  %13u  %13u  %7u  \n",
++			(long) adapter->tx_obj.q.dma_mem.dma,
++			(void *)adapter->tx_obj.q.dma_mem.va,
++			(u32) (adapter->tx_obj.q.len *
++				sizeof(struct be_eth_wrb)),
++			adapter->tx_obj.q.len, adapter->tx_obj.q.head,
++			adapter->tx_obj.q.tail,
++			atomic_read(&adapter->tx_obj.q.used));
++
++		p += n;
++		read_eth_ring_count += n;
++
++		/* Get Eth Send Compl Queue Details */
++		n = sprintf(p, "%s", "EthSendCmplRing");
++		p += n;
++		read_eth_ring_count += n;
++
++		n = sprintf(p, "     %7lx  %8p  %4u  %12u  %13s  %13u  %7s\n",
++			    (long)adapter->tx_obj.cq.dma_mem.dma,
++			    (void *)adapter->tx_obj.cq.dma_mem.va,
++			    (u32) (adapter->tx_obj.cq.len *
++				   sizeof(struct be_eth_tx_compl)),
++			    adapter->tx_obj.cq.len, "NA", 
++			    adapter->tx_obj.cq.tail, "NA");
++
++		p += n;
++		read_eth_ring_count += n;
++		/* Get Eth Rx Queue Details */
++		n = sprintf(p, "%s", "EthRxRing");
++		p += n;
++		read_eth_ring_count += n;
++
++		n = sprintf(p, "           %7lx  %8p  %4u  %12u  %13u  %13s  %7u  \n",
++			    (long)adapter->rx_obj.q.dma_mem.dma,
++			    (void *)adapter->rx_obj.q.dma_mem.va,
++			    (u32) (adapter->rx_obj.q.len * 
++				sizeof(struct be_eth_rx_d)),
++			    adapter->rx_obj.q.len, adapter->rx_obj.q.head,"NA",
++			    atomic_read(&adapter->rx_obj.q.used));
++		p += n;
++		read_eth_ring_count += n;
++
++		/* Get Eth Unicast Rx Compl Queue Details */
++		n = sprintf(p, "%s", "EthRxCmplRing");
++		p += n;
++		read_eth_ring_count += n;
++
++		n = sprintf(p, "       %7lx  %8p  %4u  %12u  %13s  %13u  %7s\n",
++			    (long)adapter->rx_obj.cq.dma_mem.dma,
++			    (void *)adapter->rx_obj.cq.dma_mem.va,
++			    (u32) (adapter->rx_obj.cq.len *
++				   sizeof(struct be_eth_rx_compl)),
++			    adapter->rx_obj.cq.len, "NA", 
++			    adapter->rx_obj.cq.tail, "NA");
++		p += n;
++		read_eth_ring_count += n;
++
++		/* Get Eth Event Queue Details */
++		n = sprintf(p, "%s", "EthTxEventRing");
++		p += n;
++		read_eth_ring_count += n;
++
++		n = sprintf(p,
++			    "      %7lx  %8p  %4u  %12u  %13s  %13u  %7s\n",
++			    (long) adapter->tx_eq.q.dma_mem.dma,
++			    (void *)adapter->tx_eq.q.dma_mem.va,
++			    (u32) (adapter->tx_eq.q.len *
++				   sizeof(struct be_eq_entry)),
++			    adapter->tx_eq.q.len, "NA",
++			    adapter->tx_eq.q.tail, "NA");
++
++		p += n;
++		read_eth_ring_count += n;
++
++		/* Get Eth Event Queue Details */
++		n = sprintf(p, "%s", "EthRxEventRing");
++		p += n;
++		read_eth_ring_count += n;
++
++		n = sprintf(p,
++			    "      %7lx  %8p  %4u  %12u  %13s  %13u  %7s\n",
++			    (long) adapter->rx_eq.q.dma_mem.dma,
++			    (void *)adapter->rx_eq.q.dma_mem.va,
++			    (u32) (adapter->rx_eq.q.len *
++				   sizeof(struct be_eq_entry)),
++			    adapter->rx_eq.q.len, "NA",
++			    adapter->rx_eq.q.tail, "NA");
++
++		p += n;
++		read_eth_ring_count += n;
++	}
++
++	*start = page;
++	/* copy whatever we can */
++	if (count < (read_eth_ring_count - off)) {
++		i = count;
++		*eof = 0;	/* More bytes left */
++	} else {
++		i = read_eth_ring_count - off;
++		*eof = 1;	/* Nothing left. indicate EOF */
++	}
++
++	memcpy(page, read_eth_ring_buf + off, i);
++	return (i);
++}
++
++static int proc_eth_write_ring(struct file *file,
++			       const char *buffer, unsigned long count,
++			       void *data)
++{
++	return (count);		/* we do not support write */
++}
++
++/*
++ * read the driver stats.
++ */
++static int proc_read_drvr_stat(char *page, char **start,
++			       off_t off, int count, int *eof, void *data)
++{
++	int n, lro_cp;
++	char *p = page;
++	struct be_adapter *adapter = (struct be_adapter *) data;
++	struct net_device *netdev = adapter->netdev;
++
++	if (off == 0) {
++		n = sprintf(p, "interface = %s\n", netdev->name);
++		p += n;
++		n = sprintf(p, "tx_reqs = %d\n",
++			    drvr_stats(adapter)->be_tx_reqs);
++		p += n;
++		n = sprintf(p, "tx_stops = %d\n",
++			    drvr_stats(adapter)->be_tx_stops);
++		p += n;
++		n = sprintf(p, "fwd_reqs = %d\n",
++			    drvr_stats(adapter)->be_fwd_reqs);
++		p += n;
++		n = sprintf(p, "tx_wrbs = %d\n",
++			    drvr_stats(adapter)->be_tx_wrbs);
++		p += n;
++		n = sprintf(p, "rx_poll = %d\n", drvr_stats(adapter)->be_rx_polls);
++		p += n;
++		n = sprintf(p, "tx_events = %d\n",
++			    drvr_stats(adapter)->be_tx_events);
++		p += n;
++		n = sprintf(p, "rx_events = %d\n",
++			    drvr_stats(adapter)->be_rx_events);
++		p += n;
++		n = sprintf(p, "tx_compl = %d\n",
++			    drvr_stats(adapter)->be_tx_compl);
++		p += n;
++		n = sprintf(p, "rx_compl = %d\n",
++			    drvr_stats(adapter)->be_rx_compl);
++		p += n;
++		n = sprintf(p, "ethrx_post_fail = %d\n",
++			    drvr_stats(adapter)->be_ethrx_post_fail);
++		p += n;
++		n = sprintf(p, "802.3_dropped_frames = %d\n",
++			    drvr_stats(adapter)->be_802_3_dropped_frames);
++		p += n;
++		n = sprintf(p, "802.3_malformed_frames = %d\n",
++			    drvr_stats(adapter)->be_802_3_malformed_frames);
++		p += n;
++		n = sprintf(p, "eth_tx_rate = %d\n",
++			    drvr_stats(adapter)->be_tx_rate);
++		p += n;
++		n = sprintf(p, "eth_rx_rate = %d\n",
++			    drvr_stats(adapter)->be_rx_rate);
++		p += n;
++
++                lro_cp = (drvr_stats(adapter)->be_lro_hgram_data[0] +
++                        drvr_stats(adapter)->be_lro_hgram_data[1] +
++                        drvr_stats(adapter)->be_lro_hgram_data[2] +
++                        drvr_stats(adapter)->be_lro_hgram_data[3] +
++                        drvr_stats(adapter)->be_lro_hgram_data[4] +
++                        drvr_stats(adapter)->be_lro_hgram_data[5] +
++                        drvr_stats(adapter)->be_lro_hgram_data[6] +
++                        drvr_stats(adapter)->be_lro_hgram_data[7])/100;
++                lro_cp = (lro_cp == 0) ? 1  : lro_cp; /* avoid divide by 0 */
++                n = sprintf(p,
++			"LRO data count %% histogram (1, 2-3, 4-5,..,>=16) = "
++                        "%d, %d, %d, %d  - %d, %d, %d, %d\n",
++                            drvr_stats(adapter)->be_lro_hgram_data[0]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_data[1]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_data[2]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_data[3]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_data[4]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_data[5]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_data[6]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_data[7]/lro_cp);
++                p += n;
++
++                lro_cp = (drvr_stats(adapter)->be_lro_hgram_ack[0] +
++                        drvr_stats(adapter)->be_lro_hgram_ack[1] +
++                        drvr_stats(adapter)->be_lro_hgram_ack[2] +
++                        drvr_stats(adapter)->be_lro_hgram_ack[3] +
++                        drvr_stats(adapter)->be_lro_hgram_ack[4] +
++                        drvr_stats(adapter)->be_lro_hgram_ack[5] +
++                        drvr_stats(adapter)->be_lro_hgram_ack[6] +
++                        drvr_stats(adapter)->be_lro_hgram_ack[7])/100;
++                lro_cp = (lro_cp == 0) ? 1  : lro_cp; /* avoid divide by 0 */
++                n = sprintf(p,
++			"LRO ack count %% histogram (1, 2-3, 4-5,..,>=16) = "
++                        "%d, %d, %d, %d  - %d, %d, %d, %d\n",
++                            drvr_stats(adapter)->be_lro_hgram_ack[0]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_ack[1]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_ack[2]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_ack[3]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_ack[4]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_ack[5]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_ack[6]/lro_cp,
++                            drvr_stats(adapter)->be_lro_hgram_ack[7]/lro_cp);
++                p += n;
++		n = sprintf(p, "rx_eq_delay = %d \n", adapter->rx_eq.cur_eqd);
++		p += n;
++		n = sprintf(p, "rx frags per sec=%d \n", 
++					drvr_stats(adapter)->be_rx_fps);
++		p += n;
++
++	}
++	*eof = 1;
++	return (p - page);
++}
++
++static int proc_write_drvr_stat(struct file *file,
++				const char *buffer, unsigned long count,
++				void *data)
++{
++	struct be_adapter *adapter = (struct be_adapter *) data;
++
++	memset(&(adapter->stats.drvr_stats), 0, 
++			sizeof(adapter->stats.drvr_stats));
++	return (count);		/* we do not support write */
++}
++
++#if 0
++/* the following are some of the functions that are needed here
++ * until all initializations are done by MPU.
++ */
++
++u32 
++CsrReadDr(void*  BaseAddress, u32 Offset)
++{
++    u32  *rp;
++
++    rp = (u32 *) (((u8 *) BaseAddress) + Offset);
++    return (*rp);
++}
++
++/*!
++
++@brief
++    This routine writes to a register located within the CSR
++    space for a given function object.
++
++@param    
++    FuncObj     - Pointer to the function object to read from.
++    
++@param    
++    Offset      - The Offset (in bytes) to write to within the function's CSR space.
++
++@param    
++    Value       - The value to write to the register.
++
++@return
++
++@note
++    IRQL: any
++
++*/
++void 
++CsrWriteDr(void*  BaseAddress, u32 Offset, u32 Value)
++{
++    u32 *Register;
++
++    Register = (u32 *) (((u8 *) BaseAddress) + Offset);
++
++    //TRACE(DL_INFO, "CsrWrite[ %X ] <= %X", Register, Value);
++    *Register = Value;
++}
++u32 be_proc_csrr_offset = -1;	/* to latch the offset of next CSR Read req. */
++
++/*
++ * read the csr_r file.  return the 32 bit register value from
++ * CSR space at offset latched in the global location 
++ * be_proc_csrr_offset
++ */
++static int proc_read_csr_r(char *page, char **start,
++			   off_t off, int count, int *eof, void *data)
++{
++	struct be_adapter * adapter = (struct be_adapter *)data;
++	u32 val;
++	int n = 0;
++	if (be_proc_csrr_offset == -1)
++		return -EINVAL;
++
++	if (off == 0) {
++		/* read the CSR at offset be_proc_csrr_offset and return */
++		val = CsrReadDr(adapter->csr_va, be_proc_csrr_offset);
++		n = sprintf(page, "0x%x\n", val);
++	}
++	*eof = 1;
++	return n;
++}
++
++/* 
++ * save the written value in be_proc_csrr_offset for next
++ * read from the file
++ */
++static int proc_write_csr_r(struct file *file,
++	    const char *buffer, unsigned long count, void *data)
++{
++	char buf[64];
++	u32 n;
++
++	if (count > sizeof(buf) + 1)
++		return -EINVAL;
++	if (copy_from_user(buf, buffer, count))
++		return -EFAULT;
++	buf[count] = '\0';
++
++	n = simple_strtoul(buf, NULL, 16);
++	if (n < 0x50000)
++		be_proc_csrr_offset = n;
++	return (count);
++}
++
++/*
++ * return the latched offset for reading the csr_r file.
++ */
++static int proc_read_csr_w(char *page, char **start,
++			   off_t off, int count, int *eof, void *data)
++{
++
++	*eof = 1;
++	return sprintf(page, "0x%x\n", be_proc_csrr_offset);
++}
++
++/* 
++ * the incoming string is of the form "<offset> <value>"
++ * where the offset is the offset of the register to be written
++ * and value is the value to be written. 
++ */
++static int proc_write_csr_w(struct file *file,
++			    const char *buffer, unsigned long count,
++			    void *data)
++{
++	char buf[64];
++	char *p;
++	u32 n, val;
++	struct be_adapter * adapter = (struct be_adapter *)data;
++
++	if (count > sizeof(buf) + 1)
++		return -EINVAL;
++	if (copy_from_user(buf, buffer, count))
++		return -EFAULT;
++	buf[count] = '\0';
++
++	n = simple_strtoul(buf, &p, 16);
++	if (n > 0x50000)
++		return -EINVAL;
++
++	/* now get the actual value to be written */
++	while (*p == ' ' || *p == '\t')
++		p++;
++	val = simple_strtoul(p, NULL, 16);
++	CsrWriteDr(adapter->csr_va, n, val);
++	return (count);
++}
++#endif
++
++void be_init_procfs(struct be_adapter *adapter, int adapt_num)
++{
++	static struct proc_dir_entry *pde;
++
++	if (adapt_num > MAX_BE_DEVICES - 1)
++		return;
++
++	/* create directory */
++	be_proc_dir[adapt_num] =
++	     proc_mkdir(be_adpt_name[adapt_num], NULL);
++	if (be_proc_dir[adapt_num]) {
++		(be_proc_dir[adapt_num])->owner = THIS_MODULE;
++	}
++
++	pde = create_proc_entry(BE_ETH_RING_FILE, BE_PROC_MODE,
++			       be_proc_dir[adapt_num]);
++	if (pde) {
++		pde->read_proc = proc_eth_read_ring;
++		pde->write_proc = proc_eth_write_ring;
++		pde->data = adapter;
++		pde->owner = THIS_MODULE;
++	}
++
++	pde = create_proc_entry(BE_DRVR_STAT_FILE, BE_PROC_MODE,
++			       be_proc_dir[adapt_num]);
++	if (pde) {
++		pde->read_proc = proc_read_drvr_stat;
++		pde->write_proc = proc_write_drvr_stat;
++		pde->data = adapter;
++		pde->owner = THIS_MODULE;
++	}
++
++#if 0
++	if ((pde = create_proc_entry(BE_CSR_R_FILE, BE_PROC_MODE, be_proc_dir[adapt_num]))) {
++		pde->read_proc = proc_read_csr_r;
++		pde->write_proc = proc_write_csr_r;
++		pde->data = adapter;
++		pde->owner = THIS_MODULE;
++	}
++
++	if ((pde = create_proc_entry(BE_CSR_W_FILE, BE_PROC_MODE, be_proc_dir[adapt_num]))) {
++		pde->read_proc = proc_read_csr_w;
++		pde->write_proc = proc_write_csr_w;
++		pde->data = adapter;
++		pde->owner = THIS_MODULE;
++	}
++#endif
++}
++
++void be_cleanup_procfs(struct be_adapter *adapter, int adapt_num)
++{
++	if (adapt_num > MAX_BE_DEVICES - 1)
++		return;
++	remove_proc_entry(BE_ETH_RING_FILE, be_proc_dir[adapt_num]);
++	remove_proc_entry(BE_DRVR_STAT_FILE, be_proc_dir[adapt_num]);
++	remove_proc_entry(BE_CSR_R_FILE, be_proc_dir[adapt_num]);
++	remove_proc_entry(BE_CSR_W_FILE, be_proc_dir[adapt_num]);
++	remove_proc_entry(be_adpt_name[adapt_num], NULL);
++}
+diff --git a/drivers/net/benet/version.h b/drivers/net/benet/version.h
+new file mode 100644
+index 0000000..c7ed692
+--- /dev/null
++++ b/drivers/net/benet/version.h
+@@ -0,0 +1,51 @@
++#define STR_BE_BRANCH "0" 
++#define STR_BE_BUILD "479" 
++#define STR_BE_DOT   "0"
++#define STR_BE_MINOR "0"
++#define STR_BE_MAJOR "4"
++
++#define BE_BRANCH 0 
++#define BE_BUILD 479 
++#define BE_DOT   0
++#define BE_MINOR 0
++#define BE_MAJOR 4
++
++#define MGMT_BRANCH 0
++#define MGMT_BUILDNUM 479
++#define MGMT_MINOR 0
++#define MGMT_MAJOR 4
++
++#define BE_REDBOOT_VERSION "2.0.5.0"
++
++//start-auto
++#define BUILD_MONTH "12"
++#define BUILD_MONTH_NAME "December"
++#define BUILD_DAY "6"
++#define BUILD_YEAR "2011"
++#define BUILD_24HOUR "21"
++#define BUILD_12HOUR "9"
++#define BUILD_AM_PM "PM"
++#define BUILD_MIN "48"
++#define BUILD_SEC "05"
++#define BUILD_MONTH_NUMBER 12
++#define BUILD_DAY_NUMBER 6
++#define BUILD_YEAR_NUMBER 2011
++#define BUILD_24HOUR_NUMBER 21
++#define BUILD_12HOUR_NUMBER 9
++#define BUILD_MIN_NUMBER 48
++#define BUILD_SEC_NUMBER 5
++#undef MAJOR_BUILD
++#undef MINOR_BUILD
++#undef DOT_BUILD
++#define NUMBERED_BUILD
++#undef BRANCH_BUILD
++//end-auto
++
++#define ELX_FCOE_XROM_BIOS_VER "7.03a1"
++#define ELX_FCoE_X86_VER       "4.02a1"
++#define ELX_FCoE_EFI_VER       "5.01a1"
++#define ELX_FCoE_FCODE_VER     "4.01a0"
++#define ELX_PXE_BIOS_VER       "3.00a5"
++#define ELX_UEFI_NIC_VER       "2.10A10"
++#define ELX_UEFI_FCODE_VER     "1.10A0"
++#define ELX_ISCSI_BIOS_VER     "1.00A8"
+diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
+index 4874b2b..67f8526 100644
+--- a/drivers/net/bnx2.c
++++ b/drivers/net/bnx2.c
+@@ -5809,6 +5809,8 @@ bnx2_test_nvram(struct bnx2 *bp)
+ 	int rc = 0;
+ 	u32 magic, csum;
+ 
++	pax_track_stack();
++
+ 	if ((rc = bnx2_nvram_read(bp, 0, data, 4)) != 0)
+ 		goto test_nvram_done;
+ 
+diff --git a/drivers/net/cxgb3/l2t.h b/drivers/net/cxgb3/l2t.h
+index fd3eb07..8a6978d 100644
+--- a/drivers/net/cxgb3/l2t.h
++++ b/drivers/net/cxgb3/l2t.h
+@@ -86,7 +86,7 @@ typedef void (*arp_failure_handler_func)(struct t3cdev * dev,
+  */
+ struct l2t_skb_cb {
+ 	arp_failure_handler_func arp_failure_handler;
+-};
++} __no_const;
+ 
+ #define L2T_SKB_CB(skb) ((struct l2t_skb_cb *)(skb)->cb)
+ 
+diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
+index 032cfe0..411af379 100644
+--- a/drivers/net/cxgb3/t3_hw.c
++++ b/drivers/net/cxgb3/t3_hw.c
+@@ -699,6 +699,8 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
+ 	int i, addr, ret;
+ 	struct t3_vpd vpd;
+ 
++	pax_track_stack();
++
+ 	/*
+ 	 * Card information is normally at VPD_BASE but some early cards had
+ 	 * it at 0.
+diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
+index d1e0563..b9e129c 100644
+--- a/drivers/net/e1000e/82571.c
++++ b/drivers/net/e1000e/82571.c
+@@ -212,7 +212,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
+ {
+ 	struct e1000_hw *hw = &adapter->hw;
+ 	struct e1000_mac_info *mac = &hw->mac;
+-	struct e1000_mac_operations *func = &mac->ops;
++	e1000_mac_operations_no_const *func = &mac->ops;
+ 	u32 swsm = 0;
+ 	u32 swsm2 = 0;
+ 	bool force_clear_smbi = false;
+@@ -1656,7 +1656,7 @@ static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw)
+ 	temp = er32(ICRXDMTC);
+ }
+ 
+-static struct e1000_mac_operations e82571_mac_ops = {
++static const struct e1000_mac_operations e82571_mac_ops = {
+ 	/* .check_mng_mode: mac type dependent */
+ 	/* .check_for_link: media type dependent */
+ 	.id_led_init		= e1000e_id_led_init,
+@@ -1674,7 +1674,7 @@ static struct e1000_mac_operations e82571_mac_ops = {
+ 	.setup_led		= e1000e_setup_led_generic,
+ };
+ 
+-static struct e1000_phy_operations e82_phy_ops_igp = {
++static const struct e1000_phy_operations e82_phy_ops_igp = {
+ 	.acquire_phy		= e1000_get_hw_semaphore_82571,
+ 	.check_reset_block	= e1000e_check_reset_block_generic,
+ 	.commit_phy		= NULL,
+@@ -1691,7 +1691,7 @@ static struct e1000_phy_operations e82_phy_ops_igp = {
+ 	.cfg_on_link_up      	= NULL,
+ };
+ 
+-static struct e1000_phy_operations e82_phy_ops_m88 = {
++static const struct e1000_phy_operations e82_phy_ops_m88 = {
+ 	.acquire_phy		= e1000_get_hw_semaphore_82571,
+ 	.check_reset_block	= e1000e_check_reset_block_generic,
+ 	.commit_phy		= e1000e_phy_sw_reset,
+@@ -1708,7 +1708,7 @@ static struct e1000_phy_operations e82_phy_ops_m88 = {
+ 	.cfg_on_link_up      	= NULL,
+ };
+ 
+-static struct e1000_phy_operations e82_phy_ops_bm = {
++static const struct e1000_phy_operations e82_phy_ops_bm = {
+ 	.acquire_phy		= e1000_get_hw_semaphore_82571,
+ 	.check_reset_block	= e1000e_check_reset_block_generic,
+ 	.commit_phy		= e1000e_phy_sw_reset,
+@@ -1725,7 +1725,7 @@ static struct e1000_phy_operations e82_phy_ops_bm = {
+ 	.cfg_on_link_up      	= NULL,
+ };
+ 
+-static struct e1000_nvm_operations e82571_nvm_ops = {
++static const struct e1000_nvm_operations e82571_nvm_ops = {
+ 	.acquire_nvm		= e1000_acquire_nvm_82571,
+ 	.read_nvm		= e1000e_read_nvm_eerd,
+ 	.release_nvm		= e1000_release_nvm_82571,
+diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
+index 47db9bd..fa58ccd 100644
+--- a/drivers/net/e1000e/e1000.h
++++ b/drivers/net/e1000e/e1000.h
+@@ -375,9 +375,9 @@ struct e1000_info {
+ 	u32			pba;
+ 	u32			max_hw_frame_size;
+ 	s32			(*get_variants)(struct e1000_adapter *);
+-	struct e1000_mac_operations *mac_ops;
+-	struct e1000_phy_operations *phy_ops;
+-	struct e1000_nvm_operations *nvm_ops;
++	const struct e1000_mac_operations *mac_ops;
++	const struct e1000_phy_operations *phy_ops;
++	const struct e1000_nvm_operations *nvm_ops;
+ };
+ 
+ /* hardware capability, feature, and workaround flags */
+diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
+index ae5d736..e9a93a1 100644
+--- a/drivers/net/e1000e/es2lan.c
++++ b/drivers/net/e1000e/es2lan.c
+@@ -207,7 +207,7 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter)
+ {
+ 	struct e1000_hw *hw = &adapter->hw;
+ 	struct e1000_mac_info *mac = &hw->mac;
+-	struct e1000_mac_operations *func = &mac->ops;
++	e1000_mac_operations_no_const *func = &mac->ops;
+ 
+ 	/* Set media type */
+ 	switch (adapter->pdev->device) {
+@@ -1365,7 +1365,7 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
+ 	temp = er32(ICRXDMTC);
+ }
+ 
+-static struct e1000_mac_operations es2_mac_ops = {
++static const struct e1000_mac_operations es2_mac_ops = {
+ 	.id_led_init		= e1000e_id_led_init,
+ 	.check_mng_mode		= e1000e_check_mng_mode_generic,
+ 	/* check_for_link dependent on media type */
+@@ -1383,7 +1383,7 @@ static struct e1000_mac_operations es2_mac_ops = {
+ 	.setup_led		= e1000e_setup_led_generic,
+ };
+ 
+-static struct e1000_phy_operations es2_phy_ops = {
++static const struct e1000_phy_operations es2_phy_ops = {
+ 	.acquire_phy		= e1000_acquire_phy_80003es2lan,
+ 	.check_reset_block	= e1000e_check_reset_block_generic,
+ 	.commit_phy	 	= e1000e_phy_sw_reset,
+@@ -1400,7 +1400,7 @@ static struct e1000_phy_operations es2_phy_ops = {
+ 	.cfg_on_link_up      	= e1000_cfg_on_link_up_80003es2lan,
+ };
+ 
+-static struct e1000_nvm_operations es2_nvm_ops = {
++static const struct e1000_nvm_operations es2_nvm_ops = {
+ 	.acquire_nvm		= e1000_acquire_nvm_80003es2lan,
+ 	.read_nvm		= e1000e_read_nvm_eerd,
+ 	.release_nvm		= e1000_release_nvm_80003es2lan,
+diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
+index 11f3b7c..6381887 100644
+--- a/drivers/net/e1000e/hw.h
++++ b/drivers/net/e1000e/hw.h
+@@ -753,6 +753,7 @@ struct e1000_mac_operations {
+ 	s32  (*setup_physical_interface)(struct e1000_hw *);
+ 	s32  (*setup_led)(struct e1000_hw *);
+ };
++typedef struct e1000_mac_operations __no_const e1000_mac_operations_no_const;
+ 
+ /* Function pointers for the PHY. */
+ struct e1000_phy_operations {
+@@ -774,6 +775,7 @@ struct e1000_phy_operations {
+ 	s32  (*write_phy_reg_locked)(struct e1000_hw *, u32, u16);
+ 	s32  (*cfg_on_link_up)(struct e1000_hw *);
+ };
++typedef struct e1000_phy_operations __no_const e1000_phy_operations_no_const;
+ 
+ /* Function pointers for the NVM. */
+ struct e1000_nvm_operations {
+@@ -785,9 +787,10 @@ struct e1000_nvm_operations {
+ 	s32  (*validate_nvm)(struct e1000_hw *);
+ 	s32  (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
+ };
++typedef struct e1000_nvm_operations __no_const e1000_nvm_operations_no_const;
+ 
+ struct e1000_mac_info {
+-	struct e1000_mac_operations ops;
++	e1000_mac_operations_no_const ops;
+ 
+ 	u8 addr[6];
+ 	u8 perm_addr[6];
+@@ -823,7 +826,7 @@ struct e1000_mac_info {
+ };
+ 
+ struct e1000_phy_info {
+-	struct e1000_phy_operations ops;
++	e1000_phy_operations_no_const ops;
+ 
+ 	enum e1000_phy_type type;
+ 
+@@ -857,7 +860,7 @@ struct e1000_phy_info {
+ };
+ 
+ struct e1000_nvm_info {
+-	struct e1000_nvm_operations ops;
++	e1000_nvm_operations_no_const ops;
+ 
+ 	enum e1000_nvm_type type;
+ 	enum e1000_nvm_override override;
+diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
+index de39f9a..e28d3e0 100644
+--- a/drivers/net/e1000e/ich8lan.c
++++ b/drivers/net/e1000e/ich8lan.c
+@@ -3463,7 +3463,7 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
+ 	}
+ }
+ 
+-static struct e1000_mac_operations ich8_mac_ops = {
++static const struct e1000_mac_operations ich8_mac_ops = {
+ 	.id_led_init		= e1000e_id_led_init,
+ 	.check_mng_mode		= e1000_check_mng_mode_ich8lan,
+ 	.check_for_link		= e1000_check_for_copper_link_ich8lan,
+@@ -3481,7 +3481,7 @@ static struct e1000_mac_operations ich8_mac_ops = {
+ 	/* id_led_init dependent on mac type */
+ };
+ 
+-static struct e1000_phy_operations ich8_phy_ops = {
++static const struct e1000_phy_operations ich8_phy_ops = {
+ 	.acquire_phy		= e1000_acquire_swflag_ich8lan,
+ 	.check_reset_block	= e1000_check_reset_block_ich8lan,
+ 	.commit_phy		= NULL,
+@@ -3497,7 +3497,7 @@ static struct e1000_phy_operations ich8_phy_ops = {
+ 	.write_phy_reg		= e1000e_write_phy_reg_igp,
+ };
+ 
+-static struct e1000_nvm_operations ich8_nvm_ops = {
++static const struct e1000_nvm_operations ich8_nvm_ops = {
+ 	.acquire_nvm		= e1000_acquire_nvm_ich8lan,
+ 	.read_nvm	 	= e1000_read_nvm_ich8lan,
+ 	.release_nvm		= e1000_release_nvm_ich8lan,
+diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
+index 18d5fbb..542d96d 100644
+--- a/drivers/net/fealnx.c
++++ b/drivers/net/fealnx.c
+@@ -151,7 +151,7 @@ struct chip_info {
+ 	int flags;
+ };
+ 
+-static const struct chip_info skel_netdrv_tbl[] __devinitdata = {
++static const struct chip_info skel_netdrv_tbl[] __devinitconst = {
+  	{ "100/10M Ethernet PCI Adapter",	HAS_MII_XCVR },
+ 	{ "100/10M Ethernet PCI Adapter",	HAS_CHIP_XCVR },
+ 	{ "1000/100/10M Ethernet PCI Adapter",	HAS_MII_XCVR },
+diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
+index 0e5b54b..b503f82 100644
+--- a/drivers/net/hamradio/6pack.c
++++ b/drivers/net/hamradio/6pack.c
+@@ -461,6 +461,8 @@ static void sixpack_receive_buf(struct tty_struct *tty,
+ 	unsigned char buf[512];
+ 	int count1;
+ 
++	pax_track_stack();
++
+ 	if (!count)
+ 		return;
+ 
+diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
+index 5862282..7cce8cb 100644
+--- a/drivers/net/ibmveth.c
++++ b/drivers/net/ibmveth.c
+@@ -1577,7 +1577,7 @@ static struct attribute * veth_pool_attrs[] = {
+ 	NULL,
+ };
+ 
+-static struct sysfs_ops veth_pool_ops = {
++static const struct sysfs_ops veth_pool_ops = {
+ 	.show   = veth_pool_show,
+ 	.store  = veth_pool_store,
+ };
+diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
+index d617f2d..57b5309 100644
+--- a/drivers/net/igb/e1000_82575.c
++++ b/drivers/net/igb/e1000_82575.c
+@@ -1411,7 +1411,7 @@ void igb_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
+ 	wr32(E1000_VT_CTL, vt_ctl);
+ }
+ 
+-static struct e1000_mac_operations e1000_mac_ops_82575 = {
++static const struct e1000_mac_operations e1000_mac_ops_82575 = {
+ 	.reset_hw             = igb_reset_hw_82575,
+ 	.init_hw              = igb_init_hw_82575,
+ 	.check_for_link       = igb_check_for_link_82575,
+@@ -1420,13 +1420,13 @@ static struct e1000_mac_operations e1000_mac_ops_82575 = {
+ 	.get_speed_and_duplex = igb_get_speed_and_duplex_copper,
+ };
+ 
+-static struct e1000_phy_operations e1000_phy_ops_82575 = {
++static const struct e1000_phy_operations e1000_phy_ops_82575 = {
+ 	.acquire              = igb_acquire_phy_82575,
+ 	.get_cfg_done         = igb_get_cfg_done_82575,
+ 	.release              = igb_release_phy_82575,
+ };
+ 
+-static struct e1000_nvm_operations e1000_nvm_ops_82575 = {
++static const struct e1000_nvm_operations e1000_nvm_ops_82575 = {
+ 	.acquire              = igb_acquire_nvm_82575,
+ 	.read                 = igb_read_nvm_eerd,
+ 	.release              = igb_release_nvm_82575,
+diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
+index 72081df..d855cf5 100644
+--- a/drivers/net/igb/e1000_hw.h
++++ b/drivers/net/igb/e1000_hw.h
+@@ -288,6 +288,7 @@ struct e1000_mac_operations {
+ 	s32  (*read_mac_addr)(struct e1000_hw *);
+ 	s32  (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
+ };
++typedef struct e1000_mac_operations __no_const e1000_mac_operations_no_const;
+ 
+ struct e1000_phy_operations {
+ 	s32  (*acquire)(struct e1000_hw *);
+@@ -303,6 +304,7 @@ struct e1000_phy_operations {
+ 	s32  (*set_d3_lplu_state)(struct e1000_hw *, bool);
+ 	s32  (*write_reg)(struct e1000_hw *, u32, u16);
+ };
++typedef struct e1000_phy_operations __no_const e1000_phy_operations_no_const;
+ 
+ struct e1000_nvm_operations {
+ 	s32  (*acquire)(struct e1000_hw *);
+@@ -310,6 +312,7 @@ struct e1000_nvm_operations {
+ 	void (*release)(struct e1000_hw *);
+ 	s32  (*write)(struct e1000_hw *, u16, u16, u16 *);
+ };
++typedef struct e1000_nvm_operations __no_const e1000_nvm_operations_no_const;
+ 
+ struct e1000_info {
+ 	s32 (*get_invariants)(struct e1000_hw *);
+@@ -321,7 +324,7 @@ struct e1000_info {
+ extern const struct e1000_info e1000_82575_info;
+ 
+ struct e1000_mac_info {
+-	struct e1000_mac_operations ops;
++	e1000_mac_operations_no_const ops;
+ 
+ 	u8 addr[6];
+ 	u8 perm_addr[6];
+@@ -365,7 +368,7 @@ struct e1000_mac_info {
+ };
+ 
+ struct e1000_phy_info {
+-	struct e1000_phy_operations ops;
++	e1000_phy_operations_no_const ops;
+ 
+ 	enum e1000_phy_type type;
+ 
+@@ -400,7 +403,7 @@ struct e1000_phy_info {
+ };
+ 
+ struct e1000_nvm_info {
+-	struct e1000_nvm_operations ops;
++	e1000_nvm_operations_no_const ops;
+ 
+ 	enum e1000_nvm_type type;
+ 	enum e1000_nvm_override override;
+@@ -446,6 +449,7 @@ struct e1000_mbx_operations {
+ 	s32 (*check_for_ack)(struct e1000_hw *, u16);
+ 	s32 (*check_for_rst)(struct e1000_hw *, u16);
+ };
++typedef struct e1000_mbx_operations __no_const e1000_mbx_operations_no_const;
+ 
+ struct e1000_mbx_stats {
+ 	u32 msgs_tx;
+@@ -457,7 +461,7 @@ struct e1000_mbx_stats {
+ };
+ 
+ struct e1000_mbx_info {
+-	struct e1000_mbx_operations ops;
++	e1000_mbx_operations_no_const ops;
+ 	struct e1000_mbx_stats stats;
+ 	u32 timeout;
+ 	u32 usec_delay;
+diff --git a/drivers/net/igbvf/vf.h b/drivers/net/igbvf/vf.h
+index 1e8ce37..549c453 100644
+--- a/drivers/net/igbvf/vf.h
++++ b/drivers/net/igbvf/vf.h
+@@ -187,9 +187,10 @@ struct e1000_mac_operations {
+ 	s32  (*read_mac_addr)(struct e1000_hw *);
+ 	s32  (*set_vfta)(struct e1000_hw *, u16, bool);
+ };
++typedef struct e1000_mac_operations __no_const e1000_mac_operations_no_const;
+ 
+ struct e1000_mac_info {
+-	struct e1000_mac_operations ops;
++	e1000_mac_operations_no_const ops;
+ 	u8 addr[6];
+ 	u8 perm_addr[6];
+ 
+@@ -211,6 +212,7 @@ struct e1000_mbx_operations {
+ 	s32 (*check_for_ack)(struct e1000_hw *);
+ 	s32 (*check_for_rst)(struct e1000_hw *);
+ };
++typedef struct e1000_mbx_operations __no_const e1000_mbx_operations_no_const;
+ 
+ struct e1000_mbx_stats {
+ 	u32 msgs_tx;
+@@ -222,7 +224,7 @@ struct e1000_mbx_stats {
+ };
+ 
+ struct e1000_mbx_info {
+-	struct e1000_mbx_operations ops;
++	e1000_mbx_operations_no_const ops;
+ 	struct e1000_mbx_stats stats;
+ 	u32 timeout;
+ 	u32 usec_delay;
+diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
+index aa7286b..a61394f 100644
+--- a/drivers/net/iseries_veth.c
++++ b/drivers/net/iseries_veth.c
+@@ -384,7 +384,7 @@ static struct attribute *veth_cnx_default_attrs[] = {
+ 	NULL
+ };
+ 
+-static struct sysfs_ops veth_cnx_sysfs_ops = {
++static const struct sysfs_ops veth_cnx_sysfs_ops = {
+ 		.show = veth_cnx_attribute_show
+ };
+ 
+@@ -441,7 +441,7 @@ static struct attribute *veth_port_default_attrs[] = {
+ 	NULL
+ };
+ 
+-static struct sysfs_ops veth_port_sysfs_ops = {
++static const struct sysfs_ops veth_port_sysfs_ops = {
+ 	.show = veth_port_attribute_show
+ };
+ 
+diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
+index 8aa44dc..fa1e797 100644
+--- a/drivers/net/ixgb/ixgb_main.c
++++ b/drivers/net/ixgb/ixgb_main.c
+@@ -1052,6 +1052,8 @@ ixgb_set_multi(struct net_device *netdev)
+ 	u32 rctl;
+ 	int i;
+ 
++	pax_track_stack();
++
+ 	/* Check for Promiscuous and All Multicast modes */
+ 
+ 	rctl = IXGB_READ_REG(hw, RCTL);
+diff --git a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
+index af35e1d..8781785 100644
+--- a/drivers/net/ixgb/ixgb_param.c
++++ b/drivers/net/ixgb/ixgb_param.c
+@@ -260,6 +260,9 @@ void __devinit
+ ixgb_check_options(struct ixgb_adapter *adapter)
+ {
+ 	int bd = adapter->bd_number;
++
++	pax_track_stack();
++
+ 	if (bd >= IXGB_MAX_NIC) {
+ 		printk(KERN_NOTICE
+ 			   "Warning: no configuration for board #%i\n", bd);
+diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
+index b17aa73..ed74540 100644
+--- a/drivers/net/ixgbe/ixgbe_type.h
++++ b/drivers/net/ixgbe/ixgbe_type.h
+@@ -2327,6 +2327,7 @@ struct ixgbe_eeprom_operations {
+ 	s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
+ 	s32 (*update_checksum)(struct ixgbe_hw *);
+ };
++typedef struct ixgbe_eeprom_operations __no_const ixgbe_eeprom_operations_no_const;
+ 
+ struct ixgbe_mac_operations {
+ 	s32 (*init_hw)(struct ixgbe_hw *);
+@@ -2376,6 +2377,7 @@ struct ixgbe_mac_operations {
+ 	/* Flow Control */
+ 	s32 (*fc_enable)(struct ixgbe_hw *, s32);
+ };
++typedef struct ixgbe_mac_operations __no_const ixgbe_mac_operations_no_const;
+ 
+ struct ixgbe_phy_operations {
+ 	s32 (*identify)(struct ixgbe_hw *);
+@@ -2394,9 +2396,10 @@ struct ixgbe_phy_operations {
+ 	s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
+ 	s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
+ };
++typedef struct ixgbe_phy_operations __no_const ixgbe_phy_operations_no_const;
+ 
+ struct ixgbe_eeprom_info {
+-	struct ixgbe_eeprom_operations  ops;
++	ixgbe_eeprom_operations_no_const ops;
+ 	enum ixgbe_eeprom_type          type;
+ 	u32                             semaphore_delay;
+ 	u16                             word_size;
+@@ -2404,7 +2407,7 @@ struct ixgbe_eeprom_info {
+ };
+ 
+ struct ixgbe_mac_info {
+-	struct ixgbe_mac_operations     ops;
++	ixgbe_mac_operations_no_const   ops;
+ 	enum ixgbe_mac_type             type;
+ 	u8                              addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+ 	u8                              perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+@@ -2423,7 +2426,7 @@ struct ixgbe_mac_info {
+ };
+ 
+ struct ixgbe_phy_info {
+-	struct ixgbe_phy_operations     ops;
++	ixgbe_phy_operations_no_const   ops;
+ 	struct mdio_if_info		mdio;
+ 	enum ixgbe_phy_type             type;
+ 	u32                             id;
+diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
+index 291a505..2543756 100644
+--- a/drivers/net/mlx4/main.c
++++ b/drivers/net/mlx4/main.c
+@@ -38,6 +38,7 @@
+ #include <linux/errno.h>
+ #include <linux/pci.h>
+ #include <linux/dma-mapping.h>
++#include <linux/sched.h>
+ 
+ #include <linux/mlx4/device.h>
+ #include <linux/mlx4/doorbell.h>
+@@ -730,6 +731,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
+ 	u64 icm_size;
+ 	int err;
+ 
++	pax_track_stack();
++
+ 	err = mlx4_QUERY_FW(dev);
+ 	if (err) {
+ 		if (err == -EACCES)
+diff --git a/drivers/net/niu.c b/drivers/net/niu.c
+index 2dce134..fa5ce75 100644
+--- a/drivers/net/niu.c
++++ b/drivers/net/niu.c
+@@ -9128,6 +9128,8 @@ static void __devinit niu_try_msix(struct niu *np, u8 *ldg_num_map)
+ 	int i, num_irqs, err;
+ 	u8 first_ldg;
+ 
++	pax_track_stack();
++
+ 	first_ldg = (NIU_NUM_LDG / parent->num_ports) * np->port;
+ 	for (i = 0; i < (NIU_NUM_LDG / parent->num_ports); i++)
+ 		ldg_num_map[i] = first_ldg + i;
+diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
+index c1b3f09..97cd8c4 100644
+--- a/drivers/net/pcnet32.c
++++ b/drivers/net/pcnet32.c
+@@ -79,7 +79,7 @@ static int cards_found;
+ /*
+  * VLB I/O addresses
+  */
+-static unsigned int pcnet32_portlist[] __initdata =
++static unsigned int pcnet32_portlist[] __devinitdata =
+     { 0x300, 0x320, 0x340, 0x360, 0 };
+ 
+ static int pcnet32_debug = 0;
+@@ -267,7 +267,7 @@ struct pcnet32_private {
+ 	struct sk_buff		**rx_skbuff;
+ 	dma_addr_t		*tx_dma_addr;
+ 	dma_addr_t		*rx_dma_addr;
+-	struct pcnet32_access	a;
++	struct pcnet32_access	*a;
+ 	spinlock_t		lock;		/* Guard lock */
+ 	unsigned int		cur_rx, cur_tx;	/* The next free ring entry */
+ 	unsigned int		rx_ring_size;	/* current rx ring size */
+@@ -457,9 +457,9 @@ static void pcnet32_netif_start(struct net_device *dev)
+ 	u16 val;
+ 
+ 	netif_wake_queue(dev);
+-	val = lp->a.read_csr(ioaddr, CSR3);
++	val = lp->a->read_csr(ioaddr, CSR3);
+ 	val &= 0x00ff;
+-	lp->a.write_csr(ioaddr, CSR3, val);
++	lp->a->write_csr(ioaddr, CSR3, val);
+ 	napi_enable(&lp->napi);
+ }
+ 
+@@ -744,7 +744,7 @@ static u32 pcnet32_get_link(struct net_device *dev)
+ 		r = mii_link_ok(&lp->mii_if);
+ 	} else if (lp->chip_version >= PCNET32_79C970A) {
+ 		ulong ioaddr = dev->base_addr;	/* card base I/O address */
+-		r = (lp->a.read_bcr(ioaddr, 4) != 0xc0);
++		r = (lp->a->read_bcr(ioaddr, 4) != 0xc0);
+ 	} else {	/* can not detect link on really old chips */
+ 		r = 1;
+ 	}
+@@ -806,7 +806,7 @@ static int pcnet32_set_ringparam(struct net_device *dev,
+ 		pcnet32_netif_stop(dev);
+ 
+ 	spin_lock_irqsave(&lp->lock, flags);
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* stop the chip */
++	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);	/* stop the chip */
+ 
+ 	size = min(ering->tx_pending, (unsigned int)TX_MAX_RING_SIZE);
+ 
+@@ -886,7 +886,7 @@ static void pcnet32_ethtool_test(struct net_device *dev,
+ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
+ {
+ 	struct pcnet32_private *lp = netdev_priv(dev);
+-	struct pcnet32_access *a = &lp->a;	/* access to registers */
++	struct pcnet32_access *a = lp->a;	/* access to registers */
+ 	ulong ioaddr = dev->base_addr;	/* card base I/O address */
+ 	struct sk_buff *skb;	/* sk buff */
+ 	int x, i;		/* counters */
+@@ -906,21 +906,21 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
+ 		pcnet32_netif_stop(dev);
+ 
+ 	spin_lock_irqsave(&lp->lock, flags);
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* stop the chip */
++	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);	/* stop the chip */
+ 
+ 	numbuffs = min(numbuffs, (int)min(lp->rx_ring_size, lp->tx_ring_size));
+ 
+ 	/* Reset the PCNET32 */
+-	lp->a.reset(ioaddr);
+-	lp->a.write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
++	lp->a->reset(ioaddr);
++	lp->a->write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
+ 
+ 	/* switch pcnet32 to 32bit mode */
+-	lp->a.write_bcr(ioaddr, 20, 2);
++	lp->a->write_bcr(ioaddr, 20, 2);
+ 
+ 	/* purge & init rings but don't actually restart */
+ 	pcnet32_restart(dev, 0x0000);
+ 
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* Set STOP bit */
++	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);	/* Set STOP bit */
+ 
+ 	/* Initialize Transmit buffers. */
+ 	size = data_len + 15;
+@@ -966,10 +966,10 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
+ 
+ 	/* set int loopback in CSR15 */
+ 	x = a->read_csr(ioaddr, CSR15) & 0xfffc;
+-	lp->a.write_csr(ioaddr, CSR15, x | 0x0044);
++	lp->a->write_csr(ioaddr, CSR15, x | 0x0044);
+ 
+ 	teststatus = cpu_to_le16(0x8000);
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_START);	/* Set STRT bit */
++	lp->a->write_csr(ioaddr, CSR0, CSR0_START);	/* Set STRT bit */
+ 
+ 	/* Check status of descriptors */
+ 	for (x = 0; x < numbuffs; x++) {
+@@ -990,7 +990,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
+ 		}
+ 	}
+ 
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* Set STOP bit */
++	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);	/* Set STOP bit */
+ 	wmb();
+ 	if (netif_msg_hw(lp) && netif_msg_pktdata(lp)) {
+ 		printk(KERN_DEBUG "%s: RX loopback packets:\n", dev->name);
+@@ -1039,7 +1039,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
+ 		pcnet32_restart(dev, CSR0_NORMAL);
+ 	} else {
+ 		pcnet32_purge_rx_ring(dev);
+-		lp->a.write_bcr(ioaddr, 20, 4);	/* return to 16bit mode */
++		lp->a->write_bcr(ioaddr, 20, 4);	/* return to 16bit mode */
+ 	}
+ 	spin_unlock_irqrestore(&lp->lock, flags);
+ 
+@@ -1049,7 +1049,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
+ static void pcnet32_led_blink_callback(struct net_device *dev)
+ {
+ 	struct pcnet32_private *lp = netdev_priv(dev);
+-	struct pcnet32_access *a = &lp->a;
++	struct pcnet32_access *a = lp->a;
+ 	ulong ioaddr = dev->base_addr;
+ 	unsigned long flags;
+ 	int i;
+@@ -1066,7 +1066,7 @@ static void pcnet32_led_blink_callback(struct net_device *dev)
+ static int pcnet32_phys_id(struct net_device *dev, u32 data)
+ {
+ 	struct pcnet32_private *lp = netdev_priv(dev);
+-	struct pcnet32_access *a = &lp->a;
++	struct pcnet32_access *a = lp->a;
+ 	ulong ioaddr = dev->base_addr;
+ 	unsigned long flags;
+ 	int i, regs[4];
+@@ -1112,7 +1112,7 @@ static int pcnet32_suspend(struct net_device *dev, unsigned long *flags,
+ {
+ 	int csr5;
+ 	struct pcnet32_private *lp = netdev_priv(dev);
+-	struct pcnet32_access *a = &lp->a;
++	struct pcnet32_access *a = lp->a;
+ 	ulong ioaddr = dev->base_addr;
+ 	int ticks;
+ 
+@@ -1388,8 +1388,8 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
+ 	spin_lock_irqsave(&lp->lock, flags);
+ 	if (pcnet32_tx(dev)) {
+ 		/* reset the chip to clear the error condition, then restart */
+-		lp->a.reset(ioaddr);
+-		lp->a.write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
++		lp->a->reset(ioaddr);
++		lp->a->write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
+ 		pcnet32_restart(dev, CSR0_START);
+ 		netif_wake_queue(dev);
+ 	}
+@@ -1401,12 +1401,12 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
+ 		__napi_complete(napi);
+ 
+ 		/* clear interrupt masks */
+-		val = lp->a.read_csr(ioaddr, CSR3);
++		val = lp->a->read_csr(ioaddr, CSR3);
+ 		val &= 0x00ff;
+-		lp->a.write_csr(ioaddr, CSR3, val);
++		lp->a->write_csr(ioaddr, CSR3, val);
+ 
+ 		/* Set interrupt enable. */
+-		lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN);
++		lp->a->write_csr(ioaddr, CSR0, CSR0_INTEN);
+ 
+ 		spin_unlock_irqrestore(&lp->lock, flags);
+ 	}
+@@ -1429,7 +1429,7 @@ static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ 	int i, csr0;
+ 	u16 *buff = ptr;
+ 	struct pcnet32_private *lp = netdev_priv(dev);
+-	struct pcnet32_access *a = &lp->a;
++	struct pcnet32_access *a = lp->a;
+ 	ulong ioaddr = dev->base_addr;
+ 	unsigned long flags;
+ 
+@@ -1466,9 +1466,9 @@ static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ 		for (j = 0; j < PCNET32_MAX_PHYS; j++) {
+ 			if (lp->phymask & (1 << j)) {
+ 				for (i = 0; i < PCNET32_REGS_PER_PHY; i++) {
+-					lp->a.write_bcr(ioaddr, 33,
++					lp->a->write_bcr(ioaddr, 33,
+ 							(j << 5) | i);
+-					*buff++ = lp->a.read_bcr(ioaddr, 34);
++					*buff++ = lp->a->read_bcr(ioaddr, 34);
+ 				}
+ 			}
+ 		}
+@@ -1858,7 +1858,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
+ 	    ((cards_found >= MAX_UNITS) || full_duplex[cards_found]))
+ 		lp->options |= PCNET32_PORT_FD;
+ 
+-	lp->a = *a;
++	lp->a = a;
+ 
+ 	/* prior to register_netdev, dev->name is not yet correct */
+ 	if (pcnet32_alloc_ring(dev, pci_name(lp->pci_dev))) {
+@@ -1917,7 +1917,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
+ 	if (lp->mii) {
+ 		/* lp->phycount and lp->phymask are set to 0 by memset above */
+ 
+-		lp->mii_if.phy_id = ((lp->a.read_bcr(ioaddr, 33)) >> 5) & 0x1f;
++		lp->mii_if.phy_id = ((lp->a->read_bcr(ioaddr, 33)) >> 5) & 0x1f;
+ 		/* scan for PHYs */
+ 		for (i = 0; i < PCNET32_MAX_PHYS; i++) {
+ 			unsigned short id1, id2;
+@@ -1938,7 +1938,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
+ 				       "Found PHY %04x:%04x at address %d.\n",
+ 				       id1, id2, i);
+ 		}
+-		lp->a.write_bcr(ioaddr, 33, (lp->mii_if.phy_id) << 5);
++		lp->a->write_bcr(ioaddr, 33, (lp->mii_if.phy_id) << 5);
+ 		if (lp->phycount > 1) {
+ 			lp->options |= PCNET32_PORT_MII;
+ 		}
+@@ -2109,10 +2109,10 @@ static int pcnet32_open(struct net_device *dev)
+ 	}
+ 
+ 	/* Reset the PCNET32 */
+-	lp->a.reset(ioaddr);
++	lp->a->reset(ioaddr);
+ 
+ 	/* switch pcnet32 to 32bit mode */
+-	lp->a.write_bcr(ioaddr, 20, 2);
++	lp->a->write_bcr(ioaddr, 20, 2);
+ 
+ 	if (netif_msg_ifup(lp))
+ 		printk(KERN_DEBUG
+@@ -2122,14 +2122,14 @@ static int pcnet32_open(struct net_device *dev)
+ 		       (u32) (lp->init_dma_addr));
+ 
+ 	/* set/reset autoselect bit */
+-	val = lp->a.read_bcr(ioaddr, 2) & ~2;
++	val = lp->a->read_bcr(ioaddr, 2) & ~2;
+ 	if (lp->options & PCNET32_PORT_ASEL)
+ 		val |= 2;
+-	lp->a.write_bcr(ioaddr, 2, val);
++	lp->a->write_bcr(ioaddr, 2, val);
+ 
+ 	/* handle full duplex setting */
+ 	if (lp->mii_if.full_duplex) {
+-		val = lp->a.read_bcr(ioaddr, 9) & ~3;
++		val = lp->a->read_bcr(ioaddr, 9) & ~3;
+ 		if (lp->options & PCNET32_PORT_FD) {
+ 			val |= 1;
+ 			if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI))
+@@ -2139,14 +2139,14 @@ static int pcnet32_open(struct net_device *dev)
+ 			if (lp->chip_version == 0x2627)
+ 				val |= 3;
+ 		}
+-		lp->a.write_bcr(ioaddr, 9, val);
++		lp->a->write_bcr(ioaddr, 9, val);
+ 	}
+ 
+ 	/* set/reset GPSI bit in test register */
+-	val = lp->a.read_csr(ioaddr, 124) & ~0x10;
++	val = lp->a->read_csr(ioaddr, 124) & ~0x10;
+ 	if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI)
+ 		val |= 0x10;
+-	lp->a.write_csr(ioaddr, 124, val);
++	lp->a->write_csr(ioaddr, 124, val);
+ 
+ 	/* Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not negotiate */
+ 	if (pdev && pdev->subsystem_vendor == PCI_VENDOR_ID_AT &&
+@@ -2167,24 +2167,24 @@ static int pcnet32_open(struct net_device *dev)
+ 		 * duplex, and/or enable auto negotiation, and clear DANAS
+ 		 */
+ 		if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) {
+-			lp->a.write_bcr(ioaddr, 32,
+-					lp->a.read_bcr(ioaddr, 32) | 0x0080);
++			lp->a->write_bcr(ioaddr, 32,
++					lp->a->read_bcr(ioaddr, 32) | 0x0080);
+ 			/* disable Auto Negotiation, set 10Mpbs, HD */
+-			val = lp->a.read_bcr(ioaddr, 32) & ~0xb8;
++			val = lp->a->read_bcr(ioaddr, 32) & ~0xb8;
+ 			if (lp->options & PCNET32_PORT_FD)
+ 				val |= 0x10;
+ 			if (lp->options & PCNET32_PORT_100)
+ 				val |= 0x08;
+-			lp->a.write_bcr(ioaddr, 32, val);
++			lp->a->write_bcr(ioaddr, 32, val);
+ 		} else {
+ 			if (lp->options & PCNET32_PORT_ASEL) {
+-				lp->a.write_bcr(ioaddr, 32,
+-						lp->a.read_bcr(ioaddr,
++				lp->a->write_bcr(ioaddr, 32,
++						lp->a->read_bcr(ioaddr,
+ 							       32) | 0x0080);
+ 				/* enable auto negotiate, setup, disable fd */
+-				val = lp->a.read_bcr(ioaddr, 32) & ~0x98;
++				val = lp->a->read_bcr(ioaddr, 32) & ~0x98;
+ 				val |= 0x20;
+-				lp->a.write_bcr(ioaddr, 32, val);
++				lp->a->write_bcr(ioaddr, 32, val);
+ 			}
+ 		}
+ 	} else {
+@@ -2197,10 +2197,10 @@ static int pcnet32_open(struct net_device *dev)
+ 		 * There is really no good other way to handle multiple PHYs
+ 		 * other than turning off all automatics
+ 		 */
+-		val = lp->a.read_bcr(ioaddr, 2);
+-		lp->a.write_bcr(ioaddr, 2, val & ~2);
+-		val = lp->a.read_bcr(ioaddr, 32);
+-		lp->a.write_bcr(ioaddr, 32, val & ~(1 << 7));	/* stop MII manager */
++		val = lp->a->read_bcr(ioaddr, 2);
++		lp->a->write_bcr(ioaddr, 2, val & ~2);
++		val = lp->a->read_bcr(ioaddr, 32);
++		lp->a->write_bcr(ioaddr, 32, val & ~(1 << 7));	/* stop MII manager */
+ 
+ 		if (!(lp->options & PCNET32_PORT_ASEL)) {
+ 			/* setup ecmd */
+@@ -2210,7 +2210,7 @@ static int pcnet32_open(struct net_device *dev)
+ 			ecmd.speed =
+ 			    lp->
+ 			    options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10;
+-			bcr9 = lp->a.read_bcr(ioaddr, 9);
++			bcr9 = lp->a->read_bcr(ioaddr, 9);
+ 
+ 			if (lp->options & PCNET32_PORT_FD) {
+ 				ecmd.duplex = DUPLEX_FULL;
+@@ -2219,7 +2219,7 @@ static int pcnet32_open(struct net_device *dev)
+ 				ecmd.duplex = DUPLEX_HALF;
+ 				bcr9 |= ~(1 << 0);
+ 			}
+-			lp->a.write_bcr(ioaddr, 9, bcr9);
++			lp->a->write_bcr(ioaddr, 9, bcr9);
+ 		}
+ 
+ 		for (i = 0; i < PCNET32_MAX_PHYS; i++) {
+@@ -2252,9 +2252,9 @@ static int pcnet32_open(struct net_device *dev)
+ 
+ #ifdef DO_DXSUFLO
+ 	if (lp->dxsuflo) {	/* Disable transmit stop on underflow */
+-		val = lp->a.read_csr(ioaddr, CSR3);
++		val = lp->a->read_csr(ioaddr, CSR3);
+ 		val |= 0x40;
+-		lp->a.write_csr(ioaddr, CSR3, val);
++		lp->a->write_csr(ioaddr, CSR3, val);
+ 	}
+ #endif
+ 
+@@ -2270,11 +2270,11 @@ static int pcnet32_open(struct net_device *dev)
+ 	napi_enable(&lp->napi);
+ 
+ 	/* Re-initialize the PCNET32, and start it when done. */
+-	lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
+-	lp->a.write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
++	lp->a->write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
++	lp->a->write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
+ 
+-	lp->a.write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_INIT);
++	lp->a->write_csr(ioaddr, CSR4, 0x0915);	/* auto tx pad */
++	lp->a->write_csr(ioaddr, CSR0, CSR0_INIT);
+ 
+ 	netif_start_queue(dev);
+ 
+@@ -2286,20 +2286,20 @@ static int pcnet32_open(struct net_device *dev)
+ 
+ 	i = 0;
+ 	while (i++ < 100)
+-		if (lp->a.read_csr(ioaddr, CSR0) & CSR0_IDON)
++		if (lp->a->read_csr(ioaddr, CSR0) & CSR0_IDON)
+ 			break;
+ 	/*
+ 	 * We used to clear the InitDone bit, 0x0100, here but Mark Stockton
+ 	 * reports that doing so triggers a bug in the '974.
+ 	 */
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_NORMAL);
++	lp->a->write_csr(ioaddr, CSR0, CSR0_NORMAL);
+ 
+ 	if (netif_msg_ifup(lp))
+ 		printk(KERN_DEBUG
+ 		       "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n",
+ 		       dev->name, i,
+ 		       (u32) (lp->init_dma_addr),
+-		       lp->a.read_csr(ioaddr, CSR0));
++		       lp->a->read_csr(ioaddr, CSR0));
+ 
+ 	spin_unlock_irqrestore(&lp->lock, flags);
+ 
+@@ -2313,7 +2313,7 @@ static int pcnet32_open(struct net_device *dev)
+ 	 * Switch back to 16bit mode to avoid problems with dumb
+ 	 * DOS packet driver after a warm reboot
+ 	 */
+-	lp->a.write_bcr(ioaddr, 20, 4);
++	lp->a->write_bcr(ioaddr, 20, 4);
+ 
+       err_free_irq:
+ 	spin_unlock_irqrestore(&lp->lock, flags);
+@@ -2420,7 +2420,7 @@ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits)
+ 
+ 	/* wait for stop */
+ 	for (i = 0; i < 100; i++)
+-		if (lp->a.read_csr(ioaddr, CSR0) & CSR0_STOP)
++		if (lp->a->read_csr(ioaddr, CSR0) & CSR0_STOP)
+ 			break;
+ 
+ 	if (i >= 100 && netif_msg_drv(lp))
+@@ -2433,13 +2433,13 @@ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits)
+ 		return;
+ 
+ 	/* ReInit Ring */
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_INIT);
++	lp->a->write_csr(ioaddr, CSR0, CSR0_INIT);
+ 	i = 0;
+ 	while (i++ < 1000)
+-		if (lp->a.read_csr(ioaddr, CSR0) & CSR0_IDON)
++		if (lp->a->read_csr(ioaddr, CSR0) & CSR0_IDON)
+ 			break;
+ 
+-	lp->a.write_csr(ioaddr, CSR0, csr0_bits);
++	lp->a->write_csr(ioaddr, CSR0, csr0_bits);
+ }
+ 
+ static void pcnet32_tx_timeout(struct net_device *dev)
+@@ -2452,8 +2452,8 @@ static void pcnet32_tx_timeout(struct net_device *dev)
+ 	if (pcnet32_debug & NETIF_MSG_DRV)
+ 		printk(KERN_ERR
+ 		       "%s: transmit timed out, status %4.4x, resetting.\n",
+-		       dev->name, lp->a.read_csr(ioaddr, CSR0));
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
++		       dev->name, lp->a->read_csr(ioaddr, CSR0));
++	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
+ 	dev->stats.tx_errors++;
+ 	if (netif_msg_tx_err(lp)) {
+ 		int i;
+@@ -2497,7 +2497,7 @@ static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb,
+ 	if (netif_msg_tx_queued(lp)) {
+ 		printk(KERN_DEBUG
+ 		       "%s: pcnet32_start_xmit() called, csr0 %4.4x.\n",
+-		       dev->name, lp->a.read_csr(ioaddr, CSR0));
++		       dev->name, lp->a->read_csr(ioaddr, CSR0));
+ 	}
+ 
+ 	/* Default status -- will not enable Successful-TxDone
+@@ -2528,7 +2528,7 @@ static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb,
+ 	dev->stats.tx_bytes += skb->len;
+ 
+ 	/* Trigger an immediate send poll. */
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
++	lp->a->write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
+ 
+ 	dev->trans_start = jiffies;
+ 
+@@ -2555,18 +2555,18 @@ pcnet32_interrupt(int irq, void *dev_id)
+ 
+ 	spin_lock(&lp->lock);
+ 
+-	csr0 = lp->a.read_csr(ioaddr, CSR0);
++	csr0 = lp->a->read_csr(ioaddr, CSR0);
+ 	while ((csr0 & 0x8f00) && --boguscnt >= 0) {
+ 		if (csr0 == 0xffff) {
+ 			break;	/* PCMCIA remove happened */
+ 		}
+ 		/* Acknowledge all of the current interrupt sources ASAP. */
+-		lp->a.write_csr(ioaddr, CSR0, csr0 & ~0x004f);
++		lp->a->write_csr(ioaddr, CSR0, csr0 & ~0x004f);
+ 
+ 		if (netif_msg_intr(lp))
+ 			printk(KERN_DEBUG
+ 			       "%s: interrupt  csr0=%#2.2x new csr=%#2.2x.\n",
+-			       dev->name, csr0, lp->a.read_csr(ioaddr, CSR0));
++			       dev->name, csr0, lp->a->read_csr(ioaddr, CSR0));
+ 
+ 		/* Log misc errors. */
+ 		if (csr0 & 0x4000)
+@@ -2595,19 +2595,19 @@ pcnet32_interrupt(int irq, void *dev_id)
+ 		if (napi_schedule_prep(&lp->napi)) {
+ 			u16 val;
+ 			/* set interrupt masks */
+-			val = lp->a.read_csr(ioaddr, CSR3);
++			val = lp->a->read_csr(ioaddr, CSR3);
+ 			val |= 0x5f00;
+-			lp->a.write_csr(ioaddr, CSR3, val);
++			lp->a->write_csr(ioaddr, CSR3, val);
+ 
+ 			__napi_schedule(&lp->napi);
+ 			break;
+ 		}
+-		csr0 = lp->a.read_csr(ioaddr, CSR0);
++		csr0 = lp->a->read_csr(ioaddr, CSR0);
+ 	}
+ 
+ 	if (netif_msg_intr(lp))
+ 		printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n",
+-		       dev->name, lp->a.read_csr(ioaddr, CSR0));
++		       dev->name, lp->a->read_csr(ioaddr, CSR0));
+ 
+ 	spin_unlock(&lp->lock);
+ 
+@@ -2627,21 +2627,21 @@ static int pcnet32_close(struct net_device *dev)
+ 
+ 	spin_lock_irqsave(&lp->lock, flags);
+ 
+-	dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
++	dev->stats.rx_missed_errors = lp->a->read_csr(ioaddr, 112);
+ 
+ 	if (netif_msg_ifdown(lp))
+ 		printk(KERN_DEBUG
+ 		       "%s: Shutting down ethercard, status was %2.2x.\n",
+-		       dev->name, lp->a.read_csr(ioaddr, CSR0));
++		       dev->name, lp->a->read_csr(ioaddr, CSR0));
+ 
+ 	/* We stop the PCNET32 here -- it occasionally polls memory if we don't. */
+-	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
++	lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
+ 
+ 	/*
+ 	 * Switch back to 16bit mode to avoid problems with dumb
+ 	 * DOS packet driver after a warm reboot
+ 	 */
+-	lp->a.write_bcr(ioaddr, 20, 4);
++	lp->a->write_bcr(ioaddr, 20, 4);
+ 
+ 	spin_unlock_irqrestore(&lp->lock, flags);
+ 
+@@ -2664,7 +2664,7 @@ static struct net_device_stats *pcnet32_get_stats(struct net_device *dev)
+ 	unsigned long flags;
+ 
+ 	spin_lock_irqsave(&lp->lock, flags);
+-	dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
++	dev->stats.rx_missed_errors = lp->a->read_csr(ioaddr, 112);
+ 	spin_unlock_irqrestore(&lp->lock, flags);
+ 
+ 	return &dev->stats;
+@@ -2686,10 +2686,10 @@ static void pcnet32_load_multicast(struct net_device *dev)
+ 	if (dev->flags & IFF_ALLMULTI) {
+ 		ib->filter[0] = cpu_to_le32(~0U);
+ 		ib->filter[1] = cpu_to_le32(~0U);
+-		lp->a.write_csr(ioaddr, PCNET32_MC_FILTER, 0xffff);
+-		lp->a.write_csr(ioaddr, PCNET32_MC_FILTER+1, 0xffff);
+-		lp->a.write_csr(ioaddr, PCNET32_MC_FILTER+2, 0xffff);
+-		lp->a.write_csr(ioaddr, PCNET32_MC_FILTER+3, 0xffff);
++		lp->a->write_csr(ioaddr, PCNET32_MC_FILTER, 0xffff);
++		lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+1, 0xffff);
++		lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+2, 0xffff);
++		lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+3, 0xffff);
+ 		return;
+ 	}
+ 	/* clear the multicast filter */
+@@ -2710,7 +2710,7 @@ static void pcnet32_load_multicast(struct net_device *dev)
+ 		mcast_table[crc >> 4] |= cpu_to_le16(1 << (crc & 0xf));
+ 	}
+ 	for (i = 0; i < 4; i++)
+-		lp->a.write_csr(ioaddr, PCNET32_MC_FILTER + i,
++		lp->a->write_csr(ioaddr, PCNET32_MC_FILTER + i,
+ 				le16_to_cpu(mcast_table[i]));
+ 	return;
+ }
+@@ -2726,7 +2726,7 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
+ 
+ 	spin_lock_irqsave(&lp->lock, flags);
+ 	suspended = pcnet32_suspend(dev, &flags, 0);
+-	csr15 = lp->a.read_csr(ioaddr, CSR15);
++	csr15 = lp->a->read_csr(ioaddr, CSR15);
+ 	if (dev->flags & IFF_PROMISC) {
+ 		/* Log any net taps. */
+ 		if (netif_msg_hw(lp))
+@@ -2735,21 +2735,21 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
+ 		lp->init_block->mode =
+ 		    cpu_to_le16(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) <<
+ 				7);
+-		lp->a.write_csr(ioaddr, CSR15, csr15 | 0x8000);
++		lp->a->write_csr(ioaddr, CSR15, csr15 | 0x8000);
+ 	} else {
+ 		lp->init_block->mode =
+ 		    cpu_to_le16((lp->options & PCNET32_PORT_PORTSEL) << 7);
+-		lp->a.write_csr(ioaddr, CSR15, csr15 & 0x7fff);
++		lp->a->write_csr(ioaddr, CSR15, csr15 & 0x7fff);
+ 		pcnet32_load_multicast(dev);
+ 	}
+ 
+ 	if (suspended) {
+ 		int csr5;
+ 		/* clear SUSPEND (SPND) - CSR5 bit 0 */
+-		csr5 = lp->a.read_csr(ioaddr, CSR5);
+-		lp->a.write_csr(ioaddr, CSR5, csr5 & (~CSR5_SUSPEND));
++		csr5 = lp->a->read_csr(ioaddr, CSR5);
++		lp->a->write_csr(ioaddr, CSR5, csr5 & (~CSR5_SUSPEND));
+ 	} else {
+-		lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
++		lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
+ 		pcnet32_restart(dev, CSR0_NORMAL);
+ 		netif_wake_queue(dev);
+ 	}
+@@ -2767,8 +2767,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
+ 	if (!lp->mii)
+ 		return 0;
+ 
+-	lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
+-	val_out = lp->a.read_bcr(ioaddr, 34);
++	lp->a->write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
++	val_out = lp->a->read_bcr(ioaddr, 34);
+ 
+ 	return val_out;
+ }
+@@ -2782,8 +2782,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
+ 	if (!lp->mii)
+ 		return;
+ 
+-	lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
+-	lp->a.write_bcr(ioaddr, 34, val);
++	lp->a->write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
++	lp->a->write_bcr(ioaddr, 34, val);
+ }
+ 
+ static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+@@ -2862,7 +2862,7 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
+ 		curr_link = mii_link_ok(&lp->mii_if);
+ 	} else {
+ 		ulong ioaddr = dev->base_addr;	/* card base I/O address */
+-		curr_link = (lp->a.read_bcr(ioaddr, 4) != 0xc0);
++		curr_link = (lp->a->read_bcr(ioaddr, 4) != 0xc0);
+ 	}
+ 	if (!curr_link) {
+ 		if (prev_link || verbose) {
+@@ -2887,13 +2887,13 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
+ 				       (ecmd.duplex ==
+ 					DUPLEX_FULL) ? "full" : "half");
+ 			}
+-			bcr9 = lp->a.read_bcr(dev->base_addr, 9);
++			bcr9 = lp->a->read_bcr(dev->base_addr, 9);
+ 			if ((bcr9 & (1 << 0)) != lp->mii_if.full_duplex) {
+ 				if (lp->mii_if.full_duplex)
+ 					bcr9 |= (1 << 0);
+ 				else
+ 					bcr9 &= ~(1 << 0);
+-				lp->a.write_bcr(dev->base_addr, 9, bcr9);
++				lp->a->write_bcr(dev->base_addr, 9, bcr9);
+ 			}
+ 		} else {
+ 			if (netif_msg_link(lp))
+diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
+index 7cc9898..6eb50d3 100644
+--- a/drivers/net/sis190.c
++++ b/drivers/net/sis190.c
+@@ -1598,7 +1598,7 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
+ static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
+ 						  struct net_device *dev)
+ {
+-	static const u16 __devinitdata ids[] = { 0x0965, 0x0966, 0x0968 };
++	static const u16 __devinitconst ids[] = { 0x0965, 0x0966, 0x0968 };
+ 	struct sis190_private *tp = netdev_priv(dev);
+ 	struct pci_dev *isa_bridge;
+ 	u8 reg, tmp8;
+diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
+index e13685a..60c948c 100644
+--- a/drivers/net/sundance.c
++++ b/drivers/net/sundance.c
+@@ -225,7 +225,7 @@ enum {
+ struct pci_id_info {
+         const char *name;
+ };
+-static const struct pci_id_info pci_id_tbl[] __devinitdata = {
++static const struct pci_id_info pci_id_tbl[] __devinitconst = {
+ 	{"D-Link DFE-550TX FAST Ethernet Adapter"},
+ 	{"D-Link DFE-550FX 100Mbps Fiber-optics Adapter"},
+ 	{"D-Link DFE-580TX 4 port Server Adapter"},
+diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
+index 529f55a..cccaa18 100644
+--- a/drivers/net/tg3.h
++++ b/drivers/net/tg3.h
+@@ -95,6 +95,7 @@
+ #define  CHIPREV_ID_5750_A0		 0x4000
+ #define  CHIPREV_ID_5750_A1		 0x4001
+ #define  CHIPREV_ID_5750_A3		 0x4003
++#define  CHIPREV_ID_5750_C1		 0x4201
+ #define  CHIPREV_ID_5750_C2		 0x4202
+ #define  CHIPREV_ID_5752_A0_HW		 0x5000
+ #define  CHIPREV_ID_5752_A0		 0x6000
+diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
+index b9db1b5..720f9ce 100644
+--- a/drivers/net/tokenring/abyss.c
++++ b/drivers/net/tokenring/abyss.c
+@@ -451,10 +451,12 @@ static struct pci_driver abyss_driver = {
+ 
+ static int __init abyss_init (void)
+ {
+-	abyss_netdev_ops = tms380tr_netdev_ops;
++	pax_open_kernel();
++	memcpy((void *)&abyss_netdev_ops, &tms380tr_netdev_ops, sizeof(tms380tr_netdev_ops));
+ 
+-	abyss_netdev_ops.ndo_open = abyss_open;
+-	abyss_netdev_ops.ndo_stop = abyss_close;
++	*(void **)&abyss_netdev_ops.ndo_open = abyss_open;
++	*(void **)&abyss_netdev_ops.ndo_stop = abyss_close;
++	pax_close_kernel();
+ 
+ 	return pci_register_driver(&abyss_driver);
+ }
+diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
+index 456f8bf..373e56d 100644
+--- a/drivers/net/tokenring/madgemc.c
++++ b/drivers/net/tokenring/madgemc.c
+@@ -755,9 +755,11 @@ static struct mca_driver madgemc_driver = {
+ 
+ static int __init madgemc_init (void)
+ {
+-	madgemc_netdev_ops = tms380tr_netdev_ops;
+-	madgemc_netdev_ops.ndo_open = madgemc_open;
+-	madgemc_netdev_ops.ndo_stop = madgemc_close;
++	pax_open_kernel();
++	memcpy((void *)&madgemc_netdev_ops, &tms380tr_netdev_ops, sizeof(tms380tr_netdev_ops));
++	*(void **)&madgemc_netdev_ops.ndo_open = madgemc_open;
++	*(void **)&madgemc_netdev_ops.ndo_stop = madgemc_close;
++	pax_close_kernel();
+ 
+ 	return mca_register_driver (&madgemc_driver);
+ }
+diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
+index 16e8783..925bd49 100644
+--- a/drivers/net/tokenring/proteon.c
++++ b/drivers/net/tokenring/proteon.c
+@@ -353,9 +353,11 @@ static int __init proteon_init(void)
+ 	struct platform_device *pdev;
+ 	int i, num = 0, err = 0;
+ 
+-	proteon_netdev_ops = tms380tr_netdev_ops;
+-	proteon_netdev_ops.ndo_open = proteon_open;
+-	proteon_netdev_ops.ndo_stop = tms380tr_close;
++	pax_open_kernel();
++	memcpy((void *)&proteon_netdev_ops, &tms380tr_netdev_ops, sizeof(tms380tr_netdev_ops));
++	*(void **)&proteon_netdev_ops.ndo_open = proteon_open;
++	*(void **)&proteon_netdev_ops.ndo_stop = tms380tr_close;
++	pax_close_kernel();
+ 
+ 	err = platform_driver_register(&proteon_driver);
+ 	if (err)
+diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
+index 46db5c5..37c1536 100644
+--- a/drivers/net/tokenring/skisa.c
++++ b/drivers/net/tokenring/skisa.c
+@@ -363,9 +363,11 @@ static int __init sk_isa_init(void)
+ 	struct platform_device *pdev;
+ 	int i, num = 0, err = 0;
+ 
+-	sk_isa_netdev_ops = tms380tr_netdev_ops;
+-	sk_isa_netdev_ops.ndo_open = sk_isa_open;
+-	sk_isa_netdev_ops.ndo_stop = tms380tr_close;
++	pax_open_kernel();
++	memcpy((void *)&sk_isa_netdev_ops, &tms380tr_netdev_ops, sizeof(tms380tr_netdev_ops));
++	*(void **)&sk_isa_netdev_ops.ndo_open = sk_isa_open;
++	*(void **)&sk_isa_netdev_ops.ndo_stop = tms380tr_close;
++	pax_close_kernel();
+ 
+ 	err = platform_driver_register(&sk_isa_driver);
+ 	if (err)
+diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
+index 74e5ba4..5cf6bc9 100644
+--- a/drivers/net/tulip/de2104x.c
++++ b/drivers/net/tulip/de2104x.c
+@@ -1785,6 +1785,8 @@ static void __devinit de21041_get_srom_info (struct de_private *de)
+ 	struct de_srom_info_leaf *il;
+ 	void *bufp;
+ 
++	pax_track_stack();
++
+ 	/* download entire eeprom */
+ 	for (i = 0; i < DE_EEPROM_WORDS; i++)
+ 		((__le16 *)ee_data)[i] =
+diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
+index a8349b7..90f9dfe 100644
+--- a/drivers/net/tulip/de4x5.c
++++ b/drivers/net/tulip/de4x5.c
+@@ -5472,7 +5472,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ 	for (i=0; i<ETH_ALEN; i++) {
+ 	    tmp.addr[i] = dev->dev_addr[i];
+ 	}
+-	if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
++	if (ioc->len > sizeof tmp.addr || copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
+ 	break;
+ 
+     case DE4X5_SET_HWADDR:           /* Set the hardware address */
+@@ -5512,7 +5512,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ 	spin_lock_irqsave(&lp->lock, flags);
+ 	memcpy(&statbuf, &lp->pktStats, ioc->len);
+ 	spin_unlock_irqrestore(&lp->lock, flags);
+-	if (copy_to_user(ioc->data, &statbuf, ioc->len))
++	if (ioc->len > sizeof statbuf || copy_to_user(ioc->data, &statbuf, ioc->len))
+ 		return -EFAULT;
+ 	break;
+     }
+diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c
+index 391acd3..56d11cd 100644
+--- a/drivers/net/tulip/eeprom.c
++++ b/drivers/net/tulip/eeprom.c
+@@ -80,7 +80,7 @@ static struct eeprom_fixup eeprom_fixups[] __devinitdata = {
+   {NULL}};
+ 
+ 
+-static const char *block_name[] __devinitdata = {
++static const char *block_name[] __devinitconst = {
+ 	"21140 non-MII",
+ 	"21140 MII PHY",
+ 	"21142 Serial PHY",
+diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
+index b38d3b7..b1cff23 100644
+--- a/drivers/net/tulip/winbond-840.c
++++ b/drivers/net/tulip/winbond-840.c
+@@ -235,7 +235,7 @@ struct pci_id_info {
+         int drv_flags;		/* Driver use, intended as capability flags. */
+ };
+ 
+-static const struct pci_id_info pci_id_tbl[] __devinitdata = {
++static const struct pci_id_info pci_id_tbl[] __devinitconst = {
+ 	{ 				/* Sometime a Level-One switch card. */
+ 	  "Winbond W89c840",	CanHaveMII | HasBrokenTx | FDXOnNoMII},
+ 	{ "Winbond W89c840",	CanHaveMII | HasBrokenTx},
+diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
+index f450bc9..2b747c8 100644
+--- a/drivers/net/usb/hso.c
++++ b/drivers/net/usb/hso.c
+@@ -71,7 +71,7 @@
+ #include <asm/byteorder.h>
+ #include <linux/serial_core.h>
+ #include <linux/serial.h>
+-
++#include <asm/local.h>
+ 
+ #define DRIVER_VERSION			"1.2"
+ #define MOD_AUTHOR			"Option Wireless"
+@@ -258,7 +258,7 @@ struct hso_serial {
+ 
+ 	/* from usb_serial_port */
+ 	struct tty_struct *tty;
+-	int open_count;
++	local_t open_count;
+ 	spinlock_t serial_lock;
+ 
+ 	int (*write_data) (struct hso_serial *serial);
+@@ -1180,7 +1180,7 @@ static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial)
+ 	struct urb *urb;
+ 
+ 	urb = serial->rx_urb[0];
+-	if (serial->open_count > 0) {
++	if (local_read(&serial->open_count) > 0) {
+ 		count = put_rxbuf_data(urb, serial);
+ 		if (count == -1)
+ 			return;
+@@ -1216,7 +1216,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb)
+ 	DUMP1(urb->transfer_buffer, urb->actual_length);
+ 
+ 	/* Anyone listening? */
+-	if (serial->open_count == 0)
++	if (local_read(&serial->open_count) == 0)
+ 		return;
+ 
+ 	if (status == 0) {
+@@ -1311,8 +1311,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
+ 	spin_unlock_irq(&serial->serial_lock);
+ 
+ 	/* check for port already opened, if not set the termios */
+-	serial->open_count++;
+-	if (serial->open_count == 1) {
++	if (local_inc_return(&serial->open_count) == 1) {
+ 		tty->low_latency = 1;
+ 		serial->rx_state = RX_IDLE;
+ 		/* Force default termio settings */
+@@ -1325,7 +1324,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
+ 		result = hso_start_serial_device(serial->parent, GFP_KERNEL);
+ 		if (result) {
+ 			hso_stop_serial_device(serial->parent);
+-			serial->open_count--;
++			local_dec(&serial->open_count);
+ 			kref_put(&serial->parent->ref, hso_serial_ref_free);
+ 		}
+ 	} else {
+@@ -1362,10 +1361,10 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
+ 
+ 	/* reset the rts and dtr */
+ 	/* do the actual close */
+-	serial->open_count--;
++	local_dec(&serial->open_count);
+ 
+-	if (serial->open_count <= 0) {
+-		serial->open_count = 0;
++	if (local_read(&serial->open_count) <= 0) {
++		local_set(&serial->open_count,  0);
+ 		spin_lock_irq(&serial->serial_lock);
+ 		if (serial->tty == tty) {
+ 			serial->tty->driver_data = NULL;
+@@ -1447,7 +1446,7 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)
+ 
+ 	/* the actual setup */
+ 	spin_lock_irqsave(&serial->serial_lock, flags);
+-	if (serial->open_count)
++	if (local_read(&serial->open_count))
+ 		_hso_serial_set_termios(tty, old);
+ 	else
+ 		tty->termios = old;
+@@ -3097,7 +3096,7 @@ static int hso_resume(struct usb_interface *iface)
+ 	/* Start all serial ports */
+ 	for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
+ 		if (serial_table[i] && (serial_table[i]->interface == iface)) {
+-			if (dev2ser(serial_table[i])->open_count) {
++			if (local_read(&dev2ser(serial_table[i])->open_count)) {
+ 				result =
+ 				    hso_start_serial_device(serial_table[i], GFP_NOIO);
+ 				hso_kick_transmit(dev2ser(serial_table[i]));
+diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
+index 3e94f0c..ffdd926 100644
+--- a/drivers/net/vxge/vxge-config.h
++++ b/drivers/net/vxge/vxge-config.h
+@@ -474,7 +474,7 @@ struct vxge_hw_uld_cbs {
+ 	void (*link_down)(struct __vxge_hw_device *devh);
+ 	void (*crit_err)(struct __vxge_hw_device *devh,
+ 			enum vxge_hw_event type, u64 ext_data);
+-};
++} __no_const;
+ 
+ /*
+  * struct __vxge_hw_blockpool_entry - Block private data structure
+diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
+index 068d7a9..35293de 100644
+--- a/drivers/net/vxge/vxge-main.c
++++ b/drivers/net/vxge/vxge-main.c
+@@ -93,6 +93,8 @@ static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo)
+ 	struct sk_buff *completed[NR_SKB_COMPLETED];
+ 	int more;
+ 
++	pax_track_stack();
++
+ 	do {
+ 		more = 0;
+ 		skb_ptr = completed;
+@@ -1779,6 +1781,8 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
+ 	u8 mtable[256] = {0}; /* CPU to vpath mapping  */
+ 	int index;
+ 
++	pax_track_stack();
++
+ 	/*
+ 	 * Filling
+ 	 * 	- itable with bucket numbers
+diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h
+index 461742b..81be42e 100644
+--- a/drivers/net/vxge/vxge-traffic.h
++++ b/drivers/net/vxge/vxge-traffic.h
+@@ -2123,7 +2123,7 @@ struct vxge_hw_mempool_cbs {
+ 			struct vxge_hw_mempool_dma	*dma_object,
+ 			u32			index,
+ 			u32			is_last);
+-};
++} __no_const;
+ 
+ void
+ __vxge_hw_mempool_destroy(
+diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
+index cd8cb95..4153b79 100644
+--- a/drivers/net/wan/cycx_x25.c
++++ b/drivers/net/wan/cycx_x25.c
+@@ -1017,6 +1017,8 @@ static void hex_dump(char *msg, unsigned char *p, int len)
+ 	unsigned char hex[1024],
+ 	    	* phex = hex;
+ 
++	pax_track_stack();
++
+ 	if (len >= (sizeof(hex) / 2))
+ 		len = (sizeof(hex) / 2) - 1;
+ 
+diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
+index aa9248f..a4e3c3b 100644
+--- a/drivers/net/wan/hdlc_x25.c
++++ b/drivers/net/wan/hdlc_x25.c
+@@ -136,16 +136,16 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev)
+ 
+ static int x25_open(struct net_device *dev)
+ {
+-	struct lapb_register_struct cb;
++	static struct lapb_register_struct cb = {
++		.connect_confirmation = x25_connected,
++		.connect_indication = x25_connected,
++		.disconnect_confirmation = x25_disconnected,
++		.disconnect_indication = x25_disconnected,
++		.data_indication = x25_data_indication,
++		.data_transmit = x25_data_transmit
++	};
+ 	int result;
+ 
+-	cb.connect_confirmation = x25_connected;
+-	cb.connect_indication = x25_connected;
+-	cb.disconnect_confirmation = x25_disconnected;
+-	cb.disconnect_indication = x25_disconnected;
+-	cb.data_indication = x25_data_indication;
+-	cb.data_transmit = x25_data_transmit;
+-
+ 	result = lapb_register(dev, &cb);
+ 	if (result != LAPB_OK)
+ 		return result;
+diff --git a/drivers/net/wimax/i2400m/usb-fw.c b/drivers/net/wimax/i2400m/usb-fw.c
+index 5ad287c..783b020 100644
+--- a/drivers/net/wimax/i2400m/usb-fw.c
++++ b/drivers/net/wimax/i2400m/usb-fw.c
+@@ -263,6 +263,8 @@ ssize_t i2400mu_bus_bm_wait_for_ack(struct i2400m *i2400m,
+ 	int do_autopm = 1;
+ 	DECLARE_COMPLETION_ONSTACK(notif_completion);
+ 
++	pax_track_stack();
++
+ 	d_fnstart(8, dev, "(i2400m %p ack %p size %zu)\n",
+ 		  i2400m, ack, ack_size);
+ 	BUG_ON(_ack == i2400m->bm_ack_buf);
+diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
+index 6c26840..62c97c3 100644
+--- a/drivers/net/wireless/airo.c
++++ b/drivers/net/wireless/airo.c
+@@ -3003,6 +3003,8 @@ static void airo_process_scan_results (struct airo_info *ai) {
+ 	BSSListElement * loop_net;
+ 	BSSListElement * tmp_net;
+ 
++	pax_track_stack();
++
+ 	/* Blow away current list of scan results */
+ 	list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) {
+ 		list_move_tail (&loop_net->list, &ai->network_free_list);
+@@ -3783,6 +3785,8 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
+ 	WepKeyRid wkr;
+ 	int rc;
+ 
++	pax_track_stack();
++
+ 	memset( &mySsid, 0, sizeof( mySsid ) );
+ 	kfree (ai->flash);
+ 	ai->flash = NULL;
+@@ -4758,6 +4762,8 @@ static int proc_stats_rid_open( struct inode *inode,
+ 	__le32 *vals = stats.vals;
+ 	int len;
+ 
++	pax_track_stack();
++
+ 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+ 		return -ENOMEM;
+ 	data = (struct proc_data *)file->private_data;
+@@ -5487,6 +5493,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
+ 	/* If doLoseSync is not 1, we won't do a Lose Sync */
+ 	int doLoseSync = -1;
+ 
++	pax_track_stack();
++
+ 	if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
+ 		return -ENOMEM;
+ 	data = (struct proc_data *)file->private_data;
+@@ -7193,6 +7201,8 @@ static int airo_get_aplist(struct net_device *dev,
+ 	int i;
+ 	int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
+ 
++	pax_track_stack();
++
+ 	qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL);
+ 	if (!qual)
+ 		return -ENOMEM;
+@@ -7753,6 +7763,8 @@ static void airo_read_wireless_stats(struct airo_info *local)
+ 	CapabilityRid cap_rid;
+ 	__le32 *vals = stats_rid.vals;
+ 
++	pax_track_stack();
++
+ 	/* Get stats out of the card */
+ 	clear_bit(JOB_WSTATS, &local->jobs);
+ 	if (local->power.event) {
+diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
+index 747508c..82e965d 100644
+--- a/drivers/net/wireless/ath/ath5k/debug.c
++++ b/drivers/net/wireless/ath/ath5k/debug.c
+@@ -205,6 +205,8 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
+ 	unsigned int v;
+ 	u64 tsf;
+ 
++	pax_track_stack();
++
+ 	v = ath5k_hw_reg_read(sc->ah, AR5K_BEACON);
+ 	len += snprintf(buf+len, sizeof(buf)-len,
+ 		"%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
+@@ -318,6 +320,8 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf,
+ 	unsigned int len = 0;
+ 	unsigned int i;
+ 
++	pax_track_stack();
++
+ 	len += snprintf(buf+len, sizeof(buf)-len,
+ 		"DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
+ 
+diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
+index 2be4c22..593b1eb 100644
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -220,6 +220,8 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
+ 	char buf[512];
+ 	unsigned int len = 0;
+ 
++	pax_track_stack();
++
+ 	len += snprintf(buf + len, sizeof(buf) - len,
+ 		"%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
+ 	len += snprintf(buf + len, sizeof(buf) - len,
+@@ -360,6 +362,8 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
+ 	int i;
+ 	u8 addr[ETH_ALEN];
+ 
++	pax_track_stack();
++
+ 	len += snprintf(buf + len, sizeof(buf) - len,
+ 			"primary: %s (%s chan=%d ht=%d)\n",
+ 			wiphy_name(sc->pri_wiphy->hw->wiphy),
+diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
+index 80b19a4..dab3a45 100644
+--- a/drivers/net/wireless/b43/debugfs.c
++++ b/drivers/net/wireless/b43/debugfs.c
+@@ -43,7 +43,7 @@ static struct dentry *rootdir;
+ struct b43_debugfs_fops {
+ 	ssize_t (*read)(struct b43_wldev *dev, char *buf, size_t bufsize);
+ 	int (*write)(struct b43_wldev *dev, const char *buf, size_t count);
+-	struct file_operations fops;
++	const struct file_operations fops;
+ 	/* Offset of struct b43_dfs_file in struct b43_dfsentry */
+ 	size_t file_struct_offset;
+ };
+diff --git a/drivers/net/wireless/b43legacy/debugfs.c b/drivers/net/wireless/b43legacy/debugfs.c
+index 1f85ac5..c99b4b4 100644
+--- a/drivers/net/wireless/b43legacy/debugfs.c
++++ b/drivers/net/wireless/b43legacy/debugfs.c
+@@ -44,7 +44,7 @@ static struct dentry *rootdir;
+ struct b43legacy_debugfs_fops {
+ 	ssize_t (*read)(struct b43legacy_wldev *dev, char *buf, size_t bufsize);
+ 	int (*write)(struct b43legacy_wldev *dev, const char *buf, size_t count);
+-	struct file_operations fops;
++	const struct file_operations fops;
+ 	/* Offset of struct b43legacy_dfs_file in struct b43legacy_dfsentry */
+ 	size_t file_struct_offset;
+ 	/* Take wl->irq_lock before calling read/write? */
+diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
+index 43102bf..3b569c3 100644
+--- a/drivers/net/wireless/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/ipw2x00/ipw2100.c
+@@ -2014,6 +2014,8 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
+ 	int err;
+ 	DECLARE_SSID_BUF(ssid);
+ 
++	pax_track_stack();
++
+ 	IPW_DEBUG_HC("SSID: '%s'\n", print_ssid(ssid, essid, ssid_len));
+ 
+ 	if (ssid_len)
+@@ -5380,6 +5382,8 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
+ 	struct ipw2100_wep_key *wep_key = (void *)cmd.host_command_parameters;
+ 	int err;
+ 
++	pax_track_stack();
++
+ 	IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n",
+ 		     idx, keylen, len);
+ 
+diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
+index 282b1f7..169f0cf 100644
+--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
++++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
+@@ -1566,6 +1566,8 @@ static void libipw_process_probe_response(struct libipw_device
+ 	unsigned long flags;
+ 	DECLARE_SSID_BUF(ssid);
+ 
++	pax_track_stack();
++
+ 	LIBIPW_DEBUG_SCAN("'%s' (%pM"
+ 		     "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+ 		     print_ssid(ssid, info_element->data, info_element->len),
+diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
+index 950267a..80d5fd2 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
+@@ -137,7 +137,7 @@ static struct iwl_lib_ops iwl1000_lib = {
+ 	 },
+ };
+ 
+-static struct iwl_ops iwl1000_ops = {
++static const struct iwl_ops iwl1000_ops = {
+ 	.ucode = &iwl5000_ucode,
+ 	.lib = &iwl1000_lib,
+ 	.hcmd = &iwl5000_hcmd,
+diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
+index 56bfcc3..b348020 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
++++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
+@@ -2874,7 +2874,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
+ 	.build_addsta_hcmd = iwl3945_build_addsta_hcmd,
+ };
+ 
+-static struct iwl_ops iwl3945_ops = {
++static const struct iwl_ops iwl3945_ops = {
+ 	.ucode = &iwl3945_ucode,
+ 	.lib = &iwl3945_lib,
+ 	.hcmd = &iwl3945_hcmd,
+diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
+index 585b8d4..e142963 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
++++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
+@@ -2345,7 +2345,7 @@ static struct iwl_lib_ops iwl4965_lib = {
+ 	},
+ };
+ 
+-static struct iwl_ops iwl4965_ops = {
++static const struct iwl_ops iwl4965_ops = {
+ 	.ucode = &iwl4965_ucode,
+ 	.lib = &iwl4965_lib,
+ 	.hcmd = &iwl4965_hcmd,
+diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
+index 1f423f2..e37c192 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
+@@ -1633,14 +1633,14 @@ static struct iwl_lib_ops iwl5150_lib = {
+ 	 },
+ };
+ 
+-struct iwl_ops iwl5000_ops = {
++const struct iwl_ops iwl5000_ops = {
+ 	.ucode = &iwl5000_ucode,
+ 	.lib = &iwl5000_lib,
+ 	.hcmd = &iwl5000_hcmd,
+ 	.utils = &iwl5000_hcmd_utils,
+ };
+ 
+-static struct iwl_ops iwl5150_ops = {
++static const struct iwl_ops iwl5150_ops = {
+ 	.ucode = &iwl5000_ucode,
+ 	.lib = &iwl5150_lib,
+ 	.hcmd = &iwl5000_hcmd,
+diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
+index 1473452..f07d5e1 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
+@@ -146,7 +146,7 @@ static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
+ 	.calc_rssi = iwl5000_calc_rssi,
+ };
+ 
+-static struct iwl_ops iwl6000_ops = {
++static const struct iwl_ops iwl6000_ops = {
+ 	.ucode = &iwl5000_ucode,
+ 	.lib = &iwl6000_lib,
+ 	.hcmd = &iwl5000_hcmd,
+diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+index 1a3dfa2..b3e0a61 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+@@ -857,6 +857,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
+ 	u8 active_index = 0;
+ 	s32 tpt = 0;
+ 
++	pax_track_stack();
++
+ 	IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
+ 
+ 	if (!ieee80211_is_data(hdr->frame_control) ||
+@@ -2722,6 +2724,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
+ 	u8 valid_tx_ant = 0;
+ 	struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq;
+ 
++	pax_track_stack();
++
+ 	/* Override starting rate (index 0) if needed for debug purposes */
+ 	rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
+ 
+diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
+index 0e56d78..6a3c107 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
+@@ -2911,7 +2911,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 		if (iwl_debug_level & IWL_DL_INFO)
+ 			dev_printk(KERN_DEBUG, &(pdev->dev),
+ 				   "Disabling hw_scan\n");
+-		iwl_hw_ops.hw_scan = NULL;
++		pax_open_kernel();
++		*(void **)&iwl_hw_ops.hw_scan = NULL;
++		pax_close_kernel();
+ 	}
+ 
+ 	hw = iwl_alloc_all(cfg, &iwl_hw_ops);
+diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
+index cbc6290..eb323d7 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
++++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
+@@ -118,8 +118,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv);
+ #endif
+ 
+ #else
+-#define IWL_DEBUG(__priv, level, fmt, args...)
+-#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
++#define IWL_DEBUG(__priv, level, fmt, args...) do {} while (0)
++#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) do {} while (0)
+ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
+ 				      void *p, u32 len)
+ {}
+diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+index a198bcf..8e68233 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
++++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+@@ -524,6 +524,8 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
+ 	int pos = 0;
+ 	const size_t bufsz = sizeof(buf);
+ 
++	pax_track_stack();
++
+ 	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
+ 		test_bit(STATUS_HCMD_ACTIVE, &priv->status));
+ 	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n",
+@@ -658,6 +660,8 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
+ 	const size_t bufsz = sizeof(buf);
+ 	ssize_t ret;
+ 
++	pax_track_stack();
++
+ 	for (i = 0; i < AC_NUM; i++) {
+ 		pos += scnprintf(buf + pos, bufsz - pos,
+ 			"\tcw_min\tcw_max\taifsn\ttxop\n");
+diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
+index 3539ea4..b174bfa 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
++++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
+@@ -68,7 +68,7 @@ struct iwl_tx_queue;
+ 
+ /* shared structures from iwl-5000.c */
+ extern struct iwl_mod_params iwl50_mod_params;
+-extern struct iwl_ops iwl5000_ops;
++extern const struct iwl_ops iwl5000_ops;
+ extern struct iwl_ucode_ops iwl5000_ucode;
+ extern struct iwl_lib_ops iwl5000_lib;
+ extern struct iwl_hcmd_ops iwl5000_hcmd;
+diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+index 619590d..69235ee 100644
+--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+@@ -3927,7 +3927,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
+ 	 */
+ 	if (iwl3945_mod_params.disable_hw_scan) {
+ 		IWL_DEBUG_INFO(priv, "Disabling hw_scan\n");
+-		iwl3945_hw_ops.hw_scan = NULL;
++		pax_open_kernel();
++		*(void **)&iwl3945_hw_ops.hw_scan = NULL;
++		pax_close_kernel();
+ 	}
+ 
+ 
+diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
+index 1465379..fe4d78b 100644
+--- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
++++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
+@@ -299,6 +299,8 @@ static ssize_t iwm_debugfs_fw_err_read(struct file *filp,
+ 	int buf_len = 512;
+ 	size_t len = 0;
+ 
++	pax_track_stack();
++
+ 	if (*ppos != 0)
+ 		return 0;
+ 	if (count < sizeof(buf))
+diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
+index 893a55c..7f66a50 100644
+--- a/drivers/net/wireless/libertas/debugfs.c
++++ b/drivers/net/wireless/libertas/debugfs.c
+@@ -708,7 +708,7 @@ out_unlock:
+ struct lbs_debugfs_files {
+ 	const char *name;
+ 	int perm;
+-	struct file_operations fops;
++	const struct file_operations fops;
+ };
+ 
+ static const struct lbs_debugfs_files debugfs_files[] = {
+diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
+index 2ecbedb..42704f0 100644
+--- a/drivers/net/wireless/rndis_wlan.c
++++ b/drivers/net/wireless/rndis_wlan.c
+@@ -1176,7 +1176,7 @@ static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold)
+ 
+ 	devdbg(usbdev, "set_rts_threshold %i", rts_threshold);
+ 
+-	if (rts_threshold < 0 || rts_threshold > 2347)
++	if (rts_threshold > 2347)
+ 		rts_threshold = 2347;
+ 
+ 	tmp = cpu_to_le32(rts_threshold);
+diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
+index 334ccd6..47f8944 100644
+--- a/drivers/oprofile/buffer_sync.c
++++ b/drivers/oprofile/buffer_sync.c
+@@ -342,7 +342,7 @@ static void add_data(struct op_entry *entry, struct mm_struct *mm)
+ 		if (cookie == NO_COOKIE)
+ 			offset = pc;
+ 		if (cookie == INVALID_COOKIE) {
+-			atomic_inc(&oprofile_stats.sample_lost_no_mapping);
++			atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
+ 			offset = pc;
+ 		}
+ 		if (cookie != last_cookie) {
+@@ -386,14 +386,14 @@ add_sample(struct mm_struct *mm, struct op_sample *s, int in_kernel)
+ 	/* add userspace sample */
+ 
+ 	if (!mm) {
+-		atomic_inc(&oprofile_stats.sample_lost_no_mm);
++		atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mm);
+ 		return 0;
+ 	}
+ 
+ 	cookie = lookup_dcookie(mm, s->eip, &offset);
+ 
+ 	if (cookie == INVALID_COOKIE) {
+-		atomic_inc(&oprofile_stats.sample_lost_no_mapping);
++		atomic_inc_unchecked(&oprofile_stats.sample_lost_no_mapping);
+ 		return 0;
+ 	}
+ 
+@@ -562,7 +562,7 @@ void sync_buffer(int cpu)
+ 		/* ignore backtraces if failed to add a sample */
+ 		if (state == sb_bt_start) {
+ 			state = sb_bt_ignore;
+-			atomic_inc(&oprofile_stats.bt_lost_no_mapping);
++			atomic_inc_unchecked(&oprofile_stats.bt_lost_no_mapping);
+ 		}
+ 	}
+ 	release_mm(mm);
+diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c
+index 5df60a6..72f5c1c 100644
+--- a/drivers/oprofile/event_buffer.c
++++ b/drivers/oprofile/event_buffer.c
+@@ -53,7 +53,7 @@ void add_event_entry(unsigned long value)
+ 	}
+ 
+ 	if (buffer_pos == buffer_size) {
+-		atomic_inc(&oprofile_stats.event_lost_overflow);
++		atomic_inc_unchecked(&oprofile_stats.event_lost_overflow);
+ 		return;
+ 	}
+ 
+diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
+index dc8a042..fe5f315 100644
+--- a/drivers/oprofile/oprof.c
++++ b/drivers/oprofile/oprof.c
+@@ -110,7 +110,7 @@ static void switch_worker(struct work_struct *work)
+ 	if (oprofile_ops.switch_events())
+ 		return;
+ 
+-	atomic_inc(&oprofile_stats.multiplex_counter);
++	atomic_inc_unchecked(&oprofile_stats.multiplex_counter);
+ 	start_switch_worker();
+ }
+ 
+diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c
+index 61689e8..387f7f8 100644
+--- a/drivers/oprofile/oprofile_stats.c
++++ b/drivers/oprofile/oprofile_stats.c
+@@ -30,11 +30,11 @@ void oprofile_reset_stats(void)
+ 		cpu_buf->sample_invalid_eip = 0;
+ 	}
+ 
+-	atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
+-	atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
+-	atomic_set(&oprofile_stats.event_lost_overflow, 0);
+-	atomic_set(&oprofile_stats.bt_lost_no_mapping, 0);
+-	atomic_set(&oprofile_stats.multiplex_counter, 0);
++	atomic_set_unchecked(&oprofile_stats.sample_lost_no_mm, 0);
++	atomic_set_unchecked(&oprofile_stats.sample_lost_no_mapping, 0);
++	atomic_set_unchecked(&oprofile_stats.event_lost_overflow, 0);
++	atomic_set_unchecked(&oprofile_stats.bt_lost_no_mapping, 0);
++	atomic_set_unchecked(&oprofile_stats.multiplex_counter, 0);
+ }
+ 
+ 
+diff --git a/drivers/oprofile/oprofile_stats.h b/drivers/oprofile/oprofile_stats.h
+index 0b54e46..a37c527 100644
+--- a/drivers/oprofile/oprofile_stats.h
++++ b/drivers/oprofile/oprofile_stats.h
+@@ -13,11 +13,11 @@
+ #include <asm/atomic.h>
+ 
+ struct oprofile_stat_struct {
+-	atomic_t sample_lost_no_mm;
+-	atomic_t sample_lost_no_mapping;
+-	atomic_t bt_lost_no_mapping;
+-	atomic_t event_lost_overflow;
+-	atomic_t multiplex_counter;
++	atomic_unchecked_t sample_lost_no_mm;
++	atomic_unchecked_t sample_lost_no_mapping;
++	atomic_unchecked_t bt_lost_no_mapping;
++	atomic_unchecked_t event_lost_overflow;
++	atomic_unchecked_t multiplex_counter;
+ };
+ 
+ extern struct oprofile_stat_struct oprofile_stats;
+diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
+index 2766a6d..80c77e2 100644
+--- a/drivers/oprofile/oprofilefs.c
++++ b/drivers/oprofile/oprofilefs.c
+@@ -187,7 +187,7 @@ static const struct file_operations atomic_ro_fops = {
+ 
+ 
+ int oprofilefs_create_ro_atomic(struct super_block *sb, struct dentry *root,
+-	char const *name, atomic_t *val)
++	char const *name, atomic_unchecked_t *val)
+ {
+ 	struct dentry *d = __oprofilefs_create_file(sb, root, name,
+ 						     &atomic_ro_fops, 0444);
+diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
+index 13a64bc..ad62835 100644
+--- a/drivers/parisc/pdc_stable.c
++++ b/drivers/parisc/pdc_stable.c
+@@ -481,7 +481,7 @@ pdcspath_attr_store(struct kobject *kobj, struct attribute *attr,
+ 	return ret;
+ }
+ 
+-static struct sysfs_ops pdcspath_attr_ops = {
++static const struct sysfs_ops pdcspath_attr_ops = {
+ 	.show = pdcspath_attr_show,
+ 	.store = pdcspath_attr_store,
+ };
+diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
+index 8eefe56..40751a7 100644
+--- a/drivers/parport/procfs.c
++++ b/drivers/parport/procfs.c
+@@ -64,7 +64,7 @@ static int do_active_device(ctl_table *table, int write,
+ 
+ 	*ppos += len;
+ 
+-	return copy_to_user(result, buffer, len) ? -EFAULT : 0;
++	return (len > sizeof buffer || copy_to_user(result, buffer, len)) ? -EFAULT : 0;
+ }
+ 
+ #ifdef CONFIG_PARPORT_1284
+@@ -106,7 +106,7 @@ static int do_autoprobe(ctl_table *table, int write,
+ 
+ 	*ppos += len;
+ 
+-	return copy_to_user (result, buffer, len) ? -EFAULT : 0;
++	return (len > sizeof buffer || copy_to_user (result, buffer, len)) ? -EFAULT : 0;
+ }
+ #endif /* IEEE1284.3 support. */
+ 
+diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
+index 73e7d8e..c80f3d2 100644
+--- a/drivers/pci/hotplug/acpiphp_glue.c
++++ b/drivers/pci/hotplug/acpiphp_glue.c
+@@ -111,7 +111,7 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
+ }
+ 
+ 
+-static struct acpi_dock_ops acpiphp_dock_ops = {
++static const struct acpi_dock_ops acpiphp_dock_ops = {
+ 	.handler = handle_hotplug_event_func,
+ };
+ 
+diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
+index 9fff878..ad0ad53 100644
+--- a/drivers/pci/hotplug/cpci_hotplug.h
++++ b/drivers/pci/hotplug/cpci_hotplug.h
+@@ -59,7 +59,7 @@ struct cpci_hp_controller_ops {
+ 	int (*hardware_test) (struct slot* slot, u32 value);
+ 	u8  (*get_power) (struct slot* slot);
+ 	int (*set_power) (struct slot* slot, int value);
+-};
++} __no_const;
+ 
+ struct cpci_hp_controller {
+ 	unsigned int irq;
+diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
+index 76ba8a1..20ca857 100644
+--- a/drivers/pci/hotplug/cpqphp_nvram.c
++++ b/drivers/pci/hotplug/cpqphp_nvram.c
+@@ -428,9 +428,13 @@ static u32 store_HRT (void __iomem *rom_start)
+ 
+ void compaq_nvram_init (void __iomem *rom_start)
+ {
++
++#ifndef CONFIG_PAX_KERNEXEC
+ 	if (rom_start) {
+ 		compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
+ 	}
++#endif
++
+ 	dbg("int15 entry  = %p\n", compaq_int15_entry_point);
+ 
+ 	/* initialize our int15 lock */
+diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
+index 6151389..0a894ef 100644
+--- a/drivers/pci/hotplug/fakephp.c
++++ b/drivers/pci/hotplug/fakephp.c
+@@ -73,7 +73,7 @@ static void legacy_release(struct kobject *kobj)
+ }
+ 
+ static struct kobj_type legacy_ktype = {
+-	.sysfs_ops = &(struct sysfs_ops){
++	.sysfs_ops = &(const struct sysfs_ops){
+ 		.store = legacy_store, .show = legacy_show
+ 	},
+ 	.release = &legacy_release,
+diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
+index 5b680df..fe05b7e 100644
+--- a/drivers/pci/intel-iommu.c
++++ b/drivers/pci/intel-iommu.c
+@@ -2643,7 +2643,7 @@ error:
+ 	return 0;
+ }
+ 
+-static dma_addr_t intel_map_page(struct device *dev, struct page *page,
++dma_addr_t intel_map_page(struct device *dev, struct page *page,
+ 				 unsigned long offset, size_t size,
+ 				 enum dma_data_direction dir,
+ 				 struct dma_attrs *attrs)
+@@ -2719,7 +2719,7 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova)
+ 	spin_unlock_irqrestore(&async_umap_flush_lock, flags);
+ }
+ 
+-static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
++void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
+ 			     size_t size, enum dma_data_direction dir,
+ 			     struct dma_attrs *attrs)
+ {
+@@ -2768,7 +2768,7 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
+ 	}
+ }
+ 
+-static void *intel_alloc_coherent(struct device *hwdev, size_t size,
++void *intel_alloc_coherent(struct device *hwdev, size_t size,
+ 				  dma_addr_t *dma_handle, gfp_t flags)
+ {
+ 	void *vaddr;
+@@ -2800,7 +2800,7 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,
+ 	return NULL;
+ }
+ 
+-static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
++void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
+ 				dma_addr_t dma_handle)
+ {
+ 	int order;
+@@ -2812,7 +2812,7 @@ static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
+ 	free_pages((unsigned long)vaddr, order);
+ }
+ 
+-static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
++void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
+ 			   int nelems, enum dma_data_direction dir,
+ 			   struct dma_attrs *attrs)
+ {
+@@ -2872,7 +2872,7 @@ static int intel_nontranslate_map_sg(struct device *hddev,
+ 	return nelems;
+ }
+ 
+-static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
++int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
+ 			enum dma_data_direction dir, struct dma_attrs *attrs)
+ {
+ 	int i;
+@@ -2941,12 +2941,12 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne
+ 	return nelems;
+ }
+ 
+-static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
++int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
+ {
+ 	return !dma_addr;
+ }
+ 
+-struct dma_map_ops intel_dma_ops = {
++const struct dma_map_ops intel_dma_ops = {
+ 	.alloc_coherent = intel_alloc_coherent,
+ 	.free_coherent = intel_free_coherent,
+ 	.map_sg = intel_map_sg,
+diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
+index 5b7056c..607bc94 100644
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -27,9 +27,9 @@
+ #define MODULE_PARAM_PREFIX "pcie_aspm."
+ 
+ /* Note: those are not register definitions */
+-#define ASPM_STATE_L0S_UP	(1)	/* Upstream direction L0s state */
+-#define ASPM_STATE_L0S_DW	(2)	/* Downstream direction L0s state */
+-#define ASPM_STATE_L1		(4)	/* L1 state */
++#define ASPM_STATE_L0S_UP	(1U)	/* Upstream direction L0s state */
++#define ASPM_STATE_L0S_DW	(2U)	/* Downstream direction L0s state */
++#define ASPM_STATE_L1		(4U)	/* L1 state */
+ #define ASPM_STATE_L0S		(ASPM_STATE_L0S_UP | ASPM_STATE_L0S_DW)
+ #define ASPM_STATE_ALL		(ASPM_STATE_L0S | ASPM_STATE_L1)
+ 
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 8105e32..ca10419 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -62,14 +62,14 @@ static ssize_t pci_bus_show_cpuaffinity(struct device *dev,
+ 	return ret;
+ }
+ 
+-static ssize_t inline pci_bus_show_cpumaskaffinity(struct device *dev,
++static inline ssize_t pci_bus_show_cpumaskaffinity(struct device *dev,
+ 					struct device_attribute *attr,
+ 					char *buf)
+ {
+ 	return pci_bus_show_cpuaffinity(dev, 0, attr, buf);
+ }
+ 
+-static ssize_t inline pci_bus_show_cpulistaffinity(struct device *dev,
++static inline ssize_t pci_bus_show_cpulistaffinity(struct device *dev,
+ 					struct device_attribute *attr,
+ 					char *buf)
+ {
+diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
+index a03ad8c..024b0da 100644
+--- a/drivers/pci/proc.c
++++ b/drivers/pci/proc.c
+@@ -480,7 +480,16 @@ static const struct file_operations proc_bus_pci_dev_operations = {
+ static int __init pci_proc_init(void)
+ {
+ 	struct pci_dev *dev = NULL;
++
++#ifdef CONFIG_GRKERNSEC_PROC_ADD
++#ifdef CONFIG_GRKERNSEC_PROC_USER
++	proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
++	proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
++#endif
++#else
+ 	proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
++#endif
+ 	proc_create("devices", 0, proc_bus_pci_dir,
+ 		    &proc_bus_pci_dev_operations);
+ 	proc_initialized = 1;
+diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
+index 8c02b6c..5584d8e 100644
+--- a/drivers/pci/slot.c
++++ b/drivers/pci/slot.c
+@@ -29,7 +29,7 @@ static ssize_t pci_slot_attr_store(struct kobject *kobj,
+ 	return attribute->store ? attribute->store(slot, buf, len) : -EIO;
+ }
+ 
+-static struct sysfs_ops pci_slot_sysfs_ops = {
++static const struct sysfs_ops pci_slot_sysfs_ops = {
+ 	.show = pci_slot_attr_show,
+ 	.store = pci_slot_attr_store,
+ };
+diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
+index 30cf71d2..50938f1 100644
+--- a/drivers/pcmcia/pcmcia_ioctl.c
++++ b/drivers/pcmcia/pcmcia_ioctl.c
+@@ -819,7 +819,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
+ 	    return -EFAULT;
+ 	}
+     }
+-    buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
++    buf = kzalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
+     if (!buf)
+ 	return -ENOMEM;
+ 
+diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
+index 52183c4..b224c69 100644
+--- a/drivers/platform/x86/acer-wmi.c
++++ b/drivers/platform/x86/acer-wmi.c
+@@ -918,7 +918,7 @@ static int update_bl_status(struct backlight_device *bd)
+ 	return 0;
+ }
+ 
+-static struct backlight_ops acer_bl_ops = {
++static const struct backlight_ops acer_bl_ops = {
+ 	.get_brightness = read_brightness,
+ 	.update_status = update_bl_status,
+ };
+diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
+index 767cb61..a87380b 100644
+--- a/drivers/platform/x86/asus-laptop.c
++++ b/drivers/platform/x86/asus-laptop.c
+@@ -250,7 +250,7 @@ static struct backlight_device *asus_backlight_device;
+  */
+ static int read_brightness(struct backlight_device *bd);
+ static int update_bl_status(struct backlight_device *bd);
+-static struct backlight_ops asusbl_ops = {
++static const struct backlight_ops asusbl_ops = {
+ 	.get_brightness = read_brightness,
+ 	.update_status = update_bl_status,
+ };
+diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c
+index d66c07a..a4abaac 100644
+--- a/drivers/platform/x86/asus_acpi.c
++++ b/drivers/platform/x86/asus_acpi.c
+@@ -1396,7 +1396,7 @@ static int asus_hotk_remove(struct acpi_device *device, int type)
+ 	return 0;
+ }
+ 
+-static struct backlight_ops asus_backlight_data = {
++static const struct backlight_ops asus_backlight_data = {
+ 	.get_brightness = read_brightness,
+ 	.update_status  = set_brightness_status,
+ };
+diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c
+index 11003bb..550ff1b 100644
+--- a/drivers/platform/x86/compal-laptop.c
++++ b/drivers/platform/x86/compal-laptop.c
+@@ -163,7 +163,7 @@ static int bl_update_status(struct backlight_device *b)
+ 	return set_lcd_level(b->props.brightness);
+ }
+ 
+-static struct backlight_ops compalbl_ops = {
++static const struct backlight_ops compalbl_ops = {
+ 	.get_brightness = bl_get_brightness,
+ 	.update_status	= bl_update_status,
+ };
+diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
+index 07a74da..9dc99fa 100644
+--- a/drivers/platform/x86/dell-laptop.c
++++ b/drivers/platform/x86/dell-laptop.c
+@@ -318,7 +318,7 @@ static int dell_get_intensity(struct backlight_device *bd)
+ 	return buffer.output[1];
+ }
+ 
+-static struct backlight_ops dell_ops = {
++static const struct backlight_ops dell_ops = {
+ 	.get_brightness = dell_get_intensity,
+ 	.update_status  = dell_send_intensity,
+ };
+diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
+index c533b1c..5c81f22 100644
+--- a/drivers/platform/x86/eeepc-laptop.c
++++ b/drivers/platform/x86/eeepc-laptop.c
+@@ -245,7 +245,7 @@ static struct device *eeepc_hwmon_device;
+  */
+ static int read_brightness(struct backlight_device *bd);
+ static int update_bl_status(struct backlight_device *bd);
+-static struct backlight_ops eeepcbl_ops = {
++static const struct backlight_ops eeepcbl_ops = {
+ 	.get_brightness = read_brightness,
+ 	.update_status = update_bl_status,
+ };
+diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
+index bcd4ba8..a249b35 100644
+--- a/drivers/platform/x86/fujitsu-laptop.c
++++ b/drivers/platform/x86/fujitsu-laptop.c
+@@ -436,7 +436,7 @@ static int bl_update_status(struct backlight_device *b)
+ 	return ret;
+ }
+ 
+-static struct backlight_ops fujitsubl_ops = {
++static const struct backlight_ops fujitsubl_ops = {
+ 	.get_brightness = bl_get_brightness,
+ 	.update_status = bl_update_status,
+ };
+diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
+index 759763d..1093ba2 100644
+--- a/drivers/platform/x86/msi-laptop.c
++++ b/drivers/platform/x86/msi-laptop.c
+@@ -161,7 +161,7 @@ static int bl_update_status(struct backlight_device *b)
+ 	return set_lcd_level(b->props.brightness);
+ }
+ 
+-static struct backlight_ops msibl_ops = {
++static const struct backlight_ops msibl_ops = {
+ 	.get_brightness = bl_get_brightness,
+ 	.update_status  = bl_update_status,
+ };
+diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
+index fe7cf01..9012d8d 100644
+--- a/drivers/platform/x86/panasonic-laptop.c
++++ b/drivers/platform/x86/panasonic-laptop.c
+@@ -352,7 +352,7 @@ static int bl_set_status(struct backlight_device *bd)
+ 	return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright);
+ }
+ 
+-static struct backlight_ops pcc_backlight_ops = {
++static const struct backlight_ops pcc_backlight_ops = {
+ 	.get_brightness	= bl_get,
+ 	.update_status	= bl_set_status,
+ };
+diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
+index a2a742c..b37e25e 100644
+--- a/drivers/platform/x86/sony-laptop.c
++++ b/drivers/platform/x86/sony-laptop.c
+@@ -850,7 +850,7 @@ static int sony_backlight_get_brightness(struct backlight_device *bd)
+ }
+ 
+ static struct backlight_device *sony_backlight_device;
+-static struct backlight_ops sony_backlight_ops = {
++static const struct backlight_ops sony_backlight_ops = {
+ 	.update_status = sony_backlight_update_status,
+ 	.get_brightness = sony_backlight_get_brightness,
+ };
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index 68271ae..5e8fb10 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -2139,7 +2139,7 @@ static int hotkey_mask_get(void)
+ 	return 0;
+ }
+ 
+-void static hotkey_mask_warn_incomplete_mask(void)
++static void hotkey_mask_warn_incomplete_mask(void)
+ {
+ 	/* log only what the user can fix... */
+ 	const u32 wantedmask = hotkey_driver_mask &
+@@ -6125,7 +6125,7 @@ static void tpacpi_brightness_notify_change(void)
+ 			       BACKLIGHT_UPDATE_HOTKEY);
+ }
+ 
+-static struct backlight_ops ibm_backlight_data = {
++static const struct backlight_ops ibm_backlight_data = {
+ 	.get_brightness = brightness_get,
+ 	.update_status  = brightness_update_status,
+ };
+diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
+index 51c0a8b..0786629 100644
+--- a/drivers/platform/x86/toshiba_acpi.c
++++ b/drivers/platform/x86/toshiba_acpi.c
+@@ -671,7 +671,7 @@ static acpi_status remove_device(void)
+ 	return AE_OK;
+ }
+ 
+-static struct backlight_ops toshiba_backlight_data = {
++static const struct backlight_ops toshiba_backlight_data = {
+         .get_brightness = get_lcd,
+         .update_status  = set_lcd_status,
+ };
+diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
+index fc83783c..cf370d7 100644
+--- a/drivers/pnp/pnpbios/bioscalls.c
++++ b/drivers/pnp/pnpbios/bioscalls.c
+@@ -60,7 +60,7 @@ do { \
+ 	set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
+ } while(0)
+ 
+-static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
++static const struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4093,
+ 			(unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
+ 
+ /*
+@@ -97,7 +97,10 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
+ 
+ 	cpu = get_cpu();
+ 	save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
++
++	pax_open_kernel();
+ 	get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
++	pax_close_kernel();
+ 
+ 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
+ 	spin_lock_irqsave(&pnp_bios_lock, flags);
+@@ -135,7 +138,10 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
+ 			     :"memory");
+ 	spin_unlock_irqrestore(&pnp_bios_lock, flags);
+ 
++	pax_open_kernel();
+ 	get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
++	pax_close_kernel();
++
+ 	put_cpu();
+ 
+ 	/* If we get here and this is set then the PnP BIOS faulted on us. */
+@@ -469,7 +475,7 @@ int pnp_bios_read_escd(char *data, u32 nvram_base)
+ 	return status;
+ }
+ 
+-void pnpbios_calls_init(union pnp_bios_install_struct *header)
++void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
+ {
+ 	int i;
+ 
+@@ -477,6 +483,8 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
+ 	pnp_bios_callpoint.offset = header->fields.pm16offset;
+ 	pnp_bios_callpoint.segment = PNP_CS16;
+ 
++	pax_open_kernel();
++
+ 	for_each_possible_cpu(i) {
+ 		struct desc_struct *gdt = get_cpu_gdt_table(i);
+ 		if (!gdt)
+@@ -488,4 +496,6 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
+ 		set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_DS],
+ 			 (unsigned long)__va(header->fields.pm16dseg));
+ 	}
++
++	pax_close_kernel();
+ }
+diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
+index ba97654..66b99d4 100644
+--- a/drivers/pnp/resource.c
++++ b/drivers/pnp/resource.c
+@@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
+ 		return 1;
+ 
+ 	/* check if the resource is valid */
+-	if (*irq < 0 || *irq > 15)
++	if (*irq > 15)
+ 		return 0;
+ 
+ 	/* check if the resource is reserved */
+@@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
+ 		return 1;
+ 
+ 	/* check if the resource is valid */
+-	if (*dma < 0 || *dma == 4 || *dma > 7)
++	if (*dma == 4 || *dma > 7)
+ 		return 0;
+ 
+ 	/* check if the resource is reserved */
+diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
+index 62bb981..24a2dc9 100644
+--- a/drivers/power/bq27x00_battery.c
++++ b/drivers/power/bq27x00_battery.c
+@@ -44,7 +44,7 @@ struct bq27x00_device_info;
+ struct bq27x00_access_methods {
+ 	int (*read)(u8 reg, int *rt_value, int b_single,
+ 		struct bq27x00_device_info *di);
+-};
++} __no_const;
+ 
+ struct bq27x00_device_info {
+ 	struct device 		*dev;
+diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
+index 62227cd..b5b538b 100644
+--- a/drivers/rtc/rtc-dev.c
++++ b/drivers/rtc/rtc-dev.c
+@@ -14,6 +14,7 @@
+ #include <linux/module.h>
+ #include <linux/rtc.h>
+ #include <linux/sched.h>
++#include <linux/grsecurity.h>
+ #include "rtc-core.h"
+ 
+ static dev_t rtc_devt;
+@@ -357,6 +358,8 @@ static long rtc_dev_ioctl(struct file *file,
+ 		if (copy_from_user(&tm, uarg, sizeof(tm)))
+ 			return -EFAULT;
+ 
++		gr_log_timechange();
++
+ 		return rtc_set_time(rtc, &tm);
+ 
+ 	case RTC_PIE_ON:
+diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c
+index 968e3c7..fbc637a 100644
+--- a/drivers/s390/cio/qdio_perf.c
++++ b/drivers/s390/cio/qdio_perf.c
+@@ -31,51 +31,51 @@ static struct proc_dir_entry *qdio_perf_pde;
+ static int qdio_perf_proc_show(struct seq_file *m, void *v)
+ {
+ 	seq_printf(m, "Number of qdio interrupts\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.qdio_int));
++		   (long)atomic_long_read_unchecked(&perf_stats.qdio_int));
+ 	seq_printf(m, "Number of PCI interrupts\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.pci_int));
++		   (long)atomic_long_read_unchecked(&perf_stats.pci_int));
+ 	seq_printf(m, "Number of adapter interrupts\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.thin_int));
++		   (long)atomic_long_read_unchecked(&perf_stats.thin_int));
+ 	seq_printf(m, "\n");
+ 	seq_printf(m, "Inbound tasklet runs\t\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.tasklet_inbound));
++		   (long)atomic_long_read_unchecked(&perf_stats.tasklet_inbound));
+ 	seq_printf(m, "Outbound tasklet runs\t\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.tasklet_outbound));
++		   (long)atomic_long_read_unchecked(&perf_stats.tasklet_outbound));
+ 	seq_printf(m, "Adapter interrupt tasklet runs/loops\t\t: %li/%li\n",
+-		   (long)atomic_long_read(&perf_stats.tasklet_thinint),
+-		   (long)atomic_long_read(&perf_stats.tasklet_thinint_loop));
++		   (long)atomic_long_read_unchecked(&perf_stats.tasklet_thinint),
++		   (long)atomic_long_read_unchecked(&perf_stats.tasklet_thinint_loop));
+ 	seq_printf(m, "Adapter interrupt inbound tasklet runs/loops\t: %li/%li\n",
+-		   (long)atomic_long_read(&perf_stats.thinint_inbound),
+-		   (long)atomic_long_read(&perf_stats.thinint_inbound_loop));
++		   (long)atomic_long_read_unchecked(&perf_stats.thinint_inbound),
++		   (long)atomic_long_read_unchecked(&perf_stats.thinint_inbound_loop));
+ 	seq_printf(m, "\n");
+ 	seq_printf(m, "Number of SIGA In issued\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.siga_in));
++		   (long)atomic_long_read_unchecked(&perf_stats.siga_in));
+ 	seq_printf(m, "Number of SIGA Out issued\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.siga_out));
++		   (long)atomic_long_read_unchecked(&perf_stats.siga_out));
+ 	seq_printf(m, "Number of SIGA Sync issued\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.siga_sync));
++		   (long)atomic_long_read_unchecked(&perf_stats.siga_sync));
+ 	seq_printf(m, "\n");
+ 	seq_printf(m, "Number of inbound transfers\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.inbound_handler));
++		   (long)atomic_long_read_unchecked(&perf_stats.inbound_handler));
+ 	seq_printf(m, "Number of outbound transfers\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.outbound_handler));
++		   (long)atomic_long_read_unchecked(&perf_stats.outbound_handler));
+ 	seq_printf(m, "\n");
+ 	seq_printf(m, "Number of fast requeues (outg. SBAL w/o SIGA)\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.fast_requeue));
++		   (long)atomic_long_read_unchecked(&perf_stats.fast_requeue));
+ 	seq_printf(m, "Number of outbound target full condition\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.outbound_target_full));
++		   (long)atomic_long_read_unchecked(&perf_stats.outbound_target_full));
+ 	seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.debug_tl_out_timer));
++		   (long)atomic_long_read_unchecked(&perf_stats.debug_tl_out_timer));
+ 	seq_printf(m, "Number of stop polling calls\t\t\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.debug_stop_polling));
++		   (long)atomic_long_read_unchecked(&perf_stats.debug_stop_polling));
+ 	seq_printf(m, "AI inbound tasklet loops after stop polling\t: %li\n",
+-		   (long)atomic_long_read(&perf_stats.thinint_inbound_loop2));
++		   (long)atomic_long_read_unchecked(&perf_stats.thinint_inbound_loop2));
+ 	seq_printf(m, "QEBSM EQBS total/incomplete\t\t\t: %li/%li\n",
+-		   (long)atomic_long_read(&perf_stats.debug_eqbs_all),
+-		   (long)atomic_long_read(&perf_stats.debug_eqbs_incomplete));
++		   (long)atomic_long_read_unchecked(&perf_stats.debug_eqbs_all),
++		   (long)atomic_long_read_unchecked(&perf_stats.debug_eqbs_incomplete));
+ 	seq_printf(m, "QEBSM SQBS total/incomplete\t\t\t: %li/%li\n",
+-		   (long)atomic_long_read(&perf_stats.debug_sqbs_all),
+-		   (long)atomic_long_read(&perf_stats.debug_sqbs_incomplete));
++		   (long)atomic_long_read_unchecked(&perf_stats.debug_sqbs_all),
++		   (long)atomic_long_read_unchecked(&perf_stats.debug_sqbs_incomplete));
+ 	seq_printf(m, "\n");
+ 	return 0;
+ }
+diff --git a/drivers/s390/cio/qdio_perf.h b/drivers/s390/cio/qdio_perf.h
+index ff4504c..b3604c3 100644
+--- a/drivers/s390/cio/qdio_perf.h
++++ b/drivers/s390/cio/qdio_perf.h
+@@ -13,46 +13,46 @@
+ 
+ struct qdio_perf_stats {
+ 	/* interrupt handler calls */
+-	atomic_long_t qdio_int;
+-	atomic_long_t pci_int;
+-	atomic_long_t thin_int;
++	atomic_long_unchecked_t qdio_int;
++	atomic_long_unchecked_t pci_int;
++	atomic_long_unchecked_t thin_int;
+ 
+ 	/* tasklet runs */
+-	atomic_long_t tasklet_inbound;
+-	atomic_long_t tasklet_outbound;
+-	atomic_long_t tasklet_thinint;
+-	atomic_long_t tasklet_thinint_loop;
+-	atomic_long_t thinint_inbound;
+-	atomic_long_t thinint_inbound_loop;
+-	atomic_long_t thinint_inbound_loop2;
++	atomic_long_unchecked_t tasklet_inbound;
++	atomic_long_unchecked_t tasklet_outbound;
++	atomic_long_unchecked_t tasklet_thinint;
++	atomic_long_unchecked_t tasklet_thinint_loop;
++	atomic_long_unchecked_t thinint_inbound;
++	atomic_long_unchecked_t thinint_inbound_loop;
++	atomic_long_unchecked_t thinint_inbound_loop2;
+ 
+ 	/* signal adapter calls */
+-	atomic_long_t siga_out;
+-	atomic_long_t siga_in;
+-	atomic_long_t siga_sync;
++	atomic_long_unchecked_t siga_out;
++	atomic_long_unchecked_t siga_in;
++	atomic_long_unchecked_t siga_sync;
+ 
+ 	/* misc */
+-	atomic_long_t inbound_handler;
+-	atomic_long_t outbound_handler;
+-	atomic_long_t fast_requeue;
+-	atomic_long_t outbound_target_full;
++	atomic_long_unchecked_t inbound_handler;
++	atomic_long_unchecked_t outbound_handler;
++	atomic_long_unchecked_t fast_requeue;
++	atomic_long_unchecked_t outbound_target_full;
+ 
+ 	/* for debugging */
+-	atomic_long_t debug_tl_out_timer;
+-	atomic_long_t debug_stop_polling;
+-	atomic_long_t debug_eqbs_all;
+-	atomic_long_t debug_eqbs_incomplete;
+-	atomic_long_t debug_sqbs_all;
+-	atomic_long_t debug_sqbs_incomplete;
++	atomic_long_unchecked_t debug_tl_out_timer;
++	atomic_long_unchecked_t debug_stop_polling;
++	atomic_long_unchecked_t debug_eqbs_all;
++	atomic_long_unchecked_t debug_eqbs_incomplete;
++	atomic_long_unchecked_t debug_sqbs_all;
++	atomic_long_unchecked_t debug_sqbs_incomplete;
+ };
+ 
+ extern struct qdio_perf_stats perf_stats;
+ extern int qdio_performance_stats;
+ 
+-static inline void qdio_perf_stat_inc(atomic_long_t *count)
++static inline void qdio_perf_stat_inc(atomic_long_unchecked_t *count)
+ {
+ 	if (qdio_performance_stats)
+-		atomic_long_inc(count);
++		atomic_long_inc_unchecked(count);
+ }
+ 
+ int qdio_setup_perf_stats(void);
+diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
+new file mode 100644
+index 0000000..7d18a18
+--- /dev/null
++++ b/drivers/scsi/3w-sas.c
+@@ -0,0 +1,1933 @@
++/*
++   3w-sas.c -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
++
++   Written By: Adam Radford <linuxraid@lsi.com>
++
++   Copyright (C) 2009 LSI Corporation.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; version 2 of the License.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   NO WARRANTY
++   THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
++   CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
++   LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
++   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
++   solely responsible for determining the appropriateness of using and
++   distributing the Program and assumes all risks associated with its
++   exercise of rights under this Agreement, including but not limited to
++   the risks and costs of program errors, damage to or loss of data,
++   programs or equipment, and unavailability or interruption of operations.
++
++   DISCLAIMER OF LIABILITY
++   NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
++   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++   DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
++   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
++   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++   USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
++   HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++
++   Controllers supported by this driver:
++
++   LSI 3ware 9750 6Gb/s SAS/SATA-RAID
++
++   Bugs/Comments/Suggestions should be mailed to:
++   linuxraid@lsi.com
++
++   For more information, goto:
++   http://www.lsi.com
++
++   History
++   -------
++   3.26.00.000 - Initial driver release.
++*/
++
++#include <linux/module.h>
++#include <linux/reboot.h>
++#include <linux/spinlock.h>
++#include <linux/interrupt.h>
++#include <linux/moduleparam.h>
++#include <linux/errno.h>
++#include <linux/types.h>
++#include <linux/delay.h>
++#include <linux/pci.h>
++#include <linux/time.h>
++#include <linux/mutex.h>
++#include <linux/smp_lock.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <scsi/scsi.h>
++#include <scsi/scsi_host.h>
++#include <scsi/scsi_tcq.h>
++#include <scsi/scsi_cmnd.h>
++#include "3w-sas.h"
++
++/* Globals */
++#define TW_DRIVER_VERSION "3.26.00.028-2.6.32RH"
++static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
++static unsigned int twl_device_extension_count;
++static int twl_major = -1;
++extern struct timezone sys_tz;
++
++/* Module parameters */
++MODULE_AUTHOR ("LSI");
++MODULE_DESCRIPTION ("LSI 3ware SAS/SATA-RAID Linux Driver");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(TW_DRIVER_VERSION);
++
++static int use_msi = 0;
++module_param(use_msi, int, S_IRUGO);
++MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
++
++/* Function prototypes */
++static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
++
++/* Functions */
++
++/* This function returns AENs through sysfs */
++static ssize_t twl_sysfs_aen_read(struct file *filp, struct kobject *kobj,
++				  struct bin_attribute *bin_attr,
++				  char *outbuf, loff_t offset, size_t count)
++{
++	struct device *dev = container_of(kobj, struct device, kobj);
++	struct Scsi_Host *shost = class_to_shost(dev);
++	TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
++	unsigned long flags = 0;
++	ssize_t ret;
++
++	if (!capable(CAP_SYS_ADMIN))
++		return -EACCES;
++
++	spin_lock_irqsave(tw_dev->host->host_lock, flags);
++	ret = memory_read_from_buffer(outbuf, count, &offset, tw_dev->event_queue[0], sizeof(TW_Event) * TW_Q_LENGTH);
++	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
++
++	return ret;
++} /* End twl_sysfs_aen_read() */
++
++/* aen_read sysfs attribute initializer */
++static struct bin_attribute twl_sysfs_aen_read_attr = {
++	.attr = {
++		.name = "3ware_aen_read",
++		.mode = S_IRUSR,
++	},
++	.size = 0,
++	.read = twl_sysfs_aen_read
++};
++
++/* This function returns driver compatibility info through sysfs */
++static ssize_t twl_sysfs_compat_info(struct file *filp, struct kobject *kobj,
++				     struct bin_attribute *bin_attr,
++				     char *outbuf, loff_t offset, size_t count)
++{
++	struct device *dev = container_of(kobj, struct device, kobj);
++	struct Scsi_Host *shost = class_to_shost(dev);
++	TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
++	unsigned long flags = 0;
++	ssize_t ret;
++
++	if (!capable(CAP_SYS_ADMIN))
++		return -EACCES;
++
++	spin_lock_irqsave(tw_dev->host->host_lock, flags);
++	ret = memory_read_from_buffer(outbuf, count, &offset, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
++	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
++
++	return ret;
++} /* End twl_sysfs_compat_info() */
++
++/* compat_info sysfs attribute initializer */
++static struct bin_attribute twl_sysfs_compat_info_attr = {
++	.attr = {
++		.name = "3ware_compat_info",
++		.mode = S_IRUSR,
++	},
++	.size = 0,
++	.read = twl_sysfs_compat_info
++};
++
++/* Show some statistics about the card */
++static ssize_t twl_show_stats(struct device *dev,
++			      struct device_attribute *attr, char *buf)
++{
++	struct Scsi_Host *host = class_to_shost(dev);
++	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
++	unsigned long flags = 0;
++	ssize_t len;
++
++	spin_lock_irqsave(tw_dev->host->host_lock, flags);
++	len = snprintf(buf, PAGE_SIZE, "3w-sas Driver version: %s\n"
++		       "Current commands posted:   %4d\n"
++		       "Max commands posted:       %4d\n"
++		       "Last sgl length:           %4d\n"
++		       "Max sgl length:            %4d\n"
++		       "Last sector count:         %4d\n"
++		       "Max sector count:          %4d\n"
++		       "SCSI Host Resets:          %4d\n"
++		       "AEN's:                     %4d\n",
++		       TW_DRIVER_VERSION,
++		       tw_dev->posted_request_count,
++		       tw_dev->max_posted_request_count,
++		       tw_dev->sgl_entries,
++		       tw_dev->max_sgl_entries,
++		       tw_dev->sector_count,
++		       tw_dev->max_sector_count,
++		       tw_dev->num_resets,
++		       tw_dev->aen_count);
++	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
++	return len;
++} /* End twl_show_stats() */
++
++/* This function will set a devices queue depth */
++static int twl_change_queue_depth(struct scsi_device *sdev, int queue_depth,
++				  int reason)
++{
++	if (reason != SCSI_QDEPTH_DEFAULT)
++		return -EOPNOTSUPP;
++
++	if (queue_depth > TW_Q_LENGTH-2)
++		queue_depth = TW_Q_LENGTH-2;
++	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
++	return queue_depth;
++} /* End twl_change_queue_depth() */
++
++/* stats sysfs attribute initializer */
++static struct device_attribute twl_host_stats_attr = {
++	.attr = {
++		.name = 	"3ware_stats",
++		.mode =		S_IRUGO,
++	},
++	.show = twl_show_stats
++};
++
++/* Host attributes initializer */
++static struct device_attribute *twl_host_attrs[] = {
++	&twl_host_stats_attr,
++	NULL,
++};
++
++/* This function will look up an AEN severity string */
++static char *twl_aen_severity_lookup(unsigned char severity_code)
++{
++	char *retval = NULL;
++
++	if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
++	    (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
++		goto out;
++
++	retval = twl_aen_severity_table[severity_code];
++out:
++	return retval;
++} /* End twl_aen_severity_lookup() */
++
++/* This function will queue an event */
++static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
++{
++	u32 local_time;
++	struct timeval time;
++	TW_Event *event;
++	unsigned short aen;
++	char host[16];
++	char *error_str;
++
++	tw_dev->aen_count++;
++
++	/* Fill out event info */
++	event = tw_dev->event_queue[tw_dev->error_index];
++
++	host[0] = '\0';
++	if (tw_dev->host)
++		sprintf(host, " scsi%d:", tw_dev->host->host_no);
++
++	aen = le16_to_cpu(header->status_block.error);
++	memset(event, 0, sizeof(TW_Event));
++
++	event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
++	do_gettimeofday(&time);
++	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
++	event->time_stamp_sec = local_time;
++	event->aen_code = aen;
++	event->retrieved = TW_AEN_NOT_RETRIEVED;
++	event->sequence_id = tw_dev->error_sequence_id;
++	tw_dev->error_sequence_id++;
++
++	/* Check for embedded error string */
++	error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
++
++	header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
++	event->parameter_len = strlen(header->err_specific_desc);
++	memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
++	if (event->severity != TW_AEN_SEVERITY_DEBUG)
++		printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
++		       host,
++		       twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
++		       TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
++		       header->err_specific_desc);
++	else
++		tw_dev->aen_count--;
++
++	tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
++} /* End twl_aen_queue_event() */
++
++/* This function will attempt to post a command packet to the board */
++static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
++{
++	dma_addr_t command_que_value;
++
++	command_que_value = tw_dev->command_packet_phys[request_id];
++	command_que_value += TW_COMMAND_OFFSET;
++
++	/* First write upper 4 bytes */
++	writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
++	/* Then the lower 4 bytes */
++	writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
++
++	tw_dev->state[request_id] = TW_S_POSTED;
++	tw_dev->posted_request_count++;
++	if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
++		tw_dev->max_posted_request_count = tw_dev->posted_request_count;
++
++	return 0;
++} /* End twl_post_command_packet() */
++
++/* This function will perform a pci-dma mapping for a scatter gather list */
++static int twl_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
++{
++	int use_sg;
++	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
++
++	use_sg = scsi_dma_map(cmd);
++	if (!use_sg)
++		return 0;
++	else if (use_sg < 0) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Failed to map scatter gather list");
++		return 0;
++	}
++
++	cmd->SCp.phase = TW_PHASE_SGLIST;
++	cmd->SCp.have_data_in = use_sg;
++
++	return use_sg;
++} /* End twl_map_scsi_sg_data() */
++
++/* This function hands scsi cdb's to the firmware */
++static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
++{
++	TW_Command_Full *full_command_packet;
++	TW_Command_Apache *command_packet;
++	int i, sg_count;
++	struct scsi_cmnd *srb = NULL;
++	struct scatterlist *sglist = NULL, *sg;
++	int retval = 1;
++
++	if (tw_dev->srb[request_id]) {
++		srb = tw_dev->srb[request_id];
++		if (scsi_sglist(srb))
++			sglist = scsi_sglist(srb);
++	}
++
++	/* Initialize command packet */
++	full_command_packet = tw_dev->command_packet_virt[request_id];
++	full_command_packet->header.header_desc.size_header = 128;
++	full_command_packet->header.status_block.error = 0;
++	full_command_packet->header.status_block.severity__reserved = 0;
++
++	command_packet = &full_command_packet->command.newcommand;
++	command_packet->status = 0;
++	command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
++
++	/* We forced 16 byte cdb use earlier */
++	if (!cdb)
++		memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
++	else
++		memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
++
++	if (srb) {
++		command_packet->unit = srb->device->id;
++		command_packet->request_id__lunl =
++			cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
++	} else {
++		command_packet->request_id__lunl =
++			cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
++		command_packet->unit = 0;
++	}
++
++	command_packet->sgl_offset = 16;
++
++	if (!sglistarg) {
++		/* Map sglist from scsi layer to cmd packet */
++		if (scsi_sg_count(srb)) {
++			sg_count = twl_map_scsi_sg_data(tw_dev, request_id);
++			if (sg_count == 0)
++				goto out;
++
++			scsi_for_each_sg(srb, sg, sg_count, i) {
++				command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
++				command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
++			}
++			command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
++		}
++	} else {
++		/* Internal cdb post */
++		for (i = 0; i < use_sg; i++) {
++			command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
++			command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
++		}
++		command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
++	}
++
++	/* Update some stats */
++	if (srb) {
++		tw_dev->sector_count = scsi_bufflen(srb) / 512;
++		if (tw_dev->sector_count > tw_dev->max_sector_count)
++			tw_dev->max_sector_count = tw_dev->sector_count;
++		tw_dev->sgl_entries = scsi_sg_count(srb);
++		if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
++			tw_dev->max_sgl_entries = tw_dev->sgl_entries;
++	}
++
++	/* Now post the command to the board */
++	retval = twl_post_command_packet(tw_dev, request_id);
++
++out:
++	return retval;
++} /* End twl_scsiop_execute_scsi() */
++
++/* This function will read the aen queue from the isr */
++static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
++{
++	char cdb[TW_MAX_CDB_LEN];
++	TW_SG_Entry_ISO sglist[1];
++	TW_Command_Full *full_command_packet;
++	int retval = 1;
++
++	full_command_packet = tw_dev->command_packet_virt[request_id];
++	memset(full_command_packet, 0, sizeof(TW_Command_Full));
++
++	/* Initialize cdb */
++	memset(&cdb, 0, TW_MAX_CDB_LEN);
++	cdb[0] = REQUEST_SENSE; /* opcode */
++	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
++
++	/* Initialize sglist */
++	memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
++	sglist[0].length = TW_SECTOR_SIZE;
++	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
++
++	/* Mark internal command */
++	tw_dev->srb[request_id] = NULL;
++
++	/* Now post the command packet */
++	if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
++		goto out;
++	}
++	retval = 0;
++out:
++	return retval;
++} /* End twl_aen_read_queue() */
++
++/* This function will sync firmware time with the host time */
++static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
++{
++	u32 schedulertime;
++	struct timeval utc;
++	TW_Command_Full *full_command_packet;
++	TW_Command *command_packet;
++	TW_Param_Apache *param;
++	u32 local_time;
++
++	/* Fill out the command packet */
++	full_command_packet = tw_dev->command_packet_virt[request_id];
++	memset(full_command_packet, 0, sizeof(TW_Command_Full));
++	command_packet = &full_command_packet->command.oldcommand;
++	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
++	command_packet->request_id = request_id;
++	command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
++	command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
++	command_packet->size = TW_COMMAND_SIZE;
++	command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
++
++	/* Setup the param */
++	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
++	memset(param, 0, TW_SECTOR_SIZE);
++	param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */
++	param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
++	param->parameter_size_bytes = cpu_to_le16(4);
++
++	/* Convert system time in UTC to local time seconds since last
++           Sunday 12:00AM */
++	do_gettimeofday(&utc);
++	local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
++	schedulertime = local_time - (3 * 86400);
++	schedulertime = cpu_to_le32(schedulertime % 604800);
++
++	memcpy(param->data, &schedulertime, sizeof(u32));
++
++	/* Mark internal command */
++	tw_dev->srb[request_id] = NULL;
++
++	/* Now post the command */
++	twl_post_command_packet(tw_dev, request_id);
++} /* End twl_aen_sync_time() */
++
++/* This function will assign an available request id */
++static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
++{
++	*request_id = tw_dev->free_queue[tw_dev->free_head];
++	tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
++	tw_dev->state[*request_id] = TW_S_STARTED;
++} /* End twl_get_request_id() */
++
++/* This function will free a request id */
++static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
++{
++	tw_dev->free_queue[tw_dev->free_tail] = request_id;
++	tw_dev->state[request_id] = TW_S_FINISHED;
++	tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
++} /* End twl_free_request_id() */
++
++/* This function will complete an aen request from the isr */
++static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
++{
++	TW_Command_Full *full_command_packet;
++	TW_Command *command_packet;
++	TW_Command_Apache_Header *header;
++	unsigned short aen;
++	int retval = 1;
++
++	header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
++	tw_dev->posted_request_count--;
++	aen = le16_to_cpu(header->status_block.error);
++	full_command_packet = tw_dev->command_packet_virt[request_id];
++	command_packet = &full_command_packet->command.oldcommand;
++
++	/* First check for internal completion of set param for time sync */
++	if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
++		/* Keep reading the queue in case there are more aen's */
++		if (twl_aen_read_queue(tw_dev, request_id))
++			goto out2;
++	        else {
++			retval = 0;
++			goto out;
++		}
++	}
++
++	switch (aen) {
++	case TW_AEN_QUEUE_EMPTY:
++		/* Quit reading the queue if this is the last one */
++		break;
++	case TW_AEN_SYNC_TIME_WITH_HOST:
++		twl_aen_sync_time(tw_dev, request_id);
++		retval = 0;
++		goto out;
++	default:
++		twl_aen_queue_event(tw_dev, header);
++
++		/* If there are more aen's, keep reading the queue */
++		if (twl_aen_read_queue(tw_dev, request_id))
++			goto out2;
++		else {
++			retval = 0;
++			goto out;
++		}
++	}
++	retval = 0;
++out2:
++	tw_dev->state[request_id] = TW_S_COMPLETED;
++	twl_free_request_id(tw_dev, request_id);
++	clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
++out:
++	return retval;
++} /* End twl_aen_complete() */
++
++/* This function will poll for a response */
++static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
++{
++	unsigned long before;
++	dma_addr_t mfa;
++	u32 regh, regl;
++	u32 response;
++	int retval = 1;
++	int found = 0;
++
++	before = jiffies;
++
++	while (!found) {
++		if (sizeof(dma_addr_t) > 4) {
++			regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
++			regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
++			mfa = ((u64)regh << 32) | regl;
++		} else
++			mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
++
++		response = (u32)mfa;
++
++		if (TW_RESID_OUT(response) == request_id)
++			found = 1;
++
++		if (time_after(jiffies, before + HZ * seconds))
++			goto out;
++
++		msleep(50);
++	}
++	retval = 0;
++out:
++	return retval;
++} /* End twl_poll_response() */
++
++/* This function will drain the aen queue */
++static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
++{
++	int request_id = 0;
++	char cdb[TW_MAX_CDB_LEN];
++	TW_SG_Entry_ISO sglist[1];
++	int finished = 0, count = 0;
++	TW_Command_Full *full_command_packet;
++	TW_Command_Apache_Header *header;
++	unsigned short aen;
++	int first_reset = 0, queue = 0, retval = 1;
++
++	if (no_check_reset)
++		first_reset = 0;
++	else
++		first_reset = 1;
++
++	full_command_packet = tw_dev->command_packet_virt[request_id];
++	memset(full_command_packet, 0, sizeof(TW_Command_Full));
++
++	/* Initialize cdb */
++	memset(&cdb, 0, TW_MAX_CDB_LEN);
++	cdb[0] = REQUEST_SENSE; /* opcode */
++	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
++
++	/* Initialize sglist */
++	memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
++	sglist[0].length = TW_SECTOR_SIZE;
++	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
++
++	/* Mark internal command */
++	tw_dev->srb[request_id] = NULL;
++
++	do {
++		/* Send command to the board */
++		if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
++			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
++			goto out;
++		}
++
++		/* Now poll for completion */
++		if (twl_poll_response(tw_dev, request_id, 30)) {
++			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
++			tw_dev->posted_request_count--;
++			goto out;
++		}
++
++		tw_dev->posted_request_count--;
++		header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
++		aen = le16_to_cpu(header->status_block.error);
++		queue = 0;
++		count++;
++
++		switch (aen) {
++		case TW_AEN_QUEUE_EMPTY:
++			if (first_reset != 1)
++				goto out;
++			else
++				finished = 1;
++			break;
++		case TW_AEN_SOFT_RESET:
++			if (first_reset == 0)
++				first_reset = 1;
++			else
++				queue = 1;
++			break;
++		case TW_AEN_SYNC_TIME_WITH_HOST:
++			break;
++		default:
++			queue = 1;
++		}
++
++		/* Now queue an event info */
++		if (queue)
++			twl_aen_queue_event(tw_dev, header);
++	} while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
++
++	if (count == TW_MAX_AEN_DRAIN)
++		goto out;
++
++	retval = 0;
++out:
++	tw_dev->state[request_id] = TW_S_INITIAL;
++	return retval;
++} /* End twl_aen_drain_queue() */
++
++/* This function will allocate memory and check if it is correctly aligned */
++static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
++{
++	int i;
++	dma_addr_t dma_handle;
++	unsigned long *cpu_addr;
++	int retval = 1;
++
++	cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
++	if (!cpu_addr) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
++		goto out;
++	}
++
++	memset(cpu_addr, 0, size*TW_Q_LENGTH);
++
++	for (i = 0; i < TW_Q_LENGTH; i++) {
++		switch(which) {
++		case 0:
++			tw_dev->command_packet_phys[i] = dma_handle+(i*size);
++			tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
++			break;
++		case 1:
++			tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
++			tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
++			break;
++		case 2:
++			tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
++			tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
++			break;
++		}
++	}
++	retval = 0;
++out:
++	return retval;
++} /* End twl_allocate_memory() */
++
++/* This function will load the request id and various sgls for ioctls */
++static void twl_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
++{
++	TW_Command *oldcommand;
++	TW_Command_Apache *newcommand;
++	TW_SG_Entry_ISO *sgl;
++	unsigned int pae = 0;
++
++	if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
++		pae = 1;
++
++	if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
++		newcommand = &full_command_packet->command.newcommand;
++		newcommand->request_id__lunl =
++			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
++		if (length) {
++			newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
++			newcommand->sg_list[0].length = TW_CPU_TO_SGL(length);
++		}
++		newcommand->sgl_entries__lunh =
++			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
++	} else {
++		oldcommand = &full_command_packet->command.oldcommand;
++		oldcommand->request_id = request_id;
++
++		if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
++			/* Load the sg list */
++			sgl = (TW_SG_Entry_ISO *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry_ISO)/4) + pae + (sizeof(dma_addr_t) > 4 ? 1 : 0));
++			sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
++			sgl->length = TW_CPU_TO_SGL(length);
++			oldcommand->size += pae;
++			oldcommand->size += sizeof(dma_addr_t) > 4 ? 1 : 0;
++		}
++	}
++} /* End twl_load_sgl() */
++
++/* This function handles ioctl for the character device
++   This interface is used by smartmontools open source software */
++static int twl_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++{
++	long timeout;
++	unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
++	dma_addr_t dma_handle;
++	int request_id = 0;
++	TW_Ioctl_Driver_Command driver_command;
++	TW_Ioctl_Buf_Apache *tw_ioctl;
++	TW_Command_Full *full_command_packet;
++	TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
++	int retval = -EFAULT;
++	void __user *argp = (void __user *)arg;
++
++	/* Only let one of these through at a time */
++	if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
++		retval = -EINTR;
++		goto out;
++	}
++
++	/* First copy down the driver command */
++	if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
++		goto out2;
++
++	/* Check data buffer size */
++	if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
++		retval = -EINVAL;
++		goto out2;
++	}
++
++	/* Hardware can only do multiple of 512 byte transfers */
++	data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
++
++	/* Now allocate ioctl buf memory */
++	cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, &dma_handle, GFP_KERNEL);
++	if (!cpu_addr) {
++		retval = -ENOMEM;
++		goto out2;
++	}
++
++	tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
++
++	/* Now copy down the entire ioctl */
++	if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
++		goto out3;
++
++	/* See which ioctl we are doing */
++	switch (cmd) {
++	case TW_IOCTL_FIRMWARE_PASS_THROUGH:
++		spin_lock_irqsave(tw_dev->host->host_lock, flags);
++		twl_get_request_id(tw_dev, &request_id);
++
++		/* Flag internal command */
++		tw_dev->srb[request_id] = NULL;
++
++		/* Flag chrdev ioctl */
++		tw_dev->chrdev_request_id = request_id;
++
++		full_command_packet = (TW_Command_Full *)&tw_ioctl->firmware_command;
++
++		/* Load request id and sglist for both command types */
++		twl_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
++
++		memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
++
++		/* Now post the command packet to the controller */
++		twl_post_command_packet(tw_dev, request_id);
++		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
++
++		timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
++
++		/* Now wait for command to complete */
++		timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
++
++		/* We timed out, and didn't get an interrupt */
++		if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
++			/* Now we need to reset the board */
++			printk(KERN_WARNING "3w-sas: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
++			       tw_dev->host->host_no, TW_DRIVER, 0x6,
++			       cmd);
++			retval = -EIO;
++			twl_reset_device_extension(tw_dev, 1);
++			goto out3;
++		}
++
++		/* Now copy in the command packet response */
++		memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
++
++		/* Now complete the io */
++		spin_lock_irqsave(tw_dev->host->host_lock, flags);
++		tw_dev->posted_request_count--;
++		tw_dev->state[request_id] = TW_S_COMPLETED;
++		twl_free_request_id(tw_dev, request_id);
++		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
++		break;
++	default:
++		retval = -ENOTTY;
++		goto out3;
++	}
++
++	/* Now copy the entire response to userspace */
++	if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
++		retval = 0;
++out3:
++	/* Now free ioctl buf memory */
++	dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
++out2:
++	mutex_unlock(&tw_dev->ioctl_lock);
++out:
++	return retval;
++} /* End twl_chrdev_ioctl() */
++
++/* This function handles open for the character device */
++static int twl_chrdev_open(struct inode *inode, struct file *file)
++{
++	unsigned int minor_number;
++	int retval = -ENODEV;
++
++	if (!capable(CAP_SYS_ADMIN)) {
++		retval = -EACCES;
++		goto out;
++	}
++
++	cycle_kernel_lock();
++	minor_number = iminor(inode);
++	if (minor_number >= twl_device_extension_count)
++		goto out;
++	retval = 0;
++out:
++	return retval;
++} /* End twl_chrdev_open() */
++
++/* File operations struct for character device */
++static const struct file_operations twl_fops = {
++	.owner		= THIS_MODULE,
++	.ioctl		= twl_chrdev_ioctl,
++	.open		= twl_chrdev_open,
++	.release	= NULL
++};
++
++/* This function passes sense data from firmware to scsi layer */
++static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, int copy_sense, int print_host)
++{
++	TW_Command_Apache_Header *header;
++	TW_Command_Full *full_command_packet;
++	unsigned short error;
++	char *error_str;
++	int retval = 1;
++
++	header = tw_dev->sense_buffer_virt[i];
++	full_command_packet = tw_dev->command_packet_virt[request_id];
++
++	/* Get embedded firmware error string */
++	error_str = &(header->err_specific_desc[strlen(header->err_specific_desc) + 1]);
++
++	/* Don't print error for Logical unit not supported during rollcall */
++	error = le16_to_cpu(header->status_block.error);
++	if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE) && (error != TW_ERROR_INVALID_FIELD_IN_CDB)) {
++		if (print_host)
++			printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
++			       tw_dev->host->host_no,
++			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
++			       header->status_block.error,
++			       error_str,
++			       header->err_specific_desc);
++		else
++			printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
++			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
++			       header->status_block.error,
++			       error_str,
++			       header->err_specific_desc);
++	}
++
++	if (copy_sense) {
++		memcpy(tw_dev->srb[request_id]->sense_buffer, header->sense_data, TW_SENSE_DATA_LENGTH);
++		tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
++		goto out;
++	}
++out:
++	return retval;
++} /* End twl_fill_sense() */
++
++/* This function will free up device extension resources */
++static void twl_free_device_extension(TW_Device_Extension *tw_dev)
++{
++	if (tw_dev->command_packet_virt[0])
++		pci_free_consistent(tw_dev->tw_pci_dev,
++				    sizeof(TW_Command_Full)*TW_Q_LENGTH,
++				    tw_dev->command_packet_virt[0],
++				    tw_dev->command_packet_phys[0]);
++
++	if (tw_dev->generic_buffer_virt[0])
++		pci_free_consistent(tw_dev->tw_pci_dev,
++				    TW_SECTOR_SIZE*TW_Q_LENGTH,
++				    tw_dev->generic_buffer_virt[0],
++				    tw_dev->generic_buffer_phys[0]);
++
++	if (tw_dev->sense_buffer_virt[0])
++		pci_free_consistent(tw_dev->tw_pci_dev,
++				    sizeof(TW_Command_Apache_Header)*
++				    TW_Q_LENGTH,
++				    tw_dev->sense_buffer_virt[0],
++				    tw_dev->sense_buffer_phys[0]);
++
++	kfree(tw_dev->event_queue[0]);
++} /* End twl_free_device_extension() */
++
++/* This function will get parameter table entries from the firmware */
++static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
++{
++	TW_Command_Full *full_command_packet;
++	TW_Command *command_packet;
++	TW_Param_Apache *param;
++	void *retval = NULL;
++
++	/* Setup the command packet */
++	full_command_packet = tw_dev->command_packet_virt[request_id];
++	memset(full_command_packet, 0, sizeof(TW_Command_Full));
++	command_packet = &full_command_packet->command.oldcommand;
++
++	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
++	command_packet->size              = TW_COMMAND_SIZE;
++	command_packet->request_id        = request_id;
++	command_packet->byte6_offset.block_count = cpu_to_le16(1);
++
++	/* Now setup the param */
++	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
++	memset(param, 0, TW_SECTOR_SIZE);
++	param->table_id = cpu_to_le16(table_id | 0x8000);
++	param->parameter_id = cpu_to_le16(parameter_id);
++	param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
++
++	command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
++	command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
++
++	/* Post the command packet to the board */
++	twl_post_command_packet(tw_dev, request_id);
++
++	/* Poll for completion */
++	if (twl_poll_response(tw_dev, request_id, 30))
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "No valid response during get param")
++	else
++		retval = (void *)&(param->data[0]);
++
++	tw_dev->posted_request_count--;
++	tw_dev->state[request_id] = TW_S_INITIAL;
++
++	return retval;
++} /* End twl_get_param() */
++
++/* This function will send an initconnection command to controller */
++static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
++ 			      u32 set_features, unsigned short current_fw_srl,
++			      unsigned short current_fw_arch_id,
++			      unsigned short current_fw_branch,
++			      unsigned short current_fw_build,
++			      unsigned short *fw_on_ctlr_srl,
++			      unsigned short *fw_on_ctlr_arch_id,
++			      unsigned short *fw_on_ctlr_branch,
++			      unsigned short *fw_on_ctlr_build,
++			      u32 *init_connect_result)
++{
++	TW_Command_Full *full_command_packet;
++	TW_Initconnect *tw_initconnect;
++	int request_id = 0, retval = 1;
++
++	/* Initialize InitConnection command packet */
++	full_command_packet = tw_dev->command_packet_virt[request_id];
++	memset(full_command_packet, 0, sizeof(TW_Command_Full));
++	full_command_packet->header.header_desc.size_header = 128;
++
++	tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
++	tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
++	tw_initconnect->request_id = request_id;
++	tw_initconnect->message_credits = cpu_to_le16(message_credits);
++	tw_initconnect->features = set_features;
++
++	/* Turn on 64-bit sgl support if we need to */
++	tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
++
++	tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
++
++	if (set_features & TW_EXTENDED_INIT_CONNECT) {
++		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
++		tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
++		tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
++		tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
++		tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
++	} else
++		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
++
++	/* Send command packet to the board */
++	twl_post_command_packet(tw_dev, request_id);
++
++	/* Poll for completion */
++	if (twl_poll_response(tw_dev, request_id, 30)) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x8, "No valid response during init connection");
++	} else {
++		if (set_features & TW_EXTENDED_INIT_CONNECT) {
++			*fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
++			*fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
++			*fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
++			*fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
++			*init_connect_result = le32_to_cpu(tw_initconnect->result);
++		}
++		retval = 0;
++	}
++
++	tw_dev->posted_request_count--;
++	tw_dev->state[request_id] = TW_S_INITIAL;
++
++	return retval;
++} /* End twl_initconnection() */
++
++/* This function will initialize the fields of a device extension */
++static int twl_initialize_device_extension(TW_Device_Extension *tw_dev)
++{
++	int i, retval = 1;
++
++	/* Initialize command packet buffers */
++	if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x9, "Command packet memory allocation failed");
++		goto out;
++	}
++
++	/* Initialize generic buffer */
++	if (twl_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Generic memory allocation failed");
++		goto out;
++	}
++
++	/* Allocate sense buffers */
++	if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Apache_Header), 2)) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xb, "Sense buffer allocation failed");
++		goto out;
++	}
++
++	/* Allocate event info space */
++	tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
++	if (!tw_dev->event_queue[0]) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed");
++		goto out;
++	}
++
++	for (i = 0; i < TW_Q_LENGTH; i++) {
++		tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
++		tw_dev->free_queue[i] = i;
++		tw_dev->state[i] = TW_S_INITIAL;
++	}
++
++	tw_dev->free_head = TW_Q_START;
++	tw_dev->free_tail = TW_Q_START;
++	tw_dev->error_sequence_id = 1;
++	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
++
++	mutex_init(&tw_dev->ioctl_lock);
++	init_waitqueue_head(&tw_dev->ioctl_wqueue);
++
++	retval = 0;
++out:
++	return retval;
++} /* End twl_initialize_device_extension() */
++
++/* This function will perform a pci-dma unmap */
++static void twl_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
++{
++	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
++
++	if (cmd->SCp.phase == TW_PHASE_SGLIST)
++		scsi_dma_unmap(cmd);
++} /* End twl_unmap_scsi_data() */
++
++/* This function will handle attention interrupts */
++static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
++{
++	int retval = 1;
++	u32 request_id, doorbell;
++
++	/* Read doorbell status */
++	doorbell = readl(TWL_HOBDB_REG_ADDR(tw_dev));
++
++	/* Check for controller errors */
++	if (doorbell & TWL_DOORBELL_CONTROLLER_ERROR) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "Microcontroller Error: clearing");
++		goto out;
++	}
++
++	/* Check if we need to perform an AEN drain */
++	if (doorbell & TWL_DOORBELL_ATTENTION_INTERRUPT) {
++		if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
++			twl_get_request_id(tw_dev, &request_id);
++			if (twl_aen_read_queue(tw_dev, request_id)) {
++				tw_dev->state[request_id] = TW_S_COMPLETED;
++				twl_free_request_id(tw_dev, request_id);
++				clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
++			}
++		}
++	}
++
++	retval = 0;
++out:
++	/* Clear doorbell interrupt */
++	TWL_CLEAR_DB_INTERRUPT(tw_dev);
++
++	/* Make sure the clear was flushed by reading it back */
++	readl(TWL_HOBDBC_REG_ADDR(tw_dev));
++
++	return retval;
++} /* End twl_handle_attention_interrupt() */
++
++/* Interrupt service routine */
++static irqreturn_t twl_interrupt(int irq, void *dev_instance)
++{
++	TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
++	int i, handled = 0, error = 0;
++	dma_addr_t mfa = 0;
++	u32 reg, regl, regh, response, request_id = 0;
++	struct scsi_cmnd *cmd;
++	TW_Command_Full *full_command_packet;
++
++	spin_lock(tw_dev->host->host_lock);
++
++	/* Read host interrupt status */
++	reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
++
++	/* Check if this is our interrupt, otherwise bail */
++	if (!(reg & TWL_HISTATUS_VALID_INTERRUPT))
++		goto twl_interrupt_bail;
++
++	handled = 1;
++
++	/* If we are resetting, bail */
++	if (test_bit(TW_IN_RESET, &tw_dev->flags))
++		goto twl_interrupt_bail;
++
++	/* Attention interrupt */
++	if (reg & TWL_HISTATUS_ATTENTION_INTERRUPT) {
++		if (twl_handle_attention_interrupt(tw_dev)) {
++			TWL_MASK_INTERRUPTS(tw_dev);
++			goto twl_interrupt_bail;
++		}
++	}
++
++	/* Response interrupt */
++	while (reg & TWL_HISTATUS_RESPONSE_INTERRUPT) {
++		if (sizeof(dma_addr_t) > 4) {
++			regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
++			regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
++			mfa = ((u64)regh << 32) | regl;
++		} else
++			mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
++
++		error = 0;
++		response = (u32)mfa;
++
++		/* Check for command packet error */
++		if (!TW_NOTMFA_OUT(response)) {
++			for (i=0;i<TW_Q_LENGTH;i++) {
++				if (tw_dev->sense_buffer_phys[i] == mfa) {
++					request_id = le16_to_cpu(tw_dev->sense_buffer_virt[i]->header_desc.request_id);
++					if (tw_dev->srb[request_id] != NULL)
++						error = twl_fill_sense(tw_dev, i, request_id, 1, 1);
++					else {
++						/* Skip ioctl error prints */
++						if (request_id != tw_dev->chrdev_request_id)
++							error = twl_fill_sense(tw_dev, i, request_id, 0, 1);
++						else
++							memcpy(tw_dev->command_packet_virt[request_id], tw_dev->sense_buffer_virt[i], sizeof(TW_Command_Apache_Header));
++					}
++
++					/* Now re-post the sense buffer */
++					writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
++					writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
++					break;
++				}
++			}
++		} else
++			request_id = TW_RESID_OUT(response);
++
++		full_command_packet = tw_dev->command_packet_virt[request_id];
++
++		/* Check for correct state */
++		if (tw_dev->state[request_id] != TW_S_POSTED) {
++			if (tw_dev->srb[request_id] != NULL) {
++				TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Received a request id that wasn't posted");
++				TWL_MASK_INTERRUPTS(tw_dev);
++				goto twl_interrupt_bail;
++			}
++		}
++
++		/* Check for internal command completion */
++		if (tw_dev->srb[request_id] == NULL) {
++			if (request_id != tw_dev->chrdev_request_id) {
++				if (twl_aen_complete(tw_dev, request_id))
++					TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "Error completing AEN during attention interrupt");
++			} else {
++				tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
++				wake_up(&tw_dev->ioctl_wqueue);
++			}
++		} else {
++			cmd = tw_dev->srb[request_id];
++
++			if (!error)
++				cmd->result = (DID_OK << 16);
++
++			/* Report residual bytes for single sgl */
++			if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
++				if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
++					scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
++			}
++
++			/* Now complete the io */
++			tw_dev->state[request_id] = TW_S_COMPLETED;
++			twl_free_request_id(tw_dev, request_id);
++			tw_dev->posted_request_count--;
++			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
++			twl_unmap_scsi_data(tw_dev, request_id);
++		}
++
++		/* Check for another response interrupt */
++		reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
++	}
++
++twl_interrupt_bail:
++	spin_unlock(tw_dev->host->host_lock);
++	return IRQ_RETVAL(handled);
++} /* End twl_interrupt() */
++
++/* This function will poll for a register change */
++static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value, u32 result, int seconds)
++{
++	unsigned long before;
++	int retval = 1;
++	u32 reg_value;
++
++	reg_value = readl(reg);
++	before = jiffies;
++
++        while ((reg_value & value) != result) {
++		reg_value = readl(reg);
++		if (time_after(jiffies, before + HZ * seconds))
++			goto out;
++		msleep(50);
++	}
++	retval = 0;
++out:
++	return retval;
++} /* End twl_poll_register() */
++
++/* This function will reset a controller */
++static int twl_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
++{
++	int retval = 1;
++	int i = 0;
++	u32 status = 0;
++	unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
++	unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
++	u32 init_connect_result = 0;
++	int tries = 0;
++	int do_soft_reset = soft_reset;
++
++	while (tries < TW_MAX_RESET_TRIES) {
++		/* Do a soft reset if one is needed */
++		if (do_soft_reset) {
++			TWL_SOFT_RESET(tw_dev);
++
++			/* Make sure controller is in a good state */
++			if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, 0x0, 30)) {
++				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Controller never went non-ready during reset sequence");
++				tries++;
++				continue;
++			}
++			if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, TWL_CONTROLLER_READY, 60)) {
++				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x11, "Controller not ready during reset sequence");
++				tries++;
++				continue;
++			}
++		}
++
++		/* Initconnect */
++		if (twl_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
++				       TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
++				       TW_9750_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
++				       TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
++				       &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
++				       &fw_on_ctlr_build, &init_connect_result)) {
++			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x12, "Initconnection failed while checking SRL");
++			do_soft_reset = 1;
++			tries++;
++			continue;
++		}
++
++		/* Load sense buffers */
++		while (i < TW_Q_LENGTH) {
++			writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
++			writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
++
++			/* Check status for over-run after each write */
++			status = readl(TWL_STATUS_REG_ADDR(tw_dev));
++			if (!(status & TWL_STATUS_OVERRUN_SUBMIT))
++			    i++;
++		}
++
++		/* Now check status */
++		status = readl(TWL_STATUS_REG_ADDR(tw_dev));
++		if (status) {
++			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "Bad controller status after loading sense buffers");
++			do_soft_reset = 1;
++			tries++;
++			continue;
++		}
++
++		/* Drain the AEN queue */
++		if (twl_aen_drain_queue(tw_dev, soft_reset)) {
++			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x14, "AEN drain failed during reset sequence");
++			do_soft_reset = 1;
++			tries++;
++			continue;
++		}
++
++		/* Load rest of compatibility struct */
++		strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
++		tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
++		tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
++		tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
++		tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
++		tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
++		tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
++		tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
++		tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
++		tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
++
++		/* If we got here, controller is in a good state */
++		retval = 0;
++		goto out;
++	}
++out:
++	return retval;
++} /* End twl_reset_sequence() */
++
++/* This function will reset a device extension */
++static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
++{
++	int i = 0, retval = 1;
++	unsigned long flags = 0;
++
++	/* Block SCSI requests while we are resetting */
++	if (ioctl_reset)
++		scsi_block_requests(tw_dev->host);
++
++	set_bit(TW_IN_RESET, &tw_dev->flags);
++	TWL_MASK_INTERRUPTS(tw_dev);
++	TWL_CLEAR_DB_INTERRUPT(tw_dev);
++
++	spin_lock_irqsave(tw_dev->host->host_lock, flags);
++
++	/* Abort all requests that are in progress */
++	for (i = 0; i < TW_Q_LENGTH; i++) {
++		if ((tw_dev->state[i] != TW_S_FINISHED) &&
++		    (tw_dev->state[i] != TW_S_INITIAL) &&
++		    (tw_dev->state[i] != TW_S_COMPLETED)) {
++			if (tw_dev->srb[i]) {
++				tw_dev->srb[i]->result = (DID_RESET << 16);
++				tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
++				twl_unmap_scsi_data(tw_dev, i);
++			}
++		}
++	}
++
++	/* Reset queues and counts */
++	for (i = 0; i < TW_Q_LENGTH; i++) {
++		tw_dev->free_queue[i] = i;
++		tw_dev->state[i] = TW_S_INITIAL;
++	}
++	tw_dev->free_head = TW_Q_START;
++	tw_dev->free_tail = TW_Q_START;
++	tw_dev->posted_request_count = 0;
++
++	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
++
++	if (twl_reset_sequence(tw_dev, 1))
++		goto out;
++
++	TWL_UNMASK_INTERRUPTS(tw_dev);
++
++	clear_bit(TW_IN_RESET, &tw_dev->flags);
++	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
++
++	retval = 0;
++out:
++	if (ioctl_reset)
++		scsi_unblock_requests(tw_dev->host);
++	return retval;
++} /* End twl_reset_device_extension() */
++
++/* This funciton returns unit geometry in cylinders/heads/sectors */
++static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
++{
++	int heads, sectors, cylinders;
++	TW_Device_Extension *tw_dev;
++
++	tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
++
++	if (capacity >= 0x200000) {
++		heads = 255;
++		sectors = 63;
++		cylinders = sector_div(capacity, heads * sectors);
++	} else {
++		heads = 64;
++		sectors = 32;
++		cylinders = sector_div(capacity, heads * sectors);
++	}
++
++	geom[0] = heads;
++	geom[1] = sectors;
++	geom[2] = cylinders;
++
++	return 0;
++} /* End twl_scsi_biosparam() */
++
++/* This is the new scsi eh reset function */
++static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
++{
++	TW_Device_Extension *tw_dev = NULL;
++	int retval = FAILED;
++
++	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
++
++	tw_dev->num_resets++;
++
++	sdev_printk(KERN_WARNING, SCpnt->device,
++		"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
++		TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
++
++	/* Make sure we are not issuing an ioctl or resetting from ioctl */
++	mutex_lock(&tw_dev->ioctl_lock);
++
++	/* Now reset the card and some of the device extension data */
++	if (twl_reset_device_extension(tw_dev, 0)) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "Controller reset failed during scsi host reset");
++		goto out;
++	}
++
++	retval = SUCCESS;
++out:
++	mutex_unlock(&tw_dev->ioctl_lock);
++	return retval;
++} /* End twl_scsi_eh_reset() */
++
++/* This is the main scsi queue function to handle scsi opcodes */
++static int twl_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
++{
++	int request_id, retval;
++	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
++
++	/* If we are resetting due to timed out ioctl, report as busy */
++	if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
++		retval = SCSI_MLQUEUE_HOST_BUSY;
++		goto out;
++	}
++
++	/* Save done function into scsi_cmnd struct */
++	SCpnt->scsi_done = done;
++
++	/* Get a free request id */
++	twl_get_request_id(tw_dev, &request_id);
++
++	/* Save the scsi command for use by the ISR */
++	tw_dev->srb[request_id] = SCpnt;
++
++	/* Initialize phase to zero */
++	SCpnt->SCp.phase = TW_PHASE_INITIAL;
++
++	retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
++	if (retval) {
++		tw_dev->state[request_id] = TW_S_COMPLETED;
++		twl_free_request_id(tw_dev, request_id);
++		SCpnt->result = (DID_ERROR << 16);
++		done(SCpnt);
++		retval = 0;
++	}
++out:
++	return retval;
++} /* End twl_scsi_queue() */
++
++/* This function tells the controller to shut down */
++static void __twl_shutdown(TW_Device_Extension *tw_dev)
++{
++	/* Disable interrupts */
++	TWL_MASK_INTERRUPTS(tw_dev);
++
++	/* Free up the IRQ */
++	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
++
++	printk(KERN_WARNING "3w-sas: Shutting down host %d.\n", tw_dev->host->host_no);
++
++	/* Tell the card we are shutting down */
++	if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Connection shutdown failed");
++	} else {
++		printk(KERN_WARNING "3w-sas: Shutdown complete.\n");
++	}
++
++	/* Clear doorbell interrupt just before exit */
++	TWL_CLEAR_DB_INTERRUPT(tw_dev);
++} /* End __twl_shutdown() */
++
++/* Wrapper for __twl_shutdown */
++static void twl_shutdown(struct pci_dev *pdev)
++{
++	struct Scsi_Host *host = pci_get_drvdata(pdev);
++	TW_Device_Extension *tw_dev;
++
++	if (!host)
++		return;
++
++	tw_dev = (TW_Device_Extension *)host->hostdata;
++
++	if (tw_dev->online)
++		__twl_shutdown(tw_dev);
++} /* End twl_shutdown() */
++
++/* This function configures unit settings when a unit is coming on-line */
++static int twl_slave_configure(struct scsi_device *sdev)
++{
++	/* Force 60 second timeout */
++	blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
++
++	return 0;
++} /* End twl_slave_configure() */
++
++/* scsi_host_template initializer */
++static struct scsi_host_template driver_template = {
++	.module			= THIS_MODULE,
++	.name			= "3w-sas",
++	.queuecommand		= twl_scsi_queue,
++	.eh_host_reset_handler	= twl_scsi_eh_reset,
++	.bios_param		= twl_scsi_biosparam,
++	.change_queue_depth	= twl_change_queue_depth,
++	.can_queue		= TW_Q_LENGTH-2,
++	.slave_configure	= twl_slave_configure,
++	.this_id		= -1,
++	.sg_tablesize		= TW_LIBERATOR_MAX_SGL_LENGTH,
++	.max_sectors		= TW_MAX_SECTORS,
++	.cmd_per_lun		= TW_MAX_CMDS_PER_LUN,
++	.use_clustering		= ENABLE_CLUSTERING,
++	.shost_attrs		= twl_host_attrs,
++	.emulated		= 1
++};
++
++/* This function will probe and initialize a card */
++static int __devinit twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
++{
++	struct Scsi_Host *host = NULL;
++	TW_Device_Extension *tw_dev;
++	resource_size_t mem_addr, mem_len;
++	int retval = -ENODEV;
++	int *ptr_phycount, phycount=0;
++
++	retval = pci_enable_device(pdev);
++	if (retval) {
++		TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
++		goto out_disable_device;
++	}
++
++	pci_set_master(pdev);
++	pci_try_set_mwi(pdev);
++
++	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
++	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
++		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
++		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
++			TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
++			retval = -ENODEV;
++			goto out_disable_device;
++		}
++
++	host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
++	if (!host) {
++		TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
++		retval = -ENOMEM;
++		goto out_disable_device;
++	}
++	tw_dev = (TW_Device_Extension *)host->hostdata;
++
++	/* Save values to device extension */
++	tw_dev->host = host;
++	tw_dev->tw_pci_dev = pdev;
++
++	if (twl_initialize_device_extension(tw_dev)) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
++		goto out_free_device_extension;
++	}
++
++	/* Request IO regions */
++	retval = pci_request_regions(pdev, "3w-sas");
++	if (retval) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
++		goto out_free_device_extension;
++	}
++
++	/* Use region 1 */
++	mem_addr = pci_resource_start(pdev, 1);
++	mem_len = pci_resource_len(pdev, 1);
++
++	/* Save base address */
++	tw_dev->base_addr = ioremap(mem_addr, mem_len);
++
++	if (!tw_dev->base_addr) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
++		goto out_release_mem_region;
++	}
++
++	/* Disable interrupts on the card */
++	TWL_MASK_INTERRUPTS(tw_dev);
++
++	/* Initialize the card */
++	if (twl_reset_sequence(tw_dev, 0)) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
++		goto out_iounmap;
++	}
++
++	/* Set host specific parameters */
++	host->max_id = TW_MAX_UNITS;
++	host->max_cmd_len = TW_MAX_CDB_LEN;
++	host->max_lun = TW_MAX_LUNS;
++	host->max_channel = 0;
++
++	/* Register the card with the kernel SCSI layer */
++	retval = scsi_add_host(host, &pdev->dev);
++	if (retval) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
++		goto out_iounmap;
++	}
++
++	pci_set_drvdata(pdev, host);
++
++	printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
++	       host->host_no,
++	       (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
++				     TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
++	       (u64)mem_addr, pdev->irq);
++
++	ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
++				     TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
++	if (ptr_phycount)
++		phycount = le32_to_cpu(*(int *)ptr_phycount);
++
++	printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
++	       host->host_no,
++	       (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
++				     TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
++	       (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
++				     TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
++	       phycount);
++
++	/* Try to enable MSI */
++	if (use_msi && !pci_enable_msi(pdev))
++		set_bit(TW_USING_MSI, &tw_dev->flags);
++
++	/* Now setup the interrupt handler */
++	retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
++	if (retval) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
++		goto out_remove_host;
++	}
++
++	twl_device_extension_list[twl_device_extension_count] = tw_dev;
++	twl_device_extension_count++;
++
++	/* Re-enable interrupts on the card */
++	TWL_UNMASK_INTERRUPTS(tw_dev);
++
++	/* Finally, scan the host */
++	scsi_scan_host(host);
++
++	/* Add sysfs binary files */
++	if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
++	if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
++
++	if (twl_major == -1) {
++		if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
++			TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
++	}
++	tw_dev->online = 1;
++	return 0;
++
++out_remove_host:
++	if (test_bit(TW_USING_MSI, &tw_dev->flags))
++		pci_disable_msi(pdev);
++	scsi_remove_host(host);
++out_iounmap:
++	iounmap(tw_dev->base_addr);
++out_release_mem_region:
++	pci_release_regions(pdev);
++out_free_device_extension:
++	twl_free_device_extension(tw_dev);
++	scsi_host_put(host);
++out_disable_device:
++	pci_disable_device(pdev);
++
++	return retval;
++} /* End twl_probe() */
++
++/* This function is called to remove a device */
++static void twl_remove(struct pci_dev *pdev)
++{
++	struct Scsi_Host *host = pci_get_drvdata(pdev);
++	TW_Device_Extension *tw_dev;
++
++	if (!host)
++		return;
++
++	tw_dev = (TW_Device_Extension *)host->hostdata;
++
++	if (!tw_dev->online)
++		return;
++
++	/* Remove sysfs binary files */
++	sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
++	sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
++
++	scsi_remove_host(tw_dev->host);
++
++	/* Unregister character device */
++	if (twl_major >= 0) {
++		unregister_chrdev(twl_major, "twl");
++		twl_major = -1;
++	}
++
++	/* Shutdown the card */
++	__twl_shutdown(tw_dev);
++
++	/* Disable MSI if enabled */
++	if (test_bit(TW_USING_MSI, &tw_dev->flags))
++		pci_disable_msi(pdev);
++
++	/* Free IO remapping */
++	iounmap(tw_dev->base_addr);
++
++	/* Free up the mem region */
++	pci_release_regions(pdev);
++
++	/* Free up device extension resources */
++	twl_free_device_extension(tw_dev);
++
++	scsi_host_put(tw_dev->host);
++	pci_disable_device(pdev);
++	twl_device_extension_count--;
++} /* End twl_remove() */
++
++#ifdef CONFIG_PM
++/* This function is called on PCI suspend */
++static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
++{
++	struct Scsi_Host *host = pci_get_drvdata(pdev);
++	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
++
++	printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
++	/* Disable interrupts */
++	TWL_MASK_INTERRUPTS(tw_dev);
++
++	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
++
++	/* Tell the card we are shutting down */
++	if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
++	} else {
++		printk(KERN_WARNING "3w-sas: Suspend complete.\n");
++	}
++
++	/* Clear doorbell interrupt */
++	TWL_CLEAR_DB_INTERRUPT(tw_dev);
++
++	pci_save_state(pdev);
++	pci_disable_device(pdev);
++	pci_set_power_state(pdev, pci_choose_state(pdev, state));
++
++	return 0;
++} /* End twl_suspend() */
++
++/* This function is called on PCI resume */
++static int twl_resume(struct pci_dev *pdev)
++{
++	int retval = 0;
++	struct Scsi_Host *host = pci_get_drvdata(pdev);
++	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
++
++	printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
++	pci_set_power_state(pdev, PCI_D0);
++	pci_enable_wake(pdev, PCI_D0, 0);
++	pci_restore_state(pdev);
++
++	retval = pci_enable_device(pdev);
++	if (retval) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
++		return retval;
++	}
++
++	pci_set_master(pdev);
++	pci_try_set_mwi(pdev);
++
++	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
++	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
++		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
++		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
++			TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
++			retval = -ENODEV;
++			goto out_disable_device;
++		}
++
++	/* Initialize the card */
++	if (twl_reset_sequence(tw_dev, 0)) {
++		retval = -ENODEV;
++		goto out_disable_device;
++	}
++
++	/* Now setup the interrupt handler */
++	retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
++	if (retval) {
++		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
++		retval = -ENODEV;
++		goto out_disable_device;
++	}
++
++	/* Now enable MSI if enabled */
++	if (test_bit(TW_USING_MSI, &tw_dev->flags))
++		pci_enable_msi(pdev);
++
++	/* Re-enable interrupts on the card */
++	TWL_UNMASK_INTERRUPTS(tw_dev);
++
++	printk(KERN_WARNING "3w-sas: Resume complete.\n");
++	return 0;
++
++out_disable_device:
++	scsi_remove_host(host);
++	pci_disable_device(pdev);
++
++	return retval;
++} /* End twl_resume() */
++#endif
++
++/* PCI Devices supported by this driver */
++static struct pci_device_id twl_pci_tbl[] __devinitdata = {
++	{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9750,
++	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++	{ }
++};
++MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
++
++/* pci_driver initializer */
++static struct pci_driver twl_driver = {
++	.name		= "3w-sas",
++	.id_table	= twl_pci_tbl,
++	.probe		= twl_probe,
++	.remove		= twl_remove,
++#ifdef CONFIG_PM
++	.suspend	= twl_suspend,
++	.resume		= twl_resume,
++#endif
++	.shutdown	= twl_shutdown
++};
++
++/* This function is called on driver initialization */
++static int __init twl_init(void)
++{
++	printk(KERN_WARNING "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
++
++	return pci_register_driver(&twl_driver);
++} /* End twl_init() */
++
++/* This function is called on driver exit */
++static void __exit twl_exit(void)
++{
++	pci_unregister_driver(&twl_driver);
++} /* End twl_exit() */
++
++module_init(twl_init);
++module_exit(twl_exit);
++
+diff --git a/drivers/scsi/3w-sas.h b/drivers/scsi/3w-sas.h
+new file mode 100644
+index 0000000..e620505
+--- /dev/null
++++ b/drivers/scsi/3w-sas.h
+@@ -0,0 +1,396 @@
++/*
++   3w-sas.h -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
++
++   Written By: Adam Radford <linuxraid@lsi.com>
++
++   Copyright (C) 2009 LSI Corporation.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; version 2 of the License.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   NO WARRANTY
++   THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
++   CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
++   LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
++   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
++   solely responsible for determining the appropriateness of using and
++   distributing the Program and assumes all risks associated with its
++   exercise of rights under this Agreement, including but not limited to
++   the risks and costs of program errors, damage to or loss of data,
++   programs or equipment, and unavailability or interruption of operations.
++
++   DISCLAIMER OF LIABILITY
++   NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
++   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++   DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
++   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
++   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++   USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
++   HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++
++   Bugs/Comments/Suggestions should be mailed to:
++   linuxraid@lsi.com
++
++   For more information, goto:
++   http://www.lsi.com
++*/
++
++#ifndef _3W_SAS_H
++#define _3W_SAS_H
++
++/* AEN severity table */
++static char *twl_aen_severity_table[] =
++{
++	"None", "ERROR", "WARNING", "INFO", "DEBUG", (char*) 0
++};
++
++/* Liberator register offsets */
++#define TWL_STATUS                         0x0  /* Status */
++#define TWL_HIBDB                          0x20 /* Inbound doorbell */
++#define TWL_HISTAT                         0x30 /* Host interrupt status */
++#define TWL_HIMASK                         0x34 /* Host interrupt mask */
++#define TWL_HOBDB			   0x9C /* Outbound doorbell */
++#define TWL_HOBDBC                         0xA0 /* Outbound doorbell clear */
++#define TWL_SCRPD3                         0xBC /* Scratchpad */
++#define TWL_HIBQPL                         0xC0 /* Host inbound Q low */
++#define TWL_HIBQPH                         0xC4 /* Host inbound Q high */
++#define TWL_HOBQPL                         0xC8 /* Host outbound Q low */
++#define TWL_HOBQPH                         0xCC /* Host outbound Q high */
++#define TWL_HISTATUS_VALID_INTERRUPT	   0xC
++#define TWL_HISTATUS_ATTENTION_INTERRUPT   0x4
++#define TWL_HISTATUS_RESPONSE_INTERRUPT	   0x8
++#define TWL_STATUS_OVERRUN_SUBMIT	   0x2000
++#define TWL_ISSUE_SOFT_RESET		   0x100
++#define TWL_CONTROLLER_READY		   0x2000
++#define TWL_DOORBELL_CONTROLLER_ERROR	   0x200000
++#define TWL_DOORBELL_ATTENTION_INTERRUPT   0x40000
++#define TWL_PULL_MODE			   0x1
++
++/* Command packet opcodes used by the driver */
++#define TW_OP_INIT_CONNECTION 0x1
++#define TW_OP_GET_PARAM	      0x12
++#define TW_OP_SET_PARAM	      0x13
++#define TW_OP_EXECUTE_SCSI    0x10
++
++/* Asynchronous Event Notification (AEN) codes used by the driver */
++#define TW_AEN_QUEUE_EMPTY       0x0000
++#define TW_AEN_SOFT_RESET        0x0001
++#define TW_AEN_SYNC_TIME_WITH_HOST 0x031
++#define TW_AEN_SEVERITY_ERROR    0x1
++#define TW_AEN_SEVERITY_DEBUG    0x4
++#define TW_AEN_NOT_RETRIEVED 0x1
++
++/* Command state defines */
++#define TW_S_INITIAL   0x1  /* Initial state */
++#define TW_S_STARTED   0x2  /* Id in use */
++#define TW_S_POSTED    0x4  /* Posted to the controller */
++#define TW_S_COMPLETED 0x8  /* Completed by isr */
++#define TW_S_FINISHED  0x10 /* I/O completely done */
++
++/* Compatibility defines */
++#define TW_9750_ARCH_ID 10
++#define TW_CURRENT_DRIVER_SRL 40
++#define TW_CURRENT_DRIVER_BUILD 0
++#define TW_CURRENT_DRIVER_BRANCH 0
++
++/* Phase defines */
++#define TW_PHASE_INITIAL 0
++#define TW_PHASE_SGLIST  2
++
++/* Misc defines */
++#define TW_SECTOR_SIZE                        512
++#define TW_MAX_UNITS			      32
++#define TW_INIT_MESSAGE_CREDITS		      0x100
++#define TW_INIT_COMMAND_PACKET_SIZE	      0x3
++#define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED  0x6
++#define TW_EXTENDED_INIT_CONNECT	      0x2
++#define TW_BASE_FW_SRL			      24
++#define TW_BASE_FW_BRANCH		      0
++#define TW_BASE_FW_BUILD		      1
++#define TW_Q_LENGTH			      256
++#define TW_Q_START			      0
++#define TW_MAX_SLOT			      32
++#define TW_MAX_RESET_TRIES		      2
++#define TW_MAX_CMDS_PER_LUN		      254
++#define TW_MAX_AEN_DRAIN		      255
++#define TW_IN_RESET                           2
++#define TW_USING_MSI			      3
++#define TW_IN_ATTENTION_LOOP		      4
++#define TW_MAX_SECTORS                        256
++#define TW_MAX_CDB_LEN                        16
++#define TW_IOCTL_CHRDEV_TIMEOUT               60 /* 60 seconds */
++#define TW_IOCTL_CHRDEV_FREE                  -1
++#define TW_COMMAND_OFFSET                     128 /* 128 bytes */
++#define TW_VERSION_TABLE                      0x0402
++#define TW_TIMEKEEP_TABLE		      0x040A
++#define TW_INFORMATION_TABLE		      0x0403
++#define TW_PARAM_FWVER			      3
++#define TW_PARAM_FWVER_LENGTH		      16
++#define TW_PARAM_BIOSVER		      4
++#define TW_PARAM_BIOSVER_LENGTH		      16
++#define TW_PARAM_MODEL			      8
++#define TW_PARAM_MODEL_LENGTH		      16
++#define TW_PARAM_PHY_SUMMARY_TABLE	      1
++#define TW_PARAM_PHYCOUNT		      2
++#define TW_PARAM_PHYCOUNT_LENGTH	      1
++#define TW_IOCTL_FIRMWARE_PASS_THROUGH        0x108  // Used by smartmontools
++#define TW_ALLOCATION_LENGTH		      128
++#define TW_SENSE_DATA_LENGTH		      18
++#define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED   0x10a
++#define TW_ERROR_INVALID_FIELD_IN_CDB	      0x10d
++#define TW_ERROR_UNIT_OFFLINE                 0x128
++#define TW_MESSAGE_SOURCE_CONTROLLER_ERROR    3
++#define TW_MESSAGE_SOURCE_CONTROLLER_EVENT    4
++#define TW_DRIVER 			      6
++#ifndef PCI_DEVICE_ID_3WARE_9750
++#define PCI_DEVICE_ID_3WARE_9750 0x1010
++#endif
++
++/* Bitmask macros to eliminate bitfields */
++
++/* opcode: 5, reserved: 3 */
++#define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f))
++#define TW_OP_OUT(x) (x & 0x1f)
++
++/* opcode: 5, sgloffset: 3 */
++#define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))
++#define TW_SGL_OUT(x) ((x >> 5) & 0x7)
++
++/* severity: 3, reserved: 5 */
++#define TW_SEV_OUT(x) (x & 0x7)
++
++/* not_mfa: 1, reserved: 7, status: 8, request_id: 16 */
++#define TW_RESID_OUT(x) ((x >> 16) & 0xffff)
++#define TW_NOTMFA_OUT(x) (x & 0x1)
++
++/* request_id: 12, lun: 4 */
++#define TW_REQ_LUN_IN(lun, request_id) (((lun << 12) & 0xf000) | (request_id & 0xfff))
++#define TW_LUN_OUT(lun) ((lun >> 12) & 0xf)
++
++/* Register access macros */
++#define TWL_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_STATUS)
++#define TWL_HOBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPL)
++#define TWL_HOBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPH)
++#define TWL_HOBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDB)
++#define TWL_HOBDBC_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDBC)
++#define TWL_HIMASK_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIMASK)
++#define TWL_HISTAT_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HISTAT)
++#define TWL_HIBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPH)
++#define TWL_HIBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPL)
++#define TWL_HIBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBDB)
++#define TWL_SCRPD3_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_SCRPD3)
++#define TWL_MASK_INTERRUPTS(x) (writel(~0, TWL_HIMASK_REG_ADDR(tw_dev)))
++#define TWL_UNMASK_INTERRUPTS(x) (writel(~TWL_HISTATUS_VALID_INTERRUPT, TWL_HIMASK_REG_ADDR(tw_dev)))
++#define TWL_CLEAR_DB_INTERRUPT(x) (writel(~0, TWL_HOBDBC_REG_ADDR(tw_dev)))
++#define TWL_SOFT_RESET(x) (writel(TWL_ISSUE_SOFT_RESET, TWL_HIBDB_REG_ADDR(tw_dev)))
++
++/* Macros */
++#define TW_PRINTK(h,a,b,c) { \
++if (h) \
++printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \
++else \
++printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \
++}
++#define TW_MAX_LUNS 16
++#define TW_COMMAND_SIZE (sizeof(dma_addr_t) > 4 ? 6 : 4)
++#define TW_LIBERATOR_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 46 : 92)
++#define TW_LIBERATOR_MAX_SGL_LENGTH_OLD (sizeof(dma_addr_t) > 4 ? 47 : 94)
++#define TW_PADDING_LENGTH_LIBERATOR 136
++#define TW_PADDING_LENGTH_LIBERATOR_OLD 132
++#define TW_CPU_TO_SGL(x) (sizeof(dma_addr_t) > 4 ? cpu_to_le64(x) : cpu_to_le32(x))
++
++#pragma pack(1)
++
++/* SGL entry */
++typedef struct TAG_TW_SG_Entry_ISO {
++	dma_addr_t address;
++	dma_addr_t length;
++} TW_SG_Entry_ISO;
++
++/* Old Command Packet with ISO SGL */
++typedef struct TW_Command {
++	unsigned char opcode__sgloffset;
++	unsigned char size;
++	unsigned char request_id;
++	unsigned char unit__hostid;
++	/* Second DWORD */
++	unsigned char status;
++	unsigned char flags;
++	union {
++		unsigned short block_count;
++		unsigned short parameter_count;
++	} byte6_offset;
++	union {
++		struct {
++			u32 lba;
++			TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];
++			unsigned char padding[TW_PADDING_LENGTH_LIBERATOR_OLD];
++		} io;
++		struct {
++			TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];
++			u32 padding;
++			unsigned char padding2[TW_PADDING_LENGTH_LIBERATOR_OLD];
++		} param;
++	} byte8_offset;
++} TW_Command;
++
++/* New Command Packet with ISO SGL */
++typedef struct TAG_TW_Command_Apache {
++	unsigned char opcode__reserved;
++	unsigned char unit;
++	unsigned short request_id__lunl;
++	unsigned char status;
++	unsigned char sgl_offset;
++	unsigned short sgl_entries__lunh;
++	unsigned char cdb[16];
++	TW_SG_Entry_ISO sg_list[TW_LIBERATOR_MAX_SGL_LENGTH];
++	unsigned char padding[TW_PADDING_LENGTH_LIBERATOR];
++} TW_Command_Apache;
++
++/* New command packet header */
++typedef struct TAG_TW_Command_Apache_Header {
++	unsigned char sense_data[TW_SENSE_DATA_LENGTH];
++	struct {
++		char reserved[4];
++		unsigned short error;
++		unsigned char padding;
++		unsigned char severity__reserved;
++	} status_block;
++	unsigned char err_specific_desc[98];
++	struct {
++		unsigned char size_header;
++		unsigned short request_id;
++		unsigned char size_sense;
++	} header_desc;
++} TW_Command_Apache_Header;
++
++/* This struct is a union of the 2 command packets */
++typedef struct TAG_TW_Command_Full {
++	TW_Command_Apache_Header header;
++	union {
++		TW_Command oldcommand;
++		TW_Command_Apache newcommand;
++	} command;
++} TW_Command_Full;
++
++/* Initconnection structure */
++typedef struct TAG_TW_Initconnect {
++	unsigned char opcode__reserved;
++	unsigned char size;
++	unsigned char request_id;
++	unsigned char res2;
++	unsigned char status;
++	unsigned char flags;
++	unsigned short message_credits;
++	u32 features;
++	unsigned short fw_srl;
++	unsigned short fw_arch_id;
++	unsigned short fw_branch;
++	unsigned short fw_build;
++	u32 result;
++} TW_Initconnect;
++
++/* Event info structure */
++typedef struct TAG_TW_Event
++{
++	unsigned int sequence_id;
++	unsigned int time_stamp_sec;
++	unsigned short aen_code;
++	unsigned char severity;
++	unsigned char retrieved;
++	unsigned char repeat_count;
++	unsigned char parameter_len;
++	unsigned char parameter_data[98];
++} TW_Event;
++
++typedef struct TAG_TW_Ioctl_Driver_Command {
++	unsigned int control_code;
++	unsigned int status;
++	unsigned int unique_id;
++	unsigned int sequence_id;
++	unsigned int os_specific;
++	unsigned int buffer_length;
++} TW_Ioctl_Driver_Command;
++
++typedef struct TAG_TW_Ioctl_Apache {
++	TW_Ioctl_Driver_Command driver_command;
++        char padding[488];
++	TW_Command_Full firmware_command;
++	char data_buffer[1];
++} TW_Ioctl_Buf_Apache;
++
++/* GetParam descriptor */
++typedef struct {
++	unsigned short	table_id;
++	unsigned short	parameter_id;
++	unsigned short	parameter_size_bytes;
++	unsigned short  actual_parameter_size_bytes;
++	unsigned char	data[1];
++} TW_Param_Apache;
++
++/* Compatibility information structure */
++typedef struct TAG_TW_Compatibility_Info
++{
++	char driver_version[32];
++	unsigned short working_srl;
++	unsigned short working_branch;
++	unsigned short working_build;
++	unsigned short driver_srl_high;
++	unsigned short driver_branch_high;
++	unsigned short driver_build_high;
++	unsigned short driver_srl_low;
++	unsigned short driver_branch_low;
++	unsigned short driver_build_low;
++	unsigned short fw_on_ctlr_srl;
++	unsigned short fw_on_ctlr_branch;
++	unsigned short fw_on_ctlr_build;
++} TW_Compatibility_Info;
++
++#pragma pack()
++
++typedef struct TAG_TW_Device_Extension {
++	void                     __iomem *base_addr;
++	unsigned long	       	*generic_buffer_virt[TW_Q_LENGTH];
++	dma_addr_t	       	generic_buffer_phys[TW_Q_LENGTH];
++	TW_Command_Full	       	*command_packet_virt[TW_Q_LENGTH];
++	dma_addr_t		command_packet_phys[TW_Q_LENGTH];
++	TW_Command_Apache_Header *sense_buffer_virt[TW_Q_LENGTH];
++	dma_addr_t		sense_buffer_phys[TW_Q_LENGTH];
++	struct pci_dev		*tw_pci_dev;
++	struct scsi_cmnd	*srb[TW_Q_LENGTH];
++	unsigned char		free_queue[TW_Q_LENGTH];
++	unsigned char		free_head;
++	unsigned char		free_tail;
++	int     		state[TW_Q_LENGTH];
++	unsigned int		posted_request_count;
++	unsigned int		max_posted_request_count;
++	unsigned int		max_sgl_entries;
++	unsigned int		sgl_entries;
++	unsigned int		num_resets;
++	unsigned int		sector_count;
++	unsigned int		max_sector_count;
++	unsigned int		aen_count;
++	struct Scsi_Host	*host;
++	long			flags;
++	TW_Event                *event_queue[TW_Q_LENGTH];
++	unsigned char           error_index;
++	unsigned int            error_sequence_id;
++	int			chrdev_request_id;
++	wait_queue_head_t	ioctl_wqueue;
++	struct mutex		ioctl_lock;
++	TW_Compatibility_Info	tw_compat_info;
++	char			online;
++} TW_Device_Extension;
++
++#endif /* _3W_SAS_H */
++
+diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
+index 1ddcf40..a85f062 100644
+--- a/drivers/scsi/BusLogic.c
++++ b/drivers/scsi/BusLogic.c
+@@ -961,6 +961,8 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda
+ static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
+ 						    *PrototypeHostAdapter)
+ {
++	pax_track_stack();
++
+ 	/*
+ 	   If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
+ 	   Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
+diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
+index e11cca4..4295679 100644
+--- a/drivers/scsi/Kconfig
++++ b/drivers/scsi/Kconfig
+@@ -399,6 +399,17 @@ config SCSI_3W_9XXX
+ 	  Please read the comments at the top of
+ 	  <file:drivers/scsi/3w-9xxx.c>.
+ 
++config SCSI_3W_SAS
++	tristate "3ware 97xx SAS/SATA-RAID support"
++	depends on PCI && SCSI
++	help
++	  This driver supports the LSI 3ware 9750 6Gb/s SAS/SATA-RAID cards.
++
++	  <http://www.lsi.com>
++
++	  Please read the comments at the top of
++	  <file:drivers/scsi/3w-sas.c>.
++
+ config SCSI_7000FASST
+ 	tristate "7000FASST SCSI support"
+ 	depends on ISA && SCSI && ISA_DMA_API
+@@ -621,6 +632,14 @@ config SCSI_FLASHPOINT
+ 	  substantial, so users of MultiMaster Host Adapters may not
+ 	  wish to include it.
+ 
++config VMWARE_PVSCSI
++	tristate "VMware PVSCSI driver support"
++	depends on PCI && SCSI && X86
++	help
++	  This driver supports VMware's para virtualized SCSI HBA.
++	  To compile this driver as a module, choose M here: the
++	  module will be called vmw_pvscsi.
++
+ config LIBFC
+ 	tristate "LibFC module"
+ 	select SCSI_FC_ATTRS
+diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
+index 3ad61db..c938975 100644
+--- a/drivers/scsi/Makefile
++++ b/drivers/scsi/Makefile
+@@ -113,6 +113,7 @@ obj-$(CONFIG_SCSI_MESH)		+= mesh.o
+ obj-$(CONFIG_SCSI_MAC53C94)	+= mac53c94.o
+ obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
+ obj-$(CONFIG_SCSI_3W_9XXX)	+= 3w-9xxx.o
++obj-$(CONFIG_SCSI_3W_SAS)       += 3w-sas.o
+ obj-$(CONFIG_SCSI_PPA)		+= ppa.o
+ obj-$(CONFIG_SCSI_IMM)		+= imm.o
+ obj-$(CONFIG_JAZZ_ESP)		+= esp_scsi.o	jazz_esp.o
+@@ -133,6 +134,7 @@ obj-$(CONFIG_SCSI_CXGB3_ISCSI)	+= libiscsi.o libiscsi_tcp.o cxgb3i/
+ obj-$(CONFIG_SCSI_BNX2_ISCSI)	+= libiscsi.o bnx2i/
+ obj-$(CONFIG_BE2ISCSI)		+= libiscsi.o be2iscsi/
+ obj-$(CONFIG_SCSI_PMCRAID)	+= pmcraid.o
++obj-$(CONFIG_VMWARE_PVSCSI)	+= vmw_pvscsi.o
+ 
+ obj-$(CONFIG_ARM)		+= arm/
+ 
+diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
+index cdbdec9..b7d560b 100644
+--- a/drivers/scsi/aacraid/aacraid.h
++++ b/drivers/scsi/aacraid/aacraid.h
+@@ -471,7 +471,7 @@ struct adapter_ops
+ 	int  (*adapter_scsi)(struct fib * fib, struct scsi_cmnd * cmd);
+ 	/* Administrative operations */
+ 	int  (*adapter_comm)(struct aac_dev * dev, int comm);
+-};
++} __no_const;
+ 
+ /*
+  *	Define which interrupt handler needs to be installed
+diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
+index a5b8e7b..a6a0e43 100644
+--- a/drivers/scsi/aacraid/commctrl.c
++++ b/drivers/scsi/aacraid/commctrl.c
+@@ -481,6 +481,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
+ 	u32 actual_fibsize64, actual_fibsize = 0;
+ 	int i;
+ 
++	pax_track_stack();
+ 
+ 	if (dev->in_reset) {
+ 		dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n"));
+diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
+index 9b97c3e..f099725 100644
+--- a/drivers/scsi/aacraid/linit.c
++++ b/drivers/scsi/aacraid/linit.c
+@@ -91,7 +91,7 @@ static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = {
+ #elif defined(__devinitconst)
+ static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
+ #else
+-static const struct pci_device_id aac_pci_tbl[] __devinitdata = {
++static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
+ #endif
+ 	{ 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */
+ 	{ 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */
+diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
+index 996f722..9127845 100644
+--- a/drivers/scsi/aic94xx/aic94xx_init.c
++++ b/drivers/scsi/aic94xx/aic94xx_init.c
+@@ -485,7 +485,7 @@ static ssize_t asd_show_update_bios(struct device *dev,
+ 			flash_error_table[i].reason);
+ }
+ 
+-static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUGO,
++static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUSR,
+ 	asd_show_update_bios, asd_store_update_bios);
+ 
+ static int asd_create_dev_attrs(struct asd_ha_struct *asd_ha)
+@@ -1011,7 +1011,7 @@ static struct sas_domain_function_template aic94xx_transport_functions = {
+ 	.lldd_control_phy	= asd_control_phy,
+ };
+ 
+-static const struct pci_device_id aic94xx_pci_table[] __devinitdata = {
++static const struct pci_device_id aic94xx_pci_table[] __devinitconst = {
+ 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x410),0, 0, 1},
+ 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x412),0, 0, 1},
+ 	{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x416),0, 0, 1},
+diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
+index 58efd4b..cb48dc7 100644
+--- a/drivers/scsi/bfa/bfa_ioc.h
++++ b/drivers/scsi/bfa/bfa_ioc.h
+@@ -127,7 +127,7 @@ struct bfa_ioc_cbfn_s {
+ 	bfa_ioc_disable_cbfn_t	disable_cbfn;
+ 	bfa_ioc_hbfail_cbfn_t	hbfail_cbfn;
+ 	bfa_ioc_reset_cbfn_t	reset_cbfn;
+-};
++} __no_const;
+ 
+ /**
+  * Heartbeat failure notification queue element.
+diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h
+index 7ad177e..5503586 100644
+--- a/drivers/scsi/bfa/bfa_iocfc.h
++++ b/drivers/scsi/bfa/bfa_iocfc.h
+@@ -61,7 +61,7 @@ struct bfa_hwif_s {
+ 	void (*hw_isr_mode_set)(struct bfa_s *bfa, bfa_boolean_t msix);
+ 	void (*hw_msix_getvecs)(struct bfa_s *bfa, u32 *vecmap,
+ 			u32 *nvecs, u32 *maxvec);
+-};
++} __no_const;
+ typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status);
+ 
+ struct bfa_iocfc_s {
+diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
+index 4967643..cbec06b 100644
+--- a/drivers/scsi/dpt_i2o.c
++++ b/drivers/scsi/dpt_i2o.c
+@@ -1804,6 +1804,8 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
+ 	dma_addr_t addr;
+ 	ulong flags = 0;
+ 
++	pax_track_stack();
++
+ 	memset(&msg, 0, MAX_MESSAGE_SIZE*4);
+ 	// get user msg size in u32s 
+ 	if(get_user(size, &user_msg[0])){
+@@ -2297,6 +2299,8 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
+ 	s32 rcode;
+ 	dma_addr_t addr;
+ 
++	pax_track_stack();
++
+ 	memset(msg, 0 , sizeof(msg));
+ 	len = scsi_bufflen(cmd);
+ 	direction = 0x00000000;	
+diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
+index c7076ce..e20c67c 100644
+--- a/drivers/scsi/eata.c
++++ b/drivers/scsi/eata.c
+@@ -1087,6 +1087,8 @@ static int port_detect(unsigned long port_base, unsigned int j,
+ 	struct hostdata *ha;
+ 	char name[16];
+ 
++	pax_track_stack();
++
+ 	sprintf(name, "%s%d", driver_name, j);
+ 
+ 	if (!request_region(port_base, REGION_SIZE, driver_name)) {
+diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
+index 11ae5c9..891daec 100644
+--- a/drivers/scsi/fcoe/libfcoe.c
++++ b/drivers/scsi/fcoe/libfcoe.c
+@@ -809,6 +809,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
+ 	size_t rlen;
+ 	size_t dlen;
+ 
++	pax_track_stack();
++
+ 	fiph = (struct fip_header *)skb->data;
+ 	sub = fiph->fip_subcode;
+ 	if (sub != FIP_SC_REQ && sub != FIP_SC_REP)
+diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
+index 71c7bbe..e93088a 100644
+--- a/drivers/scsi/fnic/fnic_main.c
++++ b/drivers/scsi/fnic/fnic_main.c
+@@ -669,7 +669,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
+ 	/* Start local port initiatialization */
+ 
+ 	lp->link_up = 0;
+-	lp->tt = fnic_transport_template;
++	memcpy((void *)&lp->tt, &fnic_transport_template, sizeof(fnic_transport_template));
+ 
+ 	lp->max_retry_count = fnic->config.flogi_retries;
+ 	lp->max_rport_retry_count = fnic->config.plogi_retries;
+diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
+index bb96d74..9ec3ce4 100644
+--- a/drivers/scsi/gdth.c
++++ b/drivers/scsi/gdth.c
+@@ -4102,6 +4102,8 @@ static int ioc_lockdrv(void __user *arg)
+     ulong flags;
+     gdth_ha_str *ha;
+ 
++    pax_track_stack();
++
+     if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)))
+         return -EFAULT;
+     ha = gdth_find_ha(ldrv.ionode);
+@@ -4134,6 +4136,8 @@ static int ioc_resetdrv(void __user *arg, char *cmnd)
+     gdth_ha_str *ha;
+     int rval;
+ 
++    pax_track_stack();
++
+     if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) ||
+         res.number >= MAX_HDRIVES)
+         return -EFAULT;
+@@ -4169,6 +4173,8 @@ static int ioc_general(void __user *arg, char *cmnd)
+     gdth_ha_str *ha;
+     int rval;
+ 
++    pax_track_stack();
++
+     if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)))
+         return -EFAULT;
+     ha = gdth_find_ha(gen.ionode);
+@@ -4625,6 +4631,9 @@ static void gdth_flush(gdth_ha_str *ha)
+     int             i;
+     gdth_cmd_str    gdtcmd;
+     char            cmnd[MAX_COMMAND_SIZE];   
++
++    pax_track_stack();
++
+     memset(cmnd, 0xff, MAX_COMMAND_SIZE);
+ 
+     TRACE2(("gdth_flush() hanum %d\n", ha->hanum));
+diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
+index 1258da3..20d8ae6 100644
+--- a/drivers/scsi/gdth_proc.c
++++ b/drivers/scsi/gdth_proc.c
+@@ -46,6 +46,9 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
+     ulong64         paddr;
+ 
+     char            cmnd[MAX_COMMAND_SIZE];
++
++    pax_track_stack();
++
+     memset(cmnd, 0xff, 12);
+     memset(&gdtcmd, 0, sizeof(gdth_cmd_str));
+ 
+@@ -174,6 +177,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
+     gdth_hget_str *phg;
+     char cmnd[MAX_COMMAND_SIZE];
+ 
++    pax_track_stack();
++
+     gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL);
+     estr = kmalloc(sizeof(*estr), GFP_KERNEL);
+     if (!gdtcmd || !estr)
+diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
+index d03a926..f324286 100644
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -40,7 +40,7 @@
+ #include "scsi_logging.h"
+ 
+ 
+-static atomic_t scsi_host_next_hn;	/* host_no for next new host */
++static atomic_unchecked_t scsi_host_next_hn;	/* host_no for next new host */
+ 
+ 
+ static void scsi_host_cls_release(struct device *dev)
+@@ -347,7 +347,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
+ 	 * subtract one because we increment first then return, but we need to
+ 	 * know what the next host number was before increment
+ 	 */
+-	shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1;
++	shost->host_no = atomic_inc_return_unchecked(&scsi_host_next_hn) - 1;
+ 	shost->dma_channel = 0xff;
+ 
+ 	/* These three are default values which can be overridden */
+diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
+index a601159..55e19d2 100644
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -5286,7 +5286,7 @@ static bool ipr_qc_fill_rtf(struct ata_queued_cmd *qc)
+ 	return true;
+ }
+ 
+-static struct ata_port_operations ipr_sata_ops = {
++static const struct ata_port_operations ipr_sata_ops = {
+ 	.phy_reset = ipr_ata_phy_reset,
+ 	.hardreset = ipr_sata_reset,
+ 	.post_internal_cmd = ipr_ata_post_internal,
+diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
+index 4e49fbc..97907ff 100644
+--- a/drivers/scsi/ips.h
++++ b/drivers/scsi/ips.h
+@@ -1027,7 +1027,7 @@ typedef struct {
+    int       (*intr)(struct ips_ha *);
+    void      (*enableint)(struct ips_ha *);
+    uint32_t (*statupd)(struct ips_ha *);
+-} ips_hw_func_t;
++} __no_const ips_hw_func_t;
+ 
+ typedef struct ips_ha {
+    uint8_t            ha_id[IPS_MAX_CHANNELS+1];
+diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
+index c1c1574..a9c9348 100644
+--- a/drivers/scsi/libfc/fc_exch.c
++++ b/drivers/scsi/libfc/fc_exch.c
+@@ -86,12 +86,12 @@ struct fc_exch_mgr {
+ 	 * all together if not used XXX
+ 	 */
+ 	struct {
+-		atomic_t no_free_exch;
+-		atomic_t no_free_exch_xid;
+-		atomic_t xid_not_found;
+-		atomic_t xid_busy;
+-		atomic_t seq_not_found;
+-		atomic_t non_bls_resp;
++		atomic_unchecked_t no_free_exch;
++		atomic_unchecked_t no_free_exch_xid;
++		atomic_unchecked_t xid_not_found;
++		atomic_unchecked_t xid_busy;
++		atomic_unchecked_t seq_not_found;
++		atomic_unchecked_t non_bls_resp;
+ 	} stats;
+ };
+ #define	fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
+@@ -510,7 +510,7 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
+ 	/* allocate memory for exchange */
+ 	ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
+ 	if (!ep) {
+-		atomic_inc(&mp->stats.no_free_exch);
++		atomic_inc_unchecked(&mp->stats.no_free_exch);
+ 		goto out;
+ 	}
+ 	memset(ep, 0, sizeof(*ep));
+@@ -557,7 +557,7 @@ out:
+ 	return ep;
+ err:
+ 	spin_unlock_bh(&pool->lock);
+-	atomic_inc(&mp->stats.no_free_exch_xid);
++	atomic_inc_unchecked(&mp->stats.no_free_exch_xid);
+ 	mempool_free(ep, mp->ep_pool);
+ 	return NULL;
+ }
+@@ -690,7 +690,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
+ 		xid = ntohs(fh->fh_ox_id);	/* we originated exch */
+ 		ep = fc_exch_find(mp, xid);
+ 		if (!ep) {
+-			atomic_inc(&mp->stats.xid_not_found);
++			atomic_inc_unchecked(&mp->stats.xid_not_found);
+ 			reject = FC_RJT_OX_ID;
+ 			goto out;
+ 		}
+@@ -720,7 +720,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
+ 		ep = fc_exch_find(mp, xid);
+ 		if ((f_ctl & FC_FC_FIRST_SEQ) && fc_sof_is_init(fr_sof(fp))) {
+ 			if (ep) {
+-				atomic_inc(&mp->stats.xid_busy);
++				atomic_inc_unchecked(&mp->stats.xid_busy);
+ 				reject = FC_RJT_RX_ID;
+ 				goto rel;
+ 			}
+@@ -731,7 +731,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
+ 			}
+ 			xid = ep->xid;	/* get our XID */
+ 		} else if (!ep) {
+-			atomic_inc(&mp->stats.xid_not_found);
++			atomic_inc_unchecked(&mp->stats.xid_not_found);
+ 			reject = FC_RJT_RX_ID;	/* XID not found */
+ 			goto out;
+ 		}
+@@ -752,7 +752,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
+ 	} else {
+ 		sp = &ep->seq;
+ 		if (sp->id != fh->fh_seq_id) {
+-			atomic_inc(&mp->stats.seq_not_found);
++			atomic_inc_unchecked(&mp->stats.seq_not_found);
+ 			reject = FC_RJT_SEQ_ID;	/* sequence/exch should exist */
+ 			goto rel;
+ 		}
+@@ -1163,22 +1163,22 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
+ 
+ 	ep = fc_exch_find(mp, ntohs(fh->fh_ox_id));
+ 	if (!ep) {
+-		atomic_inc(&mp->stats.xid_not_found);
++		atomic_inc_unchecked(&mp->stats.xid_not_found);
+ 		goto out;
+ 	}
+ 	if (ep->esb_stat & ESB_ST_COMPLETE) {
+-		atomic_inc(&mp->stats.xid_not_found);
++		atomic_inc_unchecked(&mp->stats.xid_not_found);
+ 		goto out;
+ 	}
+ 	if (ep->rxid == FC_XID_UNKNOWN)
+ 		ep->rxid = ntohs(fh->fh_rx_id);
+ 	if (ep->sid != 0 && ep->sid != ntoh24(fh->fh_d_id)) {
+-		atomic_inc(&mp->stats.xid_not_found);
++		atomic_inc_unchecked(&mp->stats.xid_not_found);
+ 		goto rel;
+ 	}
+ 	if (ep->did != ntoh24(fh->fh_s_id) &&
+ 	    ep->did != FC_FID_FLOGI) {
+-		atomic_inc(&mp->stats.xid_not_found);
++		atomic_inc_unchecked(&mp->stats.xid_not_found);
+ 		goto rel;
+ 	}
+ 	sof = fr_sof(fp);
+@@ -1189,7 +1189,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
+ 	} else {
+ 		sp = &ep->seq;
+ 		if (sp->id != fh->fh_seq_id) {
+-			atomic_inc(&mp->stats.seq_not_found);
++			atomic_inc_unchecked(&mp->stats.seq_not_found);
+ 			goto rel;
+ 		}
+ 	}
+@@ -1249,9 +1249,9 @@ static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
+ 	sp = fc_seq_lookup_orig(mp, fp);	/* doesn't hold sequence */
+ 
+ 	if (!sp)
+-		atomic_inc(&mp->stats.xid_not_found);
++		atomic_inc_unchecked(&mp->stats.xid_not_found);
+ 	else
+-		atomic_inc(&mp->stats.non_bls_resp);
++		atomic_inc_unchecked(&mp->stats.non_bls_resp);
+ 
+ 	fc_frame_free(fp);
+ }
+diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
+index 0ee989f..a582241 100644
+--- a/drivers/scsi/libsas/sas_ata.c
++++ b/drivers/scsi/libsas/sas_ata.c
+@@ -343,7 +343,7 @@ static int sas_ata_scr_read(struct ata_link *link, unsigned int sc_reg_in,
+ 	}
+ }
+ 
+-static struct ata_port_operations sas_sata_ops = {
++static const struct ata_port_operations sas_sata_ops = {
+ 	.phy_reset		= sas_ata_phy_reset,
+ 	.post_internal_cmd	= sas_ata_post_internal,
+ 	.qc_defer               = ata_std_qc_defer,
+diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
+index aa10f79..5cc79e4 100644
+--- a/drivers/scsi/lpfc/lpfc.h
++++ b/drivers/scsi/lpfc/lpfc.h
+@@ -400,7 +400,7 @@ struct lpfc_vport {
+ 	struct dentry *debug_nodelist;
+ 	struct dentry *vport_debugfs_root;
+ 	struct lpfc_debugfs_trc *disc_trc;
+-	atomic_t disc_trc_cnt;
++	atomic_unchecked_t disc_trc_cnt;
+ #endif
+ 	uint8_t stat_data_enabled;
+ 	uint8_t stat_data_blocked;
+@@ -725,8 +725,8 @@ struct lpfc_hba {
+ 	struct timer_list fabric_block_timer;
+ 	unsigned long bit_flags;
+ #define	FABRIC_COMANDS_BLOCKED	0
+-	atomic_t num_rsrc_err;
+-	atomic_t num_cmd_success;
++	atomic_unchecked_t num_rsrc_err;
++	atomic_unchecked_t num_cmd_success;
+ 	unsigned long last_rsrc_error_time;
+ 	unsigned long last_ramp_down_time;
+ 	unsigned long last_ramp_up_time;
+@@ -740,7 +740,7 @@ struct lpfc_hba {
+ 	struct dentry *debug_dumpDif;    /* BlockGuard BPL*/
+ 	struct dentry *debug_slow_ring_trc;
+ 	struct lpfc_debugfs_trc *slow_ring_trc;
+-	atomic_t slow_ring_trc_cnt;
++	atomic_unchecked_t slow_ring_trc_cnt;
+ #endif
+ 
+ 	/* Used for deferred freeing of ELS data buffers */
+diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
+index 8d0f0de..7c77a62 100644
+--- a/drivers/scsi/lpfc/lpfc_debugfs.c
++++ b/drivers/scsi/lpfc/lpfc_debugfs.c
+@@ -124,7 +124,7 @@ struct lpfc_debug {
+ 	int  len;
+ };
+ 
+-static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
++static atomic_unchecked_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
+ static unsigned long lpfc_debugfs_start_time = 0L;
+ 
+ /**
+@@ -158,7 +158,7 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
+ 	lpfc_debugfs_enable = 0;
+ 
+ 	len = 0;
+-	index = (atomic_read(&vport->disc_trc_cnt) + 1) &
++	index = (atomic_read_unchecked(&vport->disc_trc_cnt) + 1) &
+ 		(lpfc_debugfs_max_disc_trc - 1);
+ 	for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
+ 		dtp = vport->disc_trc + i;
+@@ -219,7 +219,7 @@ lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
+ 	lpfc_debugfs_enable = 0;
+ 
+ 	len = 0;
+-	index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
++	index = (atomic_read_unchecked(&phba->slow_ring_trc_cnt) + 1) &
+ 		(lpfc_debugfs_max_slow_ring_trc - 1);
+ 	for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
+ 		dtp = phba->slow_ring_trc + i;
+@@ -397,6 +397,8 @@ lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
+ 	uint32_t *ptr;
+ 	char buffer[1024];
+ 
++	pax_track_stack();
++
+ 	off = 0;
+ 	spin_lock_irq(&phba->hbalock);
+ 
+@@ -634,14 +636,14 @@ lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
+ 		!vport || !vport->disc_trc)
+ 		return;
+ 
+-	index = atomic_inc_return(&vport->disc_trc_cnt) &
++	index = atomic_inc_return_unchecked(&vport->disc_trc_cnt) &
+ 		(lpfc_debugfs_max_disc_trc - 1);
+ 	dtp = vport->disc_trc + index;
+ 	dtp->fmt = fmt;
+ 	dtp->data1 = data1;
+ 	dtp->data2 = data2;
+ 	dtp->data3 = data3;
+-	dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
++	dtp->seq_cnt = atomic_inc_return_unchecked(&lpfc_debugfs_seq_trc_cnt);
+ 	dtp->jif = jiffies;
+ #endif
+ 	return;
+@@ -672,14 +674,14 @@ lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
+ 		!phba || !phba->slow_ring_trc)
+ 		return;
+ 
+-	index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
++	index = atomic_inc_return_unchecked(&phba->slow_ring_trc_cnt) &
+ 		(lpfc_debugfs_max_slow_ring_trc - 1);
+ 	dtp = phba->slow_ring_trc + index;
+ 	dtp->fmt = fmt;
+ 	dtp->data1 = data1;
+ 	dtp->data2 = data2;
+ 	dtp->data3 = data3;
+-	dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
++	dtp->seq_cnt = atomic_inc_return_unchecked(&lpfc_debugfs_seq_trc_cnt);
+ 	dtp->jif = jiffies;
+ #endif
+ 	return;
+@@ -1364,7 +1366,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
+ 						 "slow_ring buffer\n");
+ 				goto debug_failed;
+ 			}
+-			atomic_set(&phba->slow_ring_trc_cnt, 0);
++			atomic_set_unchecked(&phba->slow_ring_trc_cnt, 0);
+ 			memset(phba->slow_ring_trc, 0,
+ 				(sizeof(struct lpfc_debugfs_trc) *
+ 				lpfc_debugfs_max_slow_ring_trc));
+@@ -1410,7 +1412,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
+ 				 "buffer\n");
+ 		goto debug_failed;
+ 	}
+-	atomic_set(&vport->disc_trc_cnt, 0);
++	atomic_set_unchecked(&vport->disc_trc_cnt, 0);
+ 
+ 	snprintf(name, sizeof(name), "discovery_trace");
+ 	vport->debug_disc_trc =
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 549bc7d..8189dbb 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -8021,8 +8021,10 @@ lpfc_init(void)
+ 	printk(LPFC_COPYRIGHT "\n");
+ 
+ 	if (lpfc_enable_npiv) {
+-		lpfc_transport_functions.vport_create = lpfc_vport_create;
+-		lpfc_transport_functions.vport_delete = lpfc_vport_delete;
++		pax_open_kernel();
++		*(void **)&lpfc_transport_functions.vport_create = lpfc_vport_create;
++		*(void **)&lpfc_transport_functions.vport_delete = lpfc_vport_delete;
++		pax_close_kernel();
+ 	}
+ 	lpfc_transport_template =
+ 				fc_attach_transport(&lpfc_transport_functions);
+diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
+index c88f59f..ff2a42f 100644
+--- a/drivers/scsi/lpfc/lpfc_scsi.c
++++ b/drivers/scsi/lpfc/lpfc_scsi.c
+@@ -259,7 +259,7 @@ lpfc_rampdown_queue_depth(struct lpfc_hba *phba)
+ 	uint32_t evt_posted;
+ 
+ 	spin_lock_irqsave(&phba->hbalock, flags);
+-	atomic_inc(&phba->num_rsrc_err);
++	atomic_inc_unchecked(&phba->num_rsrc_err);
+ 	phba->last_rsrc_error_time = jiffies;
+ 
+ 	if ((phba->last_ramp_down_time + QUEUE_RAMP_DOWN_INTERVAL) > jiffies) {
+@@ -300,7 +300,7 @@ lpfc_rampup_queue_depth(struct lpfc_vport  *vport,
+ 	unsigned long flags;
+ 	struct lpfc_hba *phba = vport->phba;
+ 	uint32_t evt_posted;
+-	atomic_inc(&phba->num_cmd_success);
++	atomic_inc_unchecked(&phba->num_cmd_success);
+ 
+ 	if (vport->cfg_lun_queue_depth <= queue_depth)
+ 		return;
+@@ -343,8 +343,8 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
+ 	int i;
+ 	struct lpfc_rport_data *rdata;
+ 
+-	num_rsrc_err = atomic_read(&phba->num_rsrc_err);
+-	num_cmd_success = atomic_read(&phba->num_cmd_success);
++	num_rsrc_err = atomic_read_unchecked(&phba->num_rsrc_err);
++	num_cmd_success = atomic_read_unchecked(&phba->num_cmd_success);
+ 
+ 	vports = lpfc_create_vport_work_array(phba);
+ 	if (vports != NULL)
+@@ -378,8 +378,8 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
+ 			}
+ 		}
+ 	lpfc_destroy_vport_work_array(phba, vports);
+-	atomic_set(&phba->num_rsrc_err, 0);
+-	atomic_set(&phba->num_cmd_success, 0);
++	atomic_set_unchecked(&phba->num_rsrc_err, 0);
++	atomic_set_unchecked(&phba->num_cmd_success, 0);
+ }
+ 
+ /**
+@@ -427,8 +427,8 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
+ 			}
+ 		}
+ 	lpfc_destroy_vport_work_array(phba, vports);
+-	atomic_set(&phba->num_rsrc_err, 0);
+-	atomic_set(&phba->num_cmd_success, 0);
++	atomic_set_unchecked(&phba->num_rsrc_err, 0);
++	atomic_set_unchecked(&phba->num_cmd_success, 0);
+ }
+ 
+ /**
+diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
+index 234f0b7..3020aea 100644
+--- a/drivers/scsi/megaraid/megaraid_mbox.c
++++ b/drivers/scsi/megaraid/megaraid_mbox.c
+@@ -3503,6 +3503,8 @@ megaraid_cmm_register(adapter_t *adapter)
+ 	int		rval;
+ 	int		i;
+ 
++	pax_track_stack();
++
+ 	// Allocate memory for the base list of scb for management module.
+ 	adapter->uscb_list = kcalloc(MBOX_MAX_USER_CMDS, sizeof(scb_t), GFP_KERNEL);
+ 
+diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
+index 7a117c1..ee01e9e 100644
+--- a/drivers/scsi/osd/osd_initiator.c
++++ b/drivers/scsi/osd/osd_initiator.c
+@@ -94,6 +94,8 @@ static int _osd_print_system_info(struct osd_dev *od, void *caps)
+ 	int nelem = ARRAY_SIZE(get_attrs), a = 0;
+ 	int ret;
+ 
++	pax_track_stack();
++
+ 	or = osd_start_request(od, GFP_KERNEL);
+ 	if (!or)
+ 		return -ENOMEM;
+diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
+index 9ab8c86..9425ad3 100644
+--- a/drivers/scsi/pmcraid.c
++++ b/drivers/scsi/pmcraid.c
+@@ -189,8 +189,8 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
+ 		res->scsi_dev = scsi_dev;
+ 		scsi_dev->hostdata = res;
+ 		res->change_detected = 0;
+-		atomic_set(&res->read_failures, 0);
+-		atomic_set(&res->write_failures, 0);
++		atomic_set_unchecked(&res->read_failures, 0);
++		atomic_set_unchecked(&res->write_failures, 0);
+ 		rc = 0;
+ 	}
+ 	spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
+@@ -2396,9 +2396,9 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
+ 
+ 	/* If this was a SCSI read/write command keep count of errors */
+ 	if (SCSI_CMD_TYPE(scsi_cmd->cmnd[0]) == SCSI_READ_CMD)
+-		atomic_inc(&res->read_failures);
++		atomic_inc_unchecked(&res->read_failures);
+ 	else if (SCSI_CMD_TYPE(scsi_cmd->cmnd[0]) == SCSI_WRITE_CMD)
+-		atomic_inc(&res->write_failures);
++		atomic_inc_unchecked(&res->write_failures);
+ 
+ 	if (!RES_IS_GSCSI(res->cfg_entry) &&
+ 		masked_ioasc != PMCRAID_IOASC_HW_DEVICE_BUS_STATUS_ERROR) {
+@@ -4116,7 +4116,7 @@ static void pmcraid_worker_function(struct work_struct *workp)
+ 
+ 	pinstance = container_of(workp, struct pmcraid_instance, worker_q);
+ 	/* add resources only after host is added into system */
+-	if (!atomic_read(&pinstance->expose_resources))
++	if (!atomic_read_unchecked(&pinstance->expose_resources))
+ 		return;
+ 
+ 	spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
+@@ -4850,7 +4850,7 @@ static int __devinit pmcraid_init_instance(
+ 	init_waitqueue_head(&pinstance->reset_wait_q);
+ 
+ 	atomic_set(&pinstance->outstanding_cmds, 0);
+-	atomic_set(&pinstance->expose_resources, 0);
++	atomic_set_unchecked(&pinstance->expose_resources, 0);
+ 
+ 	INIT_LIST_HEAD(&pinstance->free_res_q);
+ 	INIT_LIST_HEAD(&pinstance->used_res_q);
+@@ -5502,7 +5502,7 @@ static int __devinit pmcraid_probe(
+ 	/* Schedule worker thread to handle CCN and take care of adding and
+ 	 * removing devices to OS
+ 	 */
+-	atomic_set(&pinstance->expose_resources, 1);
++	atomic_set_unchecked(&pinstance->expose_resources, 1);
+ 	schedule_work(&pinstance->worker_q);
+ 	return rc;
+ 
+diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
+index 3441b3f..6cbe8f7 100644
+--- a/drivers/scsi/pmcraid.h
++++ b/drivers/scsi/pmcraid.h
+@@ -690,7 +690,7 @@ struct pmcraid_instance {
+ 	atomic_t outstanding_cmds;
+ 
+ 	/* should add/delete resources to mid-layer now ?*/
+-	atomic_t expose_resources;
++	atomic_unchecked_t expose_resources;
+ 
+ 	/* Tasklet to handle deferred processing */
+ 	struct tasklet_struct isr_tasklet[PMCRAID_NUM_MSIX_VECTORS];
+@@ -727,8 +727,8 @@ struct pmcraid_resource_entry {
+ 	struct list_head queue;	/* link to "to be exposed" resources */
+ 	struct pmcraid_config_table_entry cfg_entry;
+ 	struct scsi_device *scsi_dev;	/* Link scsi_device structure */
+-	atomic_t read_failures;		/* count of failed READ commands */
+-	atomic_t write_failures;	/* count of failed WRITE commands */
++	atomic_unchecked_t read_failures;		/* count of failed READ commands */
++	atomic_unchecked_t write_failures;	/* count of failed WRITE commands */
+ 
+ 	/* To indicate add/delete/modify during CCN */
+ 	u8 change_detected;
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 2150618..7034215 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2089,7 +2089,7 @@ struct isp_operations {
+ 
+ 	int (*get_flash_version) (struct scsi_qla_host *, void *);
+ 	int (*start_scsi) (srb_t *);
+-};
++} __no_const;
+ 
+ /* MSI-X Support *************************************************************/
+ 
+diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
+index 81b5f29..2ae1fad 100644
+--- a/drivers/scsi/qla4xxx/ql4_def.h
++++ b/drivers/scsi/qla4xxx/ql4_def.h
+@@ -240,7 +240,7 @@ struct ddb_entry {
+ 	atomic_t retry_relogin_timer; /* Min Time between relogins
+ 				       * (4000 only) */
+ 	atomic_t relogin_timer;	/* Max Time to wait for relogin to complete */
+-	atomic_t relogin_retry_count; /* Num of times relogin has been
++	atomic_unchecked_t relogin_retry_count; /* Num of times relogin has been
+ 				       * retried */
+ 
+ 	uint16_t port;
+diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
+index af8c323..515dd51 100644
+--- a/drivers/scsi/qla4xxx/ql4_init.c
++++ b/drivers/scsi/qla4xxx/ql4_init.c
+@@ -482,7 +482,7 @@ static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
+ 	atomic_set(&ddb_entry->port_down_timer, ha->port_down_retry_count);
+ 	atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY);
+ 	atomic_set(&ddb_entry->relogin_timer, 0);
+-	atomic_set(&ddb_entry->relogin_retry_count, 0);
++	atomic_set_unchecked(&ddb_entry->relogin_retry_count, 0);
+ 	atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
+ 	list_add_tail(&ddb_entry->list, &ha->ddb_list);
+ 	ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry;
+@@ -1308,7 +1308,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha,
+ 		atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
+ 		atomic_set(&ddb_entry->port_down_timer,
+ 			   ha->port_down_retry_count);
+-		atomic_set(&ddb_entry->relogin_retry_count, 0);
++		atomic_set_unchecked(&ddb_entry->relogin_retry_count, 0);
+ 		atomic_set(&ddb_entry->relogin_timer, 0);
+ 		clear_bit(DF_RELOGIN, &ddb_entry->flags);
+ 		clear_bit(DF_NO_RELOGIN, &ddb_entry->flags);
+diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
+index 83c8b5e..a82b348 100644
+--- a/drivers/scsi/qla4xxx/ql4_os.c
++++ b/drivers/scsi/qla4xxx/ql4_os.c
+@@ -641,13 +641,13 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
+ 			    ddb_entry->fw_ddb_device_state ==
+ 			    DDB_DS_SESSION_FAILED) {
+ 				/* Reset retry relogin timer */
+-				atomic_inc(&ddb_entry->relogin_retry_count);
++				atomic_inc_unchecked(&ddb_entry->relogin_retry_count);
+ 				DEBUG2(printk("scsi%ld: index[%d] relogin"
+ 					      " timed out-retrying"
+ 					      " relogin (%d)\n",
+ 					      ha->host_no,
+ 					      ddb_entry->fw_ddb_index,
+-					      atomic_read(&ddb_entry->
++					      atomic_read_unchecked(&ddb_entry->
+ 							  relogin_retry_count))
+ 					);
+ 				start_dpc++;
+diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
+index dd098ca..686ce01 100644
+--- a/drivers/scsi/scsi.c
++++ b/drivers/scsi/scsi.c
+@@ -652,7 +652,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
+ 	unsigned long timeout;
+ 	int rtn = 0;
+ 
+-	atomic_inc(&cmd->device->iorequest_cnt);
++	atomic_inc_unchecked(&cmd->device->iorequest_cnt);
+ 
+ 	/* check if the device is still usable */
+ 	if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index bc3e363..e1a8e50 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -1395,6 +1395,8 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
+ 	unsigned char arr[SDEBUG_MAX_MSELECT_SZ];
+ 	unsigned char *cmd = (unsigned char *)scp->cmnd;
+ 
++	pax_track_stack();
++
+ 	if ((errsts = check_readiness(scp, 1, devip)))
+ 		return errsts;
+ 	memset(arr, 0, sizeof(arr));
+@@ -1492,6 +1494,8 @@ static int resp_log_sense(struct scsi_cmnd * scp,
+ 	unsigned char arr[SDEBUG_MAX_LSENSE_SZ];
+ 	unsigned char *cmd = (unsigned char *)scp->cmnd;
+ 
++	pax_track_stack();
++
+ 	if ((errsts = check_readiness(scp, 1, devip)))
+ 		return errsts;
+ 	memset(arr, 0, sizeof(arr));
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 8df12522..c4c1472 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -1389,7 +1389,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
+ 	shost = sdev->host;
+ 	scsi_init_cmd_errh(cmd);
+ 	cmd->result = DID_NO_CONNECT << 16;
+-	atomic_inc(&cmd->device->iorequest_cnt);
++	atomic_inc_unchecked(&cmd->device->iorequest_cnt);
+ 
+ 	/*
+ 	 * SCSI request completion path will do scsi_device_unbusy(),
+@@ -1420,9 +1420,9 @@ static void scsi_softirq_done(struct request *rq)
+ 	 */
+ 	cmd->serial_number = 0;
+ 
+-	atomic_inc(&cmd->device->iodone_cnt);
++	atomic_inc_unchecked(&cmd->device->iodone_cnt);
+ 	if (cmd->result)
+-		atomic_inc(&cmd->device->ioerr_cnt);
++		atomic_inc_unchecked(&cmd->device->ioerr_cnt);
+ 
+ 	disposition = scsi_decide_disposition(cmd);
+ 	if (disposition != SUCCESS &&
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index 91a93e0..eae0fe3 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -662,7 +662,7 @@ show_iostat_##field(struct device *dev, struct device_attribute *attr,	\
+ 		    char *buf)						\
+ {									\
+ 	struct scsi_device *sdev = to_scsi_device(dev);			\
+-	unsigned long long count = atomic_read(&sdev->field);		\
++	unsigned long long count = atomic_read_unchecked(&sdev->field);	\
+ 	return snprintf(buf, 20, "0x%llx\n", count);			\
+ }									\
+ static DEVICE_ATTR(field, S_IRUGO, show_iostat_##field, NULL)
+diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
+index 1030327..f91fd30 100644
+--- a/drivers/scsi/scsi_tgt_lib.c
++++ b/drivers/scsi/scsi_tgt_lib.c
+@@ -362,7 +362,7 @@ static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd,
+ 	int err;
+ 
+ 	dprintk("%lx %u\n", uaddr, len);
+-	err = blk_rq_map_user(q, rq, NULL, (void *)uaddr, len, GFP_KERNEL);
++	err = blk_rq_map_user(q, rq, NULL, (void __user *)uaddr, len, GFP_KERNEL);
+ 	if (err) {
+ 		/*
+ 		 * TODO: need to fixup sg_tablesize, max_segment_size,
+diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
+index db02e31..1b42ea9 100644
+--- a/drivers/scsi/scsi_transport_fc.c
++++ b/drivers/scsi/scsi_transport_fc.c
+@@ -480,7 +480,7 @@ MODULE_PARM_DESC(dev_loss_tmo,
+  * Netlink Infrastructure
+  */
+ 
+-static atomic_t fc_event_seq;
++static atomic_unchecked_t fc_event_seq;
+ 
+ /**
+  * fc_get_event_number - Obtain the next sequential FC event number
+@@ -493,7 +493,7 @@ static atomic_t fc_event_seq;
+ u32
+ fc_get_event_number(void)
+ {
+-	return atomic_add_return(1, &fc_event_seq);
++	return atomic_add_return_unchecked(1, &fc_event_seq);
+ }
+ EXPORT_SYMBOL(fc_get_event_number);
+ 
+@@ -641,7 +641,7 @@ static __init int fc_transport_init(void)
+ {
+ 	int error;
+ 
+-	atomic_set(&fc_event_seq, 0);
++	atomic_set_unchecked(&fc_event_seq, 0);
+ 
+ 	error = transport_class_register(&fc_host_class);
+ 	if (error)
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index de2f8c4..63c5278 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -81,7 +81,7 @@ struct iscsi_internal {
+ 	struct device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
+ };
+ 
+-static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
++static atomic_unchecked_t iscsi_session_nr; /* sysfs session id for next new session */
+ static struct workqueue_struct *iscsi_eh_timer_workq;
+ 
+ /*
+@@ -728,7 +728,7 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
+ 	int err;
+ 
+ 	ihost = shost->shost_data;
+-	session->sid = atomic_add_return(1, &iscsi_session_nr);
++	session->sid = atomic_add_return_unchecked(1, &iscsi_session_nr);
+ 
+ 	if (id == ISCSI_MAX_TARGET) {
+ 		for (id = 0; id < ISCSI_MAX_TARGET; id++) {
+@@ -2060,7 +2060,7 @@ static __init int iscsi_transport_init(void)
+ 	printk(KERN_INFO "Loading iSCSI transport class v%s.\n",
+ 		ISCSI_TRANSPORT_VERSION);
+ 
+-	atomic_set(&iscsi_session_nr, 0);
++	atomic_set_unchecked(&iscsi_session_nr, 0);
+ 
+ 	err = class_register(&iscsi_transport_class);
+ 	if (err)
+diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
+index 21a045e..ec89e03 100644
+--- a/drivers/scsi/scsi_transport_srp.c
++++ b/drivers/scsi/scsi_transport_srp.c
+@@ -33,7 +33,7 @@
+ #include "scsi_transport_srp_internal.h"
+ 
+ struct srp_host_attrs {
+-	atomic_t next_port_id;
++	atomic_unchecked_t next_port_id;
+ };
+ #define to_srp_host_attrs(host)	((struct srp_host_attrs *)(host)->shost_data)
+ 
+@@ -62,7 +62,7 @@ static int srp_host_setup(struct transport_container *tc, struct device *dev,
+ 	struct Scsi_Host *shost = dev_to_shost(dev);
+ 	struct srp_host_attrs *srp_host = to_srp_host_attrs(shost);
+ 
+-	atomic_set(&srp_host->next_port_id, 0);
++	atomic_set_unchecked(&srp_host->next_port_id, 0);
+ 	return 0;
+ }
+ 
+@@ -211,7 +211,7 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost,
+ 	memcpy(rport->port_id, ids->port_id, sizeof(rport->port_id));
+ 	rport->roles = ids->roles;
+ 
+-	id = atomic_inc_return(&to_srp_host_attrs(shost)->next_port_id);
++	id = atomic_inc_return_unchecked(&to_srp_host_attrs(shost)->next_port_id);
+ 	dev_set_name(&rport->dev, "port-%d:%d", shost->host_no, id);
+ 
+ 	transport_setup_device(&rport->dev);
+diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
+index 040f751..98a5ed2 100644
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -1064,7 +1064,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
+ 				       sdp->disk->disk_name,
+ 				       MKDEV(SCSI_GENERIC_MAJOR, sdp->index),
+ 				       NULL,
+-				       (char *)arg);
++				       (char __user *)arg);
+ 	case BLKTRACESTART:
+ 		return blk_trace_startstop(sdp->device->request_queue, 1);
+ 	case BLKTRACESTOP:
+@@ -2292,7 +2292,7 @@ struct sg_proc_leaf {
+ 	const struct file_operations * fops;
+ };
+ 
+-static struct sg_proc_leaf sg_proc_leaf_arr[] = {
++static const struct sg_proc_leaf sg_proc_leaf_arr[] = {
+ 	{"allow_dio", &adio_fops},
+ 	{"debug", &debug_fops},
+ 	{"def_reserved_size", &dressz_fops},
+@@ -2307,7 +2307,7 @@ sg_proc_init(void)
+ {
+ 	int k, mask;
+ 	int num_leaves = ARRAY_SIZE(sg_proc_leaf_arr);
+-	struct sg_proc_leaf * leaf;
++	const struct sg_proc_leaf * leaf;
+ 
+ 	sg_proc_sgp = proc_mkdir(sg_proc_sg_dirname, NULL);
+ 	if (!sg_proc_sgp)
+diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
+index c19ca5e..3eb5959 100644
+--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
++++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
+@@ -1758,6 +1758,8 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
+ 	int do_iounmap = 0;
+ 	int do_disable_device = 1;
+ 
++	pax_track_stack();
++
+ 	memset(&sym_dev, 0, sizeof(sym_dev));
+ 	memset(&nvram, 0, sizeof(nvram));
+ 	sym_dev.pdev = pdev;
+diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
+new file mode 100644
+index 0000000..eabb432
+--- /dev/null
++++ b/drivers/scsi/vmw_pvscsi.c
+@@ -0,0 +1,1401 @@
++/*
++ * Linux driver for VMware's para-virtualized SCSI HBA.
++ *
++ * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; version 2 of the License and no later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
++ * NON INFRINGEMENT.  See the GNU General Public License for more
++ * details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Maintained by: Alok N Kataria <akataria@vmware.com>
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/types.h>
++#include <linux/interrupt.h>
++#include <linux/workqueue.h>
++#include <linux/pci.h>
++
++#include <scsi/scsi.h>
++#include <scsi/scsi_host.h>
++#include <scsi/scsi_cmnd.h>
++#include <scsi/scsi_device.h>
++
++#include "vmw_pvscsi.h"
++
++#define PVSCSI_LINUX_DRIVER_DESC "VMware PVSCSI driver"
++
++MODULE_DESCRIPTION(PVSCSI_LINUX_DRIVER_DESC);
++MODULE_AUTHOR("VMware, Inc.");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(PVSCSI_DRIVER_VERSION_STRING);
++
++#define PVSCSI_DEFAULT_NUM_PAGES_PER_RING	8
++#define PVSCSI_DEFAULT_NUM_PAGES_MSG_RING	1
++#define PVSCSI_DEFAULT_QUEUE_DEPTH		64
++#define SGL_SIZE				PAGE_SIZE
++
++#define pvscsi_dev(adapter) (&(adapter->dev->dev))
++
++struct pvscsi_sg_list {
++	struct PVSCSISGElement sge[PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT];
++};
++
++struct pvscsi_ctx {
++	/*
++	 * The index of the context in cmd_map serves as the context ID for a
++	 * 1-to-1 mapping completions back to requests.
++	 */
++	struct scsi_cmnd	*cmd;
++	struct pvscsi_sg_list	*sgl;
++	struct list_head	list;
++	dma_addr_t		dataPA;
++	dma_addr_t		sensePA;
++	dma_addr_t		sglPA;
++};
++
++struct pvscsi_adapter {
++	char				*mmioBase;
++	unsigned int			irq;
++	u8				rev;
++	bool				use_msi;
++	bool				use_msix;
++	bool				use_msg;
++
++	spinlock_t			hw_lock;
++
++	struct workqueue_struct		*workqueue;
++	struct work_struct		work;
++
++	struct PVSCSIRingReqDesc	*req_ring;
++	unsigned			req_pages;
++	unsigned			req_depth;
++	dma_addr_t			reqRingPA;
++
++	struct PVSCSIRingCmpDesc	*cmp_ring;
++	unsigned			cmp_pages;
++	dma_addr_t			cmpRingPA;
++
++	struct PVSCSIRingMsgDesc	*msg_ring;
++	unsigned			msg_pages;
++	dma_addr_t			msgRingPA;
++
++	struct PVSCSIRingsState		*rings_state;
++	dma_addr_t			ringStatePA;
++
++	struct pci_dev			*dev;
++	struct Scsi_Host		*host;
++
++	struct list_head		cmd_pool;
++	struct pvscsi_ctx		*cmd_map;
++};
++
++
++/* Command line parameters */
++static int pvscsi_ring_pages     = PVSCSI_DEFAULT_NUM_PAGES_PER_RING;
++static int pvscsi_msg_ring_pages = PVSCSI_DEFAULT_NUM_PAGES_MSG_RING;
++static int pvscsi_cmd_per_lun    = PVSCSI_DEFAULT_QUEUE_DEPTH;
++static bool pvscsi_disable_msi;
++static bool pvscsi_disable_msix;
++static bool pvscsi_use_msg       = true;
++
++#define PVSCSI_RW (S_IRUSR | S_IWUSR)
++
++module_param_named(ring_pages, pvscsi_ring_pages, int, PVSCSI_RW);
++MODULE_PARM_DESC(ring_pages, "Number of pages per req/cmp ring - (default="
++		 __stringify(PVSCSI_DEFAULT_NUM_PAGES_PER_RING) ")");
++
++module_param_named(msg_ring_pages, pvscsi_msg_ring_pages, int, PVSCSI_RW);
++MODULE_PARM_DESC(msg_ring_pages, "Number of pages for the msg ring - (default="
++		 __stringify(PVSCSI_DEFAULT_NUM_PAGES_MSG_RING) ")");
++
++module_param_named(cmd_per_lun, pvscsi_cmd_per_lun, int, PVSCSI_RW);
++MODULE_PARM_DESC(cmd_per_lun, "Maximum commands per lun - (default="
++		 __stringify(PVSCSI_MAX_REQ_QUEUE_DEPTH) ")");
++
++module_param_named(disable_msi, pvscsi_disable_msi, bool, PVSCSI_RW);
++MODULE_PARM_DESC(disable_msi, "Disable MSI use in driver - (default=0)");
++
++module_param_named(disable_msix, pvscsi_disable_msix, bool, PVSCSI_RW);
++MODULE_PARM_DESC(disable_msix, "Disable MSI-X use in driver - (default=0)");
++
++module_param_named(use_msg, pvscsi_use_msg, bool, PVSCSI_RW);
++MODULE_PARM_DESC(use_msg, "Use msg ring when available - (default=1)");
++
++static const struct pci_device_id pvscsi_pci_tbl[] = {
++	{ PCI_VDEVICE(VMWARE, PCI_DEVICE_ID_VMWARE_PVSCSI) },
++	{ 0 }
++};
++
++MODULE_DEVICE_TABLE(pci, pvscsi_pci_tbl);
++
++static struct pvscsi_ctx *
++pvscsi_find_context(const struct pvscsi_adapter *adapter, struct scsi_cmnd *cmd)
++{
++	struct pvscsi_ctx *ctx, *end;
++
++	end = &adapter->cmd_map[adapter->req_depth];
++	for (ctx = adapter->cmd_map; ctx < end; ctx++)
++		if (ctx->cmd == cmd)
++			return ctx;
++
++	return NULL;
++}
++
++static struct pvscsi_ctx *
++pvscsi_acquire_context(struct pvscsi_adapter *adapter, struct scsi_cmnd *cmd)
++{
++	struct pvscsi_ctx *ctx;
++
++	if (list_empty(&adapter->cmd_pool))
++		return NULL;
++
++	ctx = list_first_entry(&adapter->cmd_pool, struct pvscsi_ctx, list);
++	ctx->cmd = cmd;
++	list_del(&ctx->list);
++
++	return ctx;
++}
++
++static void pvscsi_release_context(struct pvscsi_adapter *adapter,
++				   struct pvscsi_ctx *ctx)
++{
++	ctx->cmd = NULL;
++	list_add(&ctx->list, &adapter->cmd_pool);
++}
++
++/*
++ * Map a pvscsi_ctx struct to a context ID field value; we map to a simple
++ * non-zero integer. ctx always points to an entry in cmd_map array, hence
++ * the return value is always >=1.
++ */
++static u64 pvscsi_map_context(const struct pvscsi_adapter *adapter,
++			      const struct pvscsi_ctx *ctx)
++{
++	return ctx - adapter->cmd_map + 1;
++}
++
++static struct pvscsi_ctx *
++pvscsi_get_context(const struct pvscsi_adapter *adapter, u64 context)
++{
++	return &adapter->cmd_map[context - 1];
++}
++
++static void pvscsi_reg_write(const struct pvscsi_adapter *adapter,
++			     u32 offset, u32 val)
++{
++	writel(val, adapter->mmioBase + offset);
++}
++
++static u32 pvscsi_reg_read(const struct pvscsi_adapter *adapter, u32 offset)
++{
++	return readl(adapter->mmioBase + offset);
++}
++
++static u32 pvscsi_read_intr_status(const struct pvscsi_adapter *adapter)
++{
++	return pvscsi_reg_read(adapter, PVSCSI_REG_OFFSET_INTR_STATUS);
++}
++
++static void pvscsi_write_intr_status(const struct pvscsi_adapter *adapter,
++				     u32 val)
++{
++	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_INTR_STATUS, val);
++}
++
++static void pvscsi_unmask_intr(const struct pvscsi_adapter *adapter)
++{
++	u32 intr_bits;
++
++	intr_bits = PVSCSI_INTR_CMPL_MASK;
++	if (adapter->use_msg)
++		intr_bits |= PVSCSI_INTR_MSG_MASK;
++
++	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_INTR_MASK, intr_bits);
++}
++
++static void pvscsi_mask_intr(const struct pvscsi_adapter *adapter)
++{
++	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_INTR_MASK, 0);
++}
++
++static void pvscsi_write_cmd_desc(const struct pvscsi_adapter *adapter,
++				  u32 cmd, const void *desc, size_t len)
++{
++	const u32 *ptr = desc;
++	size_t i;
++
++	len /= sizeof(*ptr);
++	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_COMMAND, cmd);
++	for (i = 0; i < len; i++)
++		pvscsi_reg_write(adapter,
++				 PVSCSI_REG_OFFSET_COMMAND_DATA, ptr[i]);
++}
++
++static void pvscsi_abort_cmd(const struct pvscsi_adapter *adapter,
++			     const struct pvscsi_ctx *ctx)
++{
++	struct PVSCSICmdDescAbortCmd cmd = { 0 };
++
++	cmd.target = ctx->cmd->device->id;
++	cmd.context = pvscsi_map_context(adapter, ctx);
++
++	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_ABORT_CMD, &cmd, sizeof(cmd));
++}
++
++static void pvscsi_kick_rw_io(const struct pvscsi_adapter *adapter)
++{
++	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_KICK_RW_IO, 0);
++}
++
++static void pvscsi_process_request_ring(const struct pvscsi_adapter *adapter)
++{
++	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_KICK_NON_RW_IO, 0);
++}
++
++static int scsi_is_rw(unsigned char op)
++{
++	return op == READ_6  || op == WRITE_6 ||
++	       op == READ_10 || op == WRITE_10 ||
++	       op == READ_12 || op == WRITE_12 ||
++	       op == READ_16 || op == WRITE_16;
++}
++
++static void pvscsi_kick_io(const struct pvscsi_adapter *adapter,
++			   unsigned char op)
++{
++	if (scsi_is_rw(op))
++		pvscsi_kick_rw_io(adapter);
++	else
++		pvscsi_process_request_ring(adapter);
++}
++
++static void ll_adapter_reset(const struct pvscsi_adapter *adapter)
++{
++	dev_dbg(pvscsi_dev(adapter), "Adapter Reset on %p\n", adapter);
++
++	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_ADAPTER_RESET, NULL, 0);
++}
++
++static void ll_bus_reset(const struct pvscsi_adapter *adapter)
++{
++	dev_dbg(pvscsi_dev(adapter), "Reseting bus on %p\n", adapter);
++
++	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_RESET_BUS, NULL, 0);
++}
++
++static void ll_device_reset(const struct pvscsi_adapter *adapter, u32 target)
++{
++	struct PVSCSICmdDescResetDevice cmd = { 0 };
++
++	dev_dbg(pvscsi_dev(adapter), "Reseting device: target=%u\n", target);
++
++	cmd.target = target;
++
++	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_RESET_DEVICE,
++			      &cmd, sizeof(cmd));
++}
++
++static void pvscsi_create_sg(struct pvscsi_ctx *ctx,
++			     struct scatterlist *sg, unsigned count)
++{
++	unsigned i;
++	struct PVSCSISGElement *sge;
++
++	BUG_ON(count > PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT);
++
++	sge = &ctx->sgl->sge[0];
++	for (i = 0; i < count; i++, sg++) {
++		sge[i].addr   = sg_dma_address(sg);
++		sge[i].length = sg_dma_len(sg);
++		sge[i].flags  = 0;
++	}
++}
++
++/*
++ * Map all data buffers for a command into PCI space and
++ * setup the scatter/gather list if needed.
++ */
++static void pvscsi_map_buffers(struct pvscsi_adapter *adapter,
++			       struct pvscsi_ctx *ctx, struct scsi_cmnd *cmd,
++			       struct PVSCSIRingReqDesc *e)
++{
++	unsigned count;
++	unsigned bufflen = scsi_bufflen(cmd);
++	struct scatterlist *sg;
++
++	e->dataLen = bufflen;
++	e->dataAddr = 0;
++	if (bufflen == 0)
++		return;
++
++	sg = scsi_sglist(cmd);
++	count = scsi_sg_count(cmd);
++	if (count != 0) {
++		int segs = scsi_dma_map(cmd);
++		if (segs > 1) {
++			pvscsi_create_sg(ctx, sg, segs);
++
++			e->flags |= PVSCSI_FLAG_CMD_WITH_SG_LIST;
++			ctx->sglPA = pci_map_single(adapter->dev, ctx->sgl,
++						    SGL_SIZE, PCI_DMA_TODEVICE);
++			e->dataAddr = ctx->sglPA;
++		} else
++			e->dataAddr = sg_dma_address(sg);
++	} else {
++		/*
++		 * In case there is no S/G list, scsi_sglist points
++		 * directly to the buffer.
++		 */
++		ctx->dataPA = pci_map_single(adapter->dev, sg, bufflen,
++					     cmd->sc_data_direction);
++		e->dataAddr = ctx->dataPA;
++	}
++}
++
++static void pvscsi_unmap_buffers(const struct pvscsi_adapter *adapter,
++				 struct pvscsi_ctx *ctx)
++{
++	struct scsi_cmnd *cmd;
++	unsigned bufflen;
++
++	cmd = ctx->cmd;
++	bufflen = scsi_bufflen(cmd);
++
++	if (bufflen != 0) {
++		unsigned count = scsi_sg_count(cmd);
++
++		if (count != 0) {
++			scsi_dma_unmap(cmd);
++			if (ctx->sglPA) {
++				pci_unmap_single(adapter->dev, ctx->sglPA,
++						 SGL_SIZE, PCI_DMA_TODEVICE);
++				ctx->sglPA = 0;
++			}
++		} else
++			pci_unmap_single(adapter->dev, ctx->dataPA, bufflen,
++					 cmd->sc_data_direction);
++	}
++	if (cmd->sense_buffer)
++		pci_unmap_single(adapter->dev, ctx->sensePA,
++				 SCSI_SENSE_BUFFERSIZE, PCI_DMA_FROMDEVICE);
++}
++
++static int __devinit pvscsi_allocate_rings(struct pvscsi_adapter *adapter)
++{
++	adapter->rings_state = pci_alloc_consistent(adapter->dev, PAGE_SIZE,
++						    &adapter->ringStatePA);
++	if (!adapter->rings_state)
++		return -ENOMEM;
++
++	adapter->req_pages = min(PVSCSI_MAX_NUM_PAGES_REQ_RING,
++				 pvscsi_ring_pages);
++	adapter->req_depth = adapter->req_pages
++					* PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
++	adapter->req_ring = pci_alloc_consistent(adapter->dev,
++						 adapter->req_pages * PAGE_SIZE,
++						 &adapter->reqRingPA);
++	if (!adapter->req_ring)
++		return -ENOMEM;
++
++	adapter->cmp_pages = min(PVSCSI_MAX_NUM_PAGES_CMP_RING,
++				 pvscsi_ring_pages);
++	adapter->cmp_ring = pci_alloc_consistent(adapter->dev,
++						 adapter->cmp_pages * PAGE_SIZE,
++						 &adapter->cmpRingPA);
++	if (!adapter->cmp_ring)
++		return -ENOMEM;
++
++	BUG_ON(!IS_ALIGNED(adapter->ringStatePA, PAGE_SIZE));
++	BUG_ON(!IS_ALIGNED(adapter->reqRingPA, PAGE_SIZE));
++	BUG_ON(!IS_ALIGNED(adapter->cmpRingPA, PAGE_SIZE));
++
++	if (!adapter->use_msg)
++		return 0;
++
++	adapter->msg_pages = min(PVSCSI_MAX_NUM_PAGES_MSG_RING,
++				 pvscsi_msg_ring_pages);
++	adapter->msg_ring = pci_alloc_consistent(adapter->dev,
++						 adapter->msg_pages * PAGE_SIZE,
++						 &adapter->msgRingPA);
++	if (!adapter->msg_ring)
++		return -ENOMEM;
++	BUG_ON(!IS_ALIGNED(adapter->msgRingPA, PAGE_SIZE));
++
++	return 0;
++}
++
++static void pvscsi_setup_all_rings(const struct pvscsi_adapter *adapter)
++{
++	struct PVSCSICmdDescSetupRings cmd = { 0 };
++	dma_addr_t base;
++	unsigned i;
++
++	cmd.ringsStatePPN   = adapter->ringStatePA >> PAGE_SHIFT;
++	cmd.reqRingNumPages = adapter->req_pages;
++	cmd.cmpRingNumPages = adapter->cmp_pages;
++
++	base = adapter->reqRingPA;
++	for (i = 0; i < adapter->req_pages; i++) {
++		cmd.reqRingPPNs[i] = base >> PAGE_SHIFT;
++		base += PAGE_SIZE;
++	}
++
++	base = adapter->cmpRingPA;
++	for (i = 0; i < adapter->cmp_pages; i++) {
++		cmd.cmpRingPPNs[i] = base >> PAGE_SHIFT;
++		base += PAGE_SIZE;
++	}
++
++	memset(adapter->rings_state, 0, PAGE_SIZE);
++	memset(adapter->req_ring, 0, adapter->req_pages * PAGE_SIZE);
++	memset(adapter->cmp_ring, 0, adapter->cmp_pages * PAGE_SIZE);
++
++	pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_SETUP_RINGS,
++			      &cmd, sizeof(cmd));
++
++	if (adapter->use_msg) {
++		struct PVSCSICmdDescSetupMsgRing cmd_msg = { 0 };
++
++		cmd_msg.numPages = adapter->msg_pages;
++
++		base = adapter->msgRingPA;
++		for (i = 0; i < adapter->msg_pages; i++) {
++			cmd_msg.ringPPNs[i] = base >> PAGE_SHIFT;
++			base += PAGE_SIZE;
++		}
++		memset(adapter->msg_ring, 0, adapter->msg_pages * PAGE_SIZE);
++
++		pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_SETUP_MSG_RING,
++				      &cmd_msg, sizeof(cmd_msg));
++	}
++}
++
++/*
++ * Pull a completion descriptor off and pass the completion back
++ * to the SCSI mid layer.
++ */
++static void pvscsi_complete_request(struct pvscsi_adapter *adapter,
++				    const struct PVSCSIRingCmpDesc *e)
++{
++	struct pvscsi_ctx *ctx;
++	struct scsi_cmnd *cmd;
++	u32 btstat = e->hostStatus;
++	u32 sdstat = e->scsiStatus;
++
++	ctx = pvscsi_get_context(adapter, e->context);
++	cmd = ctx->cmd;
++	pvscsi_unmap_buffers(adapter, ctx);
++	pvscsi_release_context(adapter, ctx);
++	cmd->result = 0;
++
++	if (sdstat != SAM_STAT_GOOD &&
++	    (btstat == BTSTAT_SUCCESS ||
++	     btstat == BTSTAT_LINKED_COMMAND_COMPLETED ||
++	     btstat == BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG)) {
++		cmd->result = (DID_OK << 16) | sdstat;
++		if (sdstat == SAM_STAT_CHECK_CONDITION && cmd->sense_buffer)
++			cmd->result |= (DRIVER_SENSE << 24);
++	} else
++		switch (btstat) {
++		case BTSTAT_SUCCESS:
++		case BTSTAT_LINKED_COMMAND_COMPLETED:
++		case BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG:
++			/* If everything went fine, let's move on..  */
++			cmd->result = (DID_OK << 16);
++			break;
++
++		case BTSTAT_DATARUN:
++		case BTSTAT_DATA_UNDERRUN:
++			/* Report residual data in underruns */
++			scsi_set_resid(cmd, scsi_bufflen(cmd) - e->dataLen);
++			cmd->result = (DID_ERROR << 16);
++			break;
++
++		case BTSTAT_SELTIMEO:
++			/* Our emulation returns this for non-connected devs */
++			cmd->result = (DID_BAD_TARGET << 16);
++			break;
++
++		case BTSTAT_LUNMISMATCH:
++		case BTSTAT_TAGREJECT:
++		case BTSTAT_BADMSG:
++			cmd->result = (DRIVER_INVALID << 24);
++			/* fall through */
++
++		case BTSTAT_HAHARDWARE:
++		case BTSTAT_INVPHASE:
++		case BTSTAT_HATIMEOUT:
++		case BTSTAT_NORESPONSE:
++		case BTSTAT_DISCONNECT:
++		case BTSTAT_HASOFTWARE:
++		case BTSTAT_BUSFREE:
++		case BTSTAT_SENSFAILED:
++			cmd->result |= (DID_ERROR << 16);
++			break;
++
++		case BTSTAT_SENTRST:
++		case BTSTAT_RECVRST:
++		case BTSTAT_BUSRESET:
++			cmd->result = (DID_RESET << 16);
++			break;
++
++		case BTSTAT_ABORTQUEUE:
++			cmd->result = (DID_ABORT << 16);
++			break;
++
++		case BTSTAT_SCSIPARITY:
++			cmd->result = (DID_PARITY << 16);
++			break;
++
++		default:
++			cmd->result = (DID_ERROR << 16);
++			scmd_printk(KERN_DEBUG, cmd,
++				    "Unknown completion status: 0x%x\n",
++				    btstat);
++	}
++
++	dev_dbg(&cmd->device->sdev_gendev,
++		"cmd=%p %x ctx=%p result=0x%x status=0x%x,%x\n",
++		cmd, cmd->cmnd[0], ctx, cmd->result, btstat, sdstat);
++
++	cmd->scsi_done(cmd);
++}
++
++/*
++ * barrier usage : Since the PVSCSI device is emulated, there could be cases
++ * where we may want to serialize some accesses between the driver and the
++ * emulation layer. We use compiler barriers instead of the more expensive
++ * memory barriers because PVSCSI is only supported on X86 which has strong
++ * memory access ordering.
++ */
++static void pvscsi_process_completion_ring(struct pvscsi_adapter *adapter)
++{
++	struct PVSCSIRingsState *s = adapter->rings_state;
++	struct PVSCSIRingCmpDesc *ring = adapter->cmp_ring;
++	u32 cmp_entries = s->cmpNumEntriesLog2;
++
++	while (s->cmpConsIdx != s->cmpProdIdx) {
++		struct PVSCSIRingCmpDesc *e = ring + (s->cmpConsIdx &
++						      MASK(cmp_entries));
++		/*
++		 * This barrier() ensures that *e is not dereferenced while
++		 * the device emulation still writes data into the slot.
++		 * Since the device emulation advances s->cmpProdIdx only after
++		 * updating the slot we want to check it first.
++		 */
++		barrier();
++		pvscsi_complete_request(adapter, e);
++		/*
++		 * This barrier() ensures that compiler doesn't reorder write
++		 * to s->cmpConsIdx before the read of (*e) inside
++		 * pvscsi_complete_request. Otherwise, device emulation may
++		 * overwrite *e before we had a chance to read it.
++		 */
++		barrier();
++		s->cmpConsIdx++;
++	}
++}
++
++/*
++ * Translate a Linux SCSI request into a request ring entry.
++ */
++static int pvscsi_queue_ring(struct pvscsi_adapter *adapter,
++			     struct pvscsi_ctx *ctx, struct scsi_cmnd *cmd)
++{
++	struct PVSCSIRingsState *s;
++	struct PVSCSIRingReqDesc *e;
++	struct scsi_device *sdev;
++	u32 req_entries;
++
++	s = adapter->rings_state;
++	sdev = cmd->device;
++	req_entries = s->reqNumEntriesLog2;
++
++	/*
++	 * If this condition holds, we might have room on the request ring, but
++	 * we might not have room on the completion ring for the response.
++	 * However, we have already ruled out this possibility - we would not
++	 * have successfully allocated a context if it were true, since we only
++	 * have one context per request entry.  Check for it anyway, since it
++	 * would be a serious bug.
++	 */
++	if (s->reqProdIdx - s->cmpConsIdx >= 1 << req_entries) {
++		scmd_printk(KERN_ERR, cmd, "vmw_pvscsi: "
++			    "ring full: reqProdIdx=%d cmpConsIdx=%d\n",
++			    s->reqProdIdx, s->cmpConsIdx);
++		return -1;
++	}
++
++	e = adapter->req_ring + (s->reqProdIdx & MASK(req_entries));
++
++	e->bus    = sdev->channel;
++	e->target = sdev->id;
++	memset(e->lun, 0, sizeof(e->lun));
++	e->lun[1] = sdev->lun;
++
++	if (cmd->sense_buffer) {
++		ctx->sensePA = pci_map_single(adapter->dev, cmd->sense_buffer,
++					      SCSI_SENSE_BUFFERSIZE,
++					      PCI_DMA_FROMDEVICE);
++		e->senseAddr = ctx->sensePA;
++		e->senseLen = SCSI_SENSE_BUFFERSIZE;
++	} else {
++		e->senseLen  = 0;
++		e->senseAddr = 0;
++	}
++	e->cdbLen   = cmd->cmd_len;
++	e->vcpuHint = smp_processor_id();
++	memcpy(e->cdb, cmd->cmnd, e->cdbLen);
++
++	e->tag = SIMPLE_QUEUE_TAG;
++	if (sdev->tagged_supported &&
++	    (cmd->tag == HEAD_OF_QUEUE_TAG ||
++	     cmd->tag == ORDERED_QUEUE_TAG))
++		e->tag = cmd->tag;
++
++	if (cmd->sc_data_direction == DMA_FROM_DEVICE)
++		e->flags = PVSCSI_FLAG_CMD_DIR_TOHOST;
++	else if (cmd->sc_data_direction == DMA_TO_DEVICE)
++		e->flags = PVSCSI_FLAG_CMD_DIR_TODEVICE;
++	else if (cmd->sc_data_direction == DMA_NONE)
++		e->flags = PVSCSI_FLAG_CMD_DIR_NONE;
++	else
++		e->flags = 0;
++
++	pvscsi_map_buffers(adapter, ctx, cmd, e);
++
++	e->context = pvscsi_map_context(adapter, ctx);
++
++	barrier();
++
++	s->reqProdIdx++;
++
++	return 0;
++}
++
++static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
++{
++	struct Scsi_Host *host = cmd->device->host;
++	struct pvscsi_adapter *adapter = shost_priv(host);
++	struct pvscsi_ctx *ctx;
++	unsigned long flags;
++
++	spin_lock_irqsave(&adapter->hw_lock, flags);
++
++	ctx = pvscsi_acquire_context(adapter, cmd);
++	if (!ctx || pvscsi_queue_ring(adapter, ctx, cmd) != 0) {
++		if (ctx)
++			pvscsi_release_context(adapter, ctx);
++		spin_unlock_irqrestore(&adapter->hw_lock, flags);
++		return SCSI_MLQUEUE_HOST_BUSY;
++	}
++
++	cmd->scsi_done = done;
++
++	dev_dbg(&cmd->device->sdev_gendev,
++		"queued cmd %p, ctx %p, op=%x\n", cmd, ctx, cmd->cmnd[0]);
++
++	spin_unlock_irqrestore(&adapter->hw_lock, flags);
++
++	pvscsi_kick_io(adapter, cmd->cmnd[0]);
++
++	return 0;
++}
++
++static int pvscsi_abort(struct scsi_cmnd *cmd)
++{
++	struct pvscsi_adapter *adapter = shost_priv(cmd->device->host);
++	struct pvscsi_ctx *ctx;
++	unsigned long flags;
++
++	scmd_printk(KERN_DEBUG, cmd, "task abort on host %u, %p\n",
++		    adapter->host->host_no, cmd);
++
++	spin_lock_irqsave(&adapter->hw_lock, flags);
++
++	/*
++	 * Poll the completion ring first - we might be trying to abort
++	 * a command that is waiting to be dispatched in the completion ring.
++	 */
++	pvscsi_process_completion_ring(adapter);
++
++	/*
++	 * If there is no context for the command, it either already succeeded
++	 * or else was never properly issued.  Not our problem.
++	 */
++	ctx = pvscsi_find_context(adapter, cmd);
++	if (!ctx) {
++		scmd_printk(KERN_DEBUG, cmd, "Failed to abort cmd %p\n", cmd);
++		goto out;
++	}
++
++	pvscsi_abort_cmd(adapter, ctx);
++
++	pvscsi_process_completion_ring(adapter);
++
++out:
++	spin_unlock_irqrestore(&adapter->hw_lock, flags);
++	return SUCCESS;
++}
++
++/*
++ * Abort all outstanding requests.  This is only safe to use if the completion
++ * ring will never be walked again or the device has been reset, because it
++ * destroys the 1-1 mapping between context field passed to emulation and our
++ * request structure.
++ */
++static void pvscsi_reset_all(struct pvscsi_adapter *adapter)
++{
++	unsigned i;
++
++	for (i = 0; i < adapter->req_depth; i++) {
++		struct pvscsi_ctx *ctx = &adapter->cmd_map[i];
++		struct scsi_cmnd *cmd = ctx->cmd;
++		if (cmd) {
++			scmd_printk(KERN_ERR, cmd,
++				    "Forced reset on cmd %p\n", cmd);
++			pvscsi_unmap_buffers(adapter, ctx);
++			pvscsi_release_context(adapter, ctx);
++			cmd->result = (DID_RESET << 16);
++			cmd->scsi_done(cmd);
++		}
++	}
++}
++
++static int pvscsi_host_reset(struct scsi_cmnd *cmd)
++{
++	struct Scsi_Host *host = cmd->device->host;
++	struct pvscsi_adapter *adapter = shost_priv(host);
++	unsigned long flags;
++	bool use_msg;
++
++	scmd_printk(KERN_INFO, cmd, "SCSI Host reset\n");
++
++	spin_lock_irqsave(&adapter->hw_lock, flags);
++
++	use_msg = adapter->use_msg;
++
++	if (use_msg) {
++		adapter->use_msg = 0;
++		spin_unlock_irqrestore(&adapter->hw_lock, flags);
++
++		/*
++		 * Now that we know that the ISR won't add more work on the
++		 * workqueue we can safely flush any outstanding work.
++		 */
++		flush_workqueue(adapter->workqueue);
++		spin_lock_irqsave(&adapter->hw_lock, flags);
++	}
++
++	/*
++	 * We're going to tear down the entire ring structure and set it back
++	 * up, so stalling new requests until all completions are flushed and
++	 * the rings are back in place.
++	 */
++
++	pvscsi_process_request_ring(adapter);
++
++	ll_adapter_reset(adapter);
++
++	/*
++	 * Now process any completions.  Note we do this AFTER adapter reset,
++	 * which is strange, but stops races where completions get posted
++	 * between processing the ring and issuing the reset.  The backend will
++	 * not touch the ring memory after reset, so the immediately pre-reset
++	 * completion ring state is still valid.
++	 */
++	pvscsi_process_completion_ring(adapter);
++
++	pvscsi_reset_all(adapter);
++	adapter->use_msg = use_msg;
++	pvscsi_setup_all_rings(adapter);
++	pvscsi_unmask_intr(adapter);
++
++	spin_unlock_irqrestore(&adapter->hw_lock, flags);
++
++	return SUCCESS;
++}
++
++static int pvscsi_bus_reset(struct scsi_cmnd *cmd)
++{
++	struct Scsi_Host *host = cmd->device->host;
++	struct pvscsi_adapter *adapter = shost_priv(host);
++	unsigned long flags;
++
++	scmd_printk(KERN_INFO, cmd, "SCSI Bus reset\n");
++
++	/*
++	 * We don't want to queue new requests for this bus after
++	 * flushing all pending requests to emulation, since new
++	 * requests could then sneak in during this bus reset phase,
++	 * so take the lock now.
++	 */
++	spin_lock_irqsave(&adapter->hw_lock, flags);
++
++	pvscsi_process_request_ring(adapter);
++	ll_bus_reset(adapter);
++	pvscsi_process_completion_ring(adapter);
++
++	spin_unlock_irqrestore(&adapter->hw_lock, flags);
++
++	return SUCCESS;
++}
++
++static int pvscsi_device_reset(struct scsi_cmnd *cmd)
++{
++	struct Scsi_Host *host = cmd->device->host;
++	struct pvscsi_adapter *adapter = shost_priv(host);
++	unsigned long flags;
++
++	scmd_printk(KERN_INFO, cmd, "SCSI device reset on scsi%u:%u\n",
++		    host->host_no, cmd->device->id);
++
++	/*
++	 * We don't want to queue new requests for this device after flushing
++	 * all pending requests to emulation, since new requests could then
++	 * sneak in during this device reset phase, so take the lock now.
++	 */
++	spin_lock_irqsave(&adapter->hw_lock, flags);
++
++	pvscsi_process_request_ring(adapter);
++	ll_device_reset(adapter, cmd->device->id);
++	pvscsi_process_completion_ring(adapter);
++
++	spin_unlock_irqrestore(&adapter->hw_lock, flags);
++
++	return SUCCESS;
++}
++
++static struct scsi_host_template pvscsi_template;
++
++static const char *pvscsi_info(struct Scsi_Host *host)
++{
++	struct pvscsi_adapter *adapter = shost_priv(host);
++	static char buf[256];
++
++	sprintf(buf, "VMware PVSCSI storage adapter rev %d, req/cmp/msg rings: "
++		"%u/%u/%u pages, cmd_per_lun=%u", adapter->rev,
++		adapter->req_pages, adapter->cmp_pages, adapter->msg_pages,
++		pvscsi_template.cmd_per_lun);
++
++	return buf;
++}
++
++static struct scsi_host_template pvscsi_template = {
++	.module				= THIS_MODULE,
++	.name				= "VMware PVSCSI Host Adapter",
++	.proc_name			= "vmw_pvscsi",
++	.info				= pvscsi_info,
++	.queuecommand			= pvscsi_queue,
++	.this_id			= -1,
++	.sg_tablesize			= PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT,
++	.dma_boundary			= UINT_MAX,
++	.max_sectors			= 0xffff,
++	.use_clustering			= ENABLE_CLUSTERING,
++	.eh_abort_handler		= pvscsi_abort,
++	.eh_device_reset_handler	= pvscsi_device_reset,
++	.eh_bus_reset_handler		= pvscsi_bus_reset,
++	.eh_host_reset_handler		= pvscsi_host_reset,
++};
++
++static void pvscsi_process_msg(const struct pvscsi_adapter *adapter,
++			       const struct PVSCSIRingMsgDesc *e)
++{
++	struct PVSCSIRingsState *s = adapter->rings_state;
++	struct Scsi_Host *host = adapter->host;
++	struct scsi_device *sdev;
++
++	printk(KERN_INFO "vmw_pvscsi: msg type: 0x%x - MSG RING: %u/%u (%u) \n",
++	       e->type, s->msgProdIdx, s->msgConsIdx, s->msgNumEntriesLog2);
++
++	BUILD_BUG_ON(PVSCSI_MSG_LAST != 2);
++
++	if (e->type == PVSCSI_MSG_DEV_ADDED) {
++		struct PVSCSIMsgDescDevStatusChanged *desc;
++		desc = (struct PVSCSIMsgDescDevStatusChanged *)e;
++
++		printk(KERN_INFO
++		       "vmw_pvscsi: msg: device added at scsi%u:%u:%u\n",
++		       desc->bus, desc->target, desc->lun[1]);
++
++		if (!scsi_host_get(host))
++			return;
++
++		sdev = scsi_device_lookup(host, desc->bus, desc->target,
++					  desc->lun[1]);
++		if (sdev) {
++			printk(KERN_INFO "vmw_pvscsi: device already exists\n");
++			scsi_device_put(sdev);
++		} else
++			scsi_add_device(adapter->host, desc->bus,
++					desc->target, desc->lun[1]);
++
++		scsi_host_put(host);
++	} else if (e->type == PVSCSI_MSG_DEV_REMOVED) {
++		struct PVSCSIMsgDescDevStatusChanged *desc;
++		desc = (struct PVSCSIMsgDescDevStatusChanged *)e;
++
++		printk(KERN_INFO
++		       "vmw_pvscsi: msg: device removed at scsi%u:%u:%u\n",
++		       desc->bus, desc->target, desc->lun[1]);
++
++		if (!scsi_host_get(host))
++			return;
++
++		sdev = scsi_device_lookup(host, desc->bus, desc->target,
++					  desc->lun[1]);
++		if (sdev) {
++			scsi_remove_device(sdev);
++			scsi_device_put(sdev);
++		} else
++			printk(KERN_INFO
++			       "vmw_pvscsi: failed to lookup scsi%u:%u:%u\n",
++			       desc->bus, desc->target, desc->lun[1]);
++
++		scsi_host_put(host);
++	}
++}
++
++static int pvscsi_msg_pending(const struct pvscsi_adapter *adapter)
++{
++	struct PVSCSIRingsState *s = adapter->rings_state;
++
++	return s->msgProdIdx != s->msgConsIdx;
++}
++
++static void pvscsi_process_msg_ring(const struct pvscsi_adapter *adapter)
++{
++	struct PVSCSIRingsState *s = adapter->rings_state;
++	struct PVSCSIRingMsgDesc *ring = adapter->msg_ring;
++	u32 msg_entries = s->msgNumEntriesLog2;
++
++	while (pvscsi_msg_pending(adapter)) {
++		struct PVSCSIRingMsgDesc *e = ring + (s->msgConsIdx &
++						      MASK(msg_entries));
++
++		barrier();
++		pvscsi_process_msg(adapter, e);
++		barrier();
++		s->msgConsIdx++;
++	}
++}
++
++static void pvscsi_msg_workqueue_handler(struct work_struct *data)
++{
++	struct pvscsi_adapter *adapter;
++
++	adapter = container_of(data, struct pvscsi_adapter, work);
++
++	pvscsi_process_msg_ring(adapter);
++}
++
++static int pvscsi_setup_msg_workqueue(struct pvscsi_adapter *adapter)
++{
++	char name[32];
++
++	if (!pvscsi_use_msg)
++		return 0;
++
++	pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_COMMAND,
++			 PVSCSI_CMD_SETUP_MSG_RING);
++
++	if (pvscsi_reg_read(adapter, PVSCSI_REG_OFFSET_COMMAND_STATUS) == -1)
++		return 0;
++
++	snprintf(name, sizeof(name),
++		 "vmw_pvscsi_wq_%u", adapter->host->host_no);
++
++	adapter->workqueue = create_singlethread_workqueue(name);
++	if (!adapter->workqueue) {
++		printk(KERN_ERR "vmw_pvscsi: failed to create work queue\n");
++		return 0;
++	}
++	INIT_WORK(&adapter->work, pvscsi_msg_workqueue_handler);
++
++	return 1;
++}
++
++static irqreturn_t pvscsi_isr(int irq, void *devp)
++{
++	struct pvscsi_adapter *adapter = devp;
++	int handled;
++
++	if (adapter->use_msi || adapter->use_msix)
++		handled = true;
++	else {
++		u32 val = pvscsi_read_intr_status(adapter);
++		handled = (val & PVSCSI_INTR_ALL_SUPPORTED) != 0;
++		if (handled)
++			pvscsi_write_intr_status(devp, val);
++	}
++
++	if (handled) {
++		unsigned long flags;
++
++		spin_lock_irqsave(&adapter->hw_lock, flags);
++
++		pvscsi_process_completion_ring(adapter);
++		if (adapter->use_msg && pvscsi_msg_pending(adapter))
++			queue_work(adapter->workqueue, &adapter->work);
++
++		spin_unlock_irqrestore(&adapter->hw_lock, flags);
++	}
++
++	return IRQ_RETVAL(handled);
++}
++
++static void pvscsi_free_sgls(const struct pvscsi_adapter *adapter)
++{
++	struct pvscsi_ctx *ctx = adapter->cmd_map;
++	unsigned i;
++
++	for (i = 0; i < adapter->req_depth; ++i, ++ctx)
++		kfree(ctx->sgl);
++}
++
++static int pvscsi_setup_msix(const struct pvscsi_adapter *adapter, int *irq)
++{
++	struct msix_entry entry = { 0, PVSCSI_VECTOR_COMPLETION };
++	int ret;
++
++	ret = pci_enable_msix(adapter->dev, &entry, 1);
++	if (ret)
++		return ret;
++
++	*irq = entry.vector;
++
++	return 0;
++}
++
++static void pvscsi_shutdown_intr(struct pvscsi_adapter *adapter)
++{
++	if (adapter->irq) {
++		free_irq(adapter->irq, adapter);
++		adapter->irq = 0;
++	}
++	if (adapter->use_msi) {
++		pci_disable_msi(adapter->dev);
++		adapter->use_msi = 0;
++	} else if (adapter->use_msix) {
++		pci_disable_msix(adapter->dev);
++		adapter->use_msix = 0;
++	}
++}
++
++static void pvscsi_release_resources(struct pvscsi_adapter *adapter)
++{
++	pvscsi_shutdown_intr(adapter);
++
++	if (adapter->workqueue)
++		destroy_workqueue(adapter->workqueue);
++
++	if (adapter->mmioBase)
++		pci_iounmap(adapter->dev, adapter->mmioBase);
++
++	pci_release_regions(adapter->dev);
++
++	if (adapter->cmd_map) {
++		pvscsi_free_sgls(adapter);
++		kfree(adapter->cmd_map);
++	}
++
++	if (adapter->rings_state)
++		pci_free_consistent(adapter->dev, PAGE_SIZE,
++				    adapter->rings_state, adapter->ringStatePA);
++
++	if (adapter->req_ring)
++		pci_free_consistent(adapter->dev,
++				    adapter->req_pages * PAGE_SIZE,
++				    adapter->req_ring, adapter->reqRingPA);
++
++	if (adapter->cmp_ring)
++		pci_free_consistent(adapter->dev,
++				    adapter->cmp_pages * PAGE_SIZE,
++				    adapter->cmp_ring, adapter->cmpRingPA);
++
++	if (adapter->msg_ring)
++		pci_free_consistent(adapter->dev,
++				    adapter->msg_pages * PAGE_SIZE,
++				    adapter->msg_ring, adapter->msgRingPA);
++}
++
++/*
++ * Allocate scatter gather lists.
++ *
++ * These are statically allocated.  Trying to be clever was not worth it.
++ *
++ * Dynamic allocation can fail, and we can't go deeep into the memory
++ * allocator, since we're a SCSI driver, and trying too hard to allocate
++ * memory might generate disk I/O.  We also don't want to fail disk I/O
++ * in that case because we can't get an allocation - the I/O could be
++ * trying to swap out data to free memory.  Since that is pathological,
++ * just use a statically allocated scatter list.
++ *
++ */
++static int __devinit pvscsi_allocate_sg(struct pvscsi_adapter *adapter)
++{
++	struct pvscsi_ctx *ctx;
++	int i;
++
++	ctx = adapter->cmd_map;
++	BUILD_BUG_ON(sizeof(struct pvscsi_sg_list) > SGL_SIZE);
++
++	for (i = 0; i < adapter->req_depth; ++i, ++ctx) {
++		ctx->sgl = kmalloc(SGL_SIZE, GFP_KERNEL);
++		ctx->sglPA = 0;
++		BUG_ON(!IS_ALIGNED(((unsigned long)ctx->sgl), PAGE_SIZE));
++		if (!ctx->sgl) {
++			for (; i >= 0; --i, --ctx) {
++				kfree(ctx->sgl);
++				ctx->sgl = NULL;
++			}
++			return -ENOMEM;
++		}
++	}
++
++	return 0;
++}
++
++static int __devinit pvscsi_probe(struct pci_dev *pdev,
++				  const struct pci_device_id *id)
++{
++	struct pvscsi_adapter *adapter;
++	struct Scsi_Host *host;
++	unsigned int i;
++	int error;
++
++	error = -ENODEV;
++
++	if (pci_enable_device(pdev))
++		return error;
++
++	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0 &&
++	    pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
++		printk(KERN_INFO "vmw_pvscsi: using 64bit dma\n");
++	} else if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) == 0 &&
++		   pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) == 0) {
++		printk(KERN_INFO "vmw_pvscsi: using 32bit dma\n");
++	} else {
++		printk(KERN_ERR "vmw_pvscsi: failed to set DMA mask\n");
++		goto out_disable_device;
++	}
++
++	pvscsi_template.can_queue =
++		min(PVSCSI_MAX_NUM_PAGES_REQ_RING, pvscsi_ring_pages) *
++		PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
++	pvscsi_template.cmd_per_lun =
++		min(pvscsi_template.can_queue, pvscsi_cmd_per_lun);
++	host = scsi_host_alloc(&pvscsi_template, sizeof(struct pvscsi_adapter));
++	if (!host) {
++		printk(KERN_ERR "vmw_pvscsi: failed to allocate host\n");
++		goto out_disable_device;
++	}
++
++	adapter = shost_priv(host);
++	memset(adapter, 0, sizeof(*adapter));
++	adapter->dev  = pdev;
++	adapter->host = host;
++
++	spin_lock_init(&adapter->hw_lock);
++
++	host->max_channel = 0;
++	host->max_id      = 16;
++	host->max_lun     = 1;
++	host->max_cmd_len = 16;
++
++	adapter->rev = pdev->revision;
++
++	if (pci_request_regions(pdev, "vmw_pvscsi")) {
++		printk(KERN_ERR "vmw_pvscsi: pci memory selection failed\n");
++		goto out_free_host;
++	}
++
++	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
++		if ((pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO))
++			continue;
++
++		if (pci_resource_len(pdev, i) < PVSCSI_MEM_SPACE_SIZE)
++			continue;
++
++		break;
++	}
++
++	if (i == DEVICE_COUNT_RESOURCE) {
++		printk(KERN_ERR
++		       "vmw_pvscsi: adapter has no suitable MMIO region\n");
++		goto out_release_resources;
++	}
++
++	adapter->mmioBase = pci_iomap(pdev, i, PVSCSI_MEM_SPACE_SIZE);
++
++	if (!adapter->mmioBase) {
++		printk(KERN_ERR
++		       "vmw_pvscsi: can't iomap for BAR %d memsize %lu\n",
++		       i, PVSCSI_MEM_SPACE_SIZE);
++		goto out_release_resources;
++	}
++
++	pci_set_master(pdev);
++	pci_set_drvdata(pdev, host);
++
++	ll_adapter_reset(adapter);
++
++	adapter->use_msg = pvscsi_setup_msg_workqueue(adapter);
++
++	error = pvscsi_allocate_rings(adapter);
++	if (error) {
++		printk(KERN_ERR "vmw_pvscsi: unable to allocate ring memory\n");
++		goto out_release_resources;
++	}
++
++	/*
++	 * From this point on we should reset the adapter if anything goes
++	 * wrong.
++	 */
++	pvscsi_setup_all_rings(adapter);
++
++	adapter->cmd_map = kcalloc(adapter->req_depth,
++				   sizeof(struct pvscsi_ctx), GFP_KERNEL);
++	if (!adapter->cmd_map) {
++		printk(KERN_ERR "vmw_pvscsi: failed to allocate memory.\n");
++		error = -ENOMEM;
++		goto out_reset_adapter;
++	}
++
++	INIT_LIST_HEAD(&adapter->cmd_pool);
++	for (i = 0; i < adapter->req_depth; i++) {
++		struct pvscsi_ctx *ctx = adapter->cmd_map + i;
++		list_add(&ctx->list, &adapter->cmd_pool);
++	}
++
++	error = pvscsi_allocate_sg(adapter);
++	if (error) {
++		printk(KERN_ERR "vmw_pvscsi: unable to allocate s/g table\n");
++		goto out_reset_adapter;
++	}
++
++	if (!pvscsi_disable_msix &&
++	    pvscsi_setup_msix(adapter, &adapter->irq) == 0) {
++		printk(KERN_INFO "vmw_pvscsi: using MSI-X\n");
++		adapter->use_msix = 1;
++	} else if (!pvscsi_disable_msi && pci_enable_msi(pdev) == 0) {
++		printk(KERN_INFO "vmw_pvscsi: using MSI\n");
++		adapter->use_msi = 1;
++		adapter->irq = pdev->irq;
++	} else {
++		printk(KERN_INFO "vmw_pvscsi: using INTx\n");
++		adapter->irq = pdev->irq;
++	}
++
++	error = request_irq(adapter->irq, pvscsi_isr, IRQF_SHARED,
++			    "vmw_pvscsi", adapter);
++	if (error) {
++		printk(KERN_ERR
++		       "vmw_pvscsi: unable to request IRQ: %d\n", error);
++		adapter->irq = 0;
++		goto out_reset_adapter;
++	}
++
++	error = scsi_add_host(host, &pdev->dev);
++	if (error) {
++		printk(KERN_ERR
++		       "vmw_pvscsi: scsi_add_host failed: %d\n", error);
++		goto out_reset_adapter;
++	}
++
++	dev_info(&pdev->dev, "VMware PVSCSI rev %d host #%u\n",
++		 adapter->rev, host->host_no);
++
++	pvscsi_unmask_intr(adapter);
++
++	scsi_scan_host(host);
++
++	return 0;
++
++out_reset_adapter:
++	ll_adapter_reset(adapter);
++out_release_resources:
++	pvscsi_release_resources(adapter);
++out_free_host:
++	scsi_host_put(host);
++out_disable_device:
++	pci_set_drvdata(pdev, NULL);
++	pci_disable_device(pdev);
++
++	return error;
++}
++
++static void __pvscsi_shutdown(struct pvscsi_adapter *adapter)
++{
++	pvscsi_mask_intr(adapter);
++
++	if (adapter->workqueue)
++		flush_workqueue(adapter->workqueue);
++
++	pvscsi_shutdown_intr(adapter);
++
++	pvscsi_process_request_ring(adapter);
++	pvscsi_process_completion_ring(adapter);
++	ll_adapter_reset(adapter);
++}
++
++static void pvscsi_shutdown(struct pci_dev *dev)
++{
++	struct Scsi_Host *host = pci_get_drvdata(dev);
++	struct pvscsi_adapter *adapter = shost_priv(host);
++
++	__pvscsi_shutdown(adapter);
++}
++
++static void pvscsi_remove(struct pci_dev *pdev)
++{
++	struct Scsi_Host *host = pci_get_drvdata(pdev);
++	struct pvscsi_adapter *adapter = shost_priv(host);
++
++	scsi_remove_host(host);
++
++	__pvscsi_shutdown(adapter);
++	pvscsi_release_resources(adapter);
++
++	scsi_host_put(host);
++
++	pci_set_drvdata(pdev, NULL);
++	pci_disable_device(pdev);
++}
++
++static struct pci_driver pvscsi_pci_driver = {
++	.name		= "vmw_pvscsi",
++	.id_table	= pvscsi_pci_tbl,
++	.probe		= pvscsi_probe,
++	.remove		= __devexit_p(pvscsi_remove),
++	.shutdown       = pvscsi_shutdown,
++};
++
++static int __init pvscsi_init(void)
++{
++	pr_info("%s - version %s\n",
++		PVSCSI_LINUX_DRIVER_DESC, PVSCSI_DRIVER_VERSION_STRING);
++	return pci_register_driver(&pvscsi_pci_driver);
++}
++
++static void __exit pvscsi_exit(void)
++{
++	pci_unregister_driver(&pvscsi_pci_driver);
++}
++
++module_init(pvscsi_init);
++module_exit(pvscsi_exit);
+diff --git a/drivers/scsi/vmw_pvscsi.h b/drivers/scsi/vmw_pvscsi.h
+new file mode 100644
+index 0000000..62e36e7
+--- /dev/null
++++ b/drivers/scsi/vmw_pvscsi.h
+@@ -0,0 +1,397 @@
++/*
++ * VMware PVSCSI header file
++ *
++ * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; version 2 of the License and no later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
++ * NON INFRINGEMENT.  See the GNU General Public License for more
++ * details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Maintained by: Alok N Kataria <akataria@vmware.com>
++ *
++ */
++
++#ifndef _VMW_PVSCSI_H_
++#define _VMW_PVSCSI_H_
++
++#include <linux/types.h>
++
++#define PVSCSI_DRIVER_VERSION_STRING   "1.0.1.0-k"
++
++#define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128
++
++#define MASK(n)        ((1 << (n)) - 1)        /* make an n-bit mask */
++
++#define PCI_VENDOR_ID_VMWARE		0x15AD
++#define PCI_DEVICE_ID_VMWARE_PVSCSI	0x07C0
++
++/*
++ * host adapter status/error codes
++ */
++enum HostBusAdapterStatus {
++   BTSTAT_SUCCESS       = 0x00,  /* CCB complete normally with no errors */
++   BTSTAT_LINKED_COMMAND_COMPLETED           = 0x0a,
++   BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b,
++   BTSTAT_DATA_UNDERRUN = 0x0c,
++   BTSTAT_SELTIMEO      = 0x11,  /* SCSI selection timeout */
++   BTSTAT_DATARUN       = 0x12,  /* data overrun/underrun */
++   BTSTAT_BUSFREE       = 0x13,  /* unexpected bus free */
++   BTSTAT_INVPHASE      = 0x14,  /* invalid bus phase or sequence requested by target */
++   BTSTAT_LUNMISMATCH   = 0x17,  /* linked CCB has different LUN from first CCB */
++   BTSTAT_SENSFAILED    = 0x1b,  /* auto request sense failed */
++   BTSTAT_TAGREJECT     = 0x1c,  /* SCSI II tagged queueing message rejected by target */
++   BTSTAT_BADMSG        = 0x1d,  /* unsupported message received by the host adapter */
++   BTSTAT_HAHARDWARE    = 0x20,  /* host adapter hardware failed */
++   BTSTAT_NORESPONSE    = 0x21,  /* target did not respond to SCSI ATN, sent a SCSI RST */
++   BTSTAT_SENTRST       = 0x22,  /* host adapter asserted a SCSI RST */
++   BTSTAT_RECVRST       = 0x23,  /* other SCSI devices asserted a SCSI RST */
++   BTSTAT_DISCONNECT    = 0x24,  /* target device reconnected improperly (w/o tag) */
++   BTSTAT_BUSRESET      = 0x25,  /* host adapter issued BUS device reset */
++   BTSTAT_ABORTQUEUE    = 0x26,  /* abort queue generated */
++   BTSTAT_HASOFTWARE    = 0x27,  /* host adapter software error */
++   BTSTAT_HATIMEOUT     = 0x30,  /* host adapter hardware timeout error */
++   BTSTAT_SCSIPARITY    = 0x34,  /* SCSI parity error detected */
++};
++
++/*
++ * Register offsets.
++ *
++ * These registers are accessible both via i/o space and mm i/o.
++ */
++
++enum PVSCSIRegOffset {
++	PVSCSI_REG_OFFSET_COMMAND        =    0x0,
++	PVSCSI_REG_OFFSET_COMMAND_DATA   =    0x4,
++	PVSCSI_REG_OFFSET_COMMAND_STATUS =    0x8,
++	PVSCSI_REG_OFFSET_LAST_STS_0     =  0x100,
++	PVSCSI_REG_OFFSET_LAST_STS_1     =  0x104,
++	PVSCSI_REG_OFFSET_LAST_STS_2     =  0x108,
++	PVSCSI_REG_OFFSET_LAST_STS_3     =  0x10c,
++	PVSCSI_REG_OFFSET_INTR_STATUS    = 0x100c,
++	PVSCSI_REG_OFFSET_INTR_MASK      = 0x2010,
++	PVSCSI_REG_OFFSET_KICK_NON_RW_IO = 0x3014,
++	PVSCSI_REG_OFFSET_DEBUG          = 0x3018,
++	PVSCSI_REG_OFFSET_KICK_RW_IO     = 0x4018,
++};
++
++/*
++ * Virtual h/w commands.
++ */
++
++enum PVSCSICommands {
++	PVSCSI_CMD_FIRST             = 0, /* has to be first */
++
++	PVSCSI_CMD_ADAPTER_RESET     = 1,
++	PVSCSI_CMD_ISSUE_SCSI        = 2,
++	PVSCSI_CMD_SETUP_RINGS       = 3,
++	PVSCSI_CMD_RESET_BUS         = 4,
++	PVSCSI_CMD_RESET_DEVICE      = 5,
++	PVSCSI_CMD_ABORT_CMD         = 6,
++	PVSCSI_CMD_CONFIG            = 7,
++	PVSCSI_CMD_SETUP_MSG_RING    = 8,
++	PVSCSI_CMD_DEVICE_UNPLUG     = 9,
++
++	PVSCSI_CMD_LAST              = 10  /* has to be last */
++};
 +
- 	if ((errsts = check_readiness(scp, 1, devip)))
- 		return errsts;
- 	memset(arr, 0, sizeof(arr));
-@@ -1492,6 +1494,8 @@ static int resp_log_sense(struct scsi_cmnd * scp,
- 	unsigned char arr[SDEBUG_MAX_LSENSE_SZ];
- 	unsigned char *cmd = (unsigned char *)scp->cmnd;
- 
-+	pax_track_stack();
++/*
++ * Command descriptor for PVSCSI_CMD_RESET_DEVICE --
++ */
 +
- 	if ((errsts = check_readiness(scp, 1, devip)))
- 		return errsts;
- 	memset(arr, 0, sizeof(arr));
-diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
-index 8df12522..c4c1472 100644
---- a/drivers/scsi/scsi_lib.c
-+++ b/drivers/scsi/scsi_lib.c
-@@ -1389,7 +1389,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
- 	shost = sdev->host;
- 	scsi_init_cmd_errh(cmd);
- 	cmd->result = DID_NO_CONNECT << 16;
--	atomic_inc(&cmd->device->iorequest_cnt);
-+	atomic_inc_unchecked(&cmd->device->iorequest_cnt);
- 
- 	/*
- 	 * SCSI request completion path will do scsi_device_unbusy(),
-@@ -1420,9 +1420,9 @@ static void scsi_softirq_done(struct request *rq)
- 	 */
- 	cmd->serial_number = 0;
- 
--	atomic_inc(&cmd->device->iodone_cnt);
-+	atomic_inc_unchecked(&cmd->device->iodone_cnt);
- 	if (cmd->result)
--		atomic_inc(&cmd->device->ioerr_cnt);
-+		atomic_inc_unchecked(&cmd->device->ioerr_cnt);
- 
- 	disposition = scsi_decide_disposition(cmd);
- 	if (disposition != SUCCESS &&
-diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
-index 91a93e0..eae0fe3 100644
---- a/drivers/scsi/scsi_sysfs.c
-+++ b/drivers/scsi/scsi_sysfs.c
-@@ -662,7 +662,7 @@ show_iostat_##field(struct device *dev, struct device_attribute *attr,	\
- 		    char *buf)						\
- {									\
- 	struct scsi_device *sdev = to_scsi_device(dev);			\
--	unsigned long long count = atomic_read(&sdev->field);		\
-+	unsigned long long count = atomic_read_unchecked(&sdev->field);	\
- 	return snprintf(buf, 20, "0x%llx\n", count);			\
- }									\
- static DEVICE_ATTR(field, S_IRUGO, show_iostat_##field, NULL)
-diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
-index 1030327..f91fd30 100644
---- a/drivers/scsi/scsi_tgt_lib.c
-+++ b/drivers/scsi/scsi_tgt_lib.c
-@@ -362,7 +362,7 @@ static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd,
- 	int err;
- 
- 	dprintk("%lx %u\n", uaddr, len);
--	err = blk_rq_map_user(q, rq, NULL, (void *)uaddr, len, GFP_KERNEL);
-+	err = blk_rq_map_user(q, rq, NULL, (void __user *)uaddr, len, GFP_KERNEL);
- 	if (err) {
- 		/*
- 		 * TODO: need to fixup sg_tablesize, max_segment_size,
-diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
-index db02e31..1b42ea9 100644
---- a/drivers/scsi/scsi_transport_fc.c
-+++ b/drivers/scsi/scsi_transport_fc.c
-@@ -480,7 +480,7 @@ MODULE_PARM_DESC(dev_loss_tmo,
-  * Netlink Infrastructure
-  */
- 
--static atomic_t fc_event_seq;
-+static atomic_unchecked_t fc_event_seq;
- 
- /**
-  * fc_get_event_number - Obtain the next sequential FC event number
-@@ -493,7 +493,7 @@ static atomic_t fc_event_seq;
- u32
- fc_get_event_number(void)
- {
--	return atomic_add_return(1, &fc_event_seq);
-+	return atomic_add_return_unchecked(1, &fc_event_seq);
- }
- EXPORT_SYMBOL(fc_get_event_number);
- 
-@@ -641,7 +641,7 @@ static __init int fc_transport_init(void)
- {
- 	int error;
- 
--	atomic_set(&fc_event_seq, 0);
-+	atomic_set_unchecked(&fc_event_seq, 0);
- 
- 	error = transport_class_register(&fc_host_class);
- 	if (error)
-diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
-index de2f8c4..63c5278 100644
---- a/drivers/scsi/scsi_transport_iscsi.c
-+++ b/drivers/scsi/scsi_transport_iscsi.c
-@@ -81,7 +81,7 @@ struct iscsi_internal {
- 	struct device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
- };
- 
--static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
-+static atomic_unchecked_t iscsi_session_nr; /* sysfs session id for next new session */
- static struct workqueue_struct *iscsi_eh_timer_workq;
- 
- /*
-@@ -728,7 +728,7 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
- 	int err;
- 
- 	ihost = shost->shost_data;
--	session->sid = atomic_add_return(1, &iscsi_session_nr);
-+	session->sid = atomic_add_return_unchecked(1, &iscsi_session_nr);
- 
- 	if (id == ISCSI_MAX_TARGET) {
- 		for (id = 0; id < ISCSI_MAX_TARGET; id++) {
-@@ -2060,7 +2060,7 @@ static __init int iscsi_transport_init(void)
- 	printk(KERN_INFO "Loading iSCSI transport class v%s.\n",
- 		ISCSI_TRANSPORT_VERSION);
- 
--	atomic_set(&iscsi_session_nr, 0);
-+	atomic_set_unchecked(&iscsi_session_nr, 0);
- 
- 	err = class_register(&iscsi_transport_class);
- 	if (err)
-diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
-index 21a045e..ec89e03 100644
---- a/drivers/scsi/scsi_transport_srp.c
-+++ b/drivers/scsi/scsi_transport_srp.c
-@@ -33,7 +33,7 @@
- #include "scsi_transport_srp_internal.h"
- 
- struct srp_host_attrs {
--	atomic_t next_port_id;
-+	atomic_unchecked_t next_port_id;
- };
- #define to_srp_host_attrs(host)	((struct srp_host_attrs *)(host)->shost_data)
- 
-@@ -62,7 +62,7 @@ static int srp_host_setup(struct transport_container *tc, struct device *dev,
- 	struct Scsi_Host *shost = dev_to_shost(dev);
- 	struct srp_host_attrs *srp_host = to_srp_host_attrs(shost);
- 
--	atomic_set(&srp_host->next_port_id, 0);
-+	atomic_set_unchecked(&srp_host->next_port_id, 0);
- 	return 0;
- }
- 
-@@ -211,7 +211,7 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost,
- 	memcpy(rport->port_id, ids->port_id, sizeof(rport->port_id));
- 	rport->roles = ids->roles;
- 
--	id = atomic_inc_return(&to_srp_host_attrs(shost)->next_port_id);
-+	id = atomic_inc_return_unchecked(&to_srp_host_attrs(shost)->next_port_id);
- 	dev_set_name(&rport->dev, "port-%d:%d", shost->host_no, id);
- 
- 	transport_setup_device(&rport->dev);
-diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
-index 040f751..98a5ed2 100644
---- a/drivers/scsi/sg.c
-+++ b/drivers/scsi/sg.c
-@@ -1064,7 +1064,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
- 				       sdp->disk->disk_name,
- 				       MKDEV(SCSI_GENERIC_MAJOR, sdp->index),
- 				       NULL,
--				       (char *)arg);
-+				       (char __user *)arg);
- 	case BLKTRACESTART:
- 		return blk_trace_startstop(sdp->device->request_queue, 1);
- 	case BLKTRACESTOP:
-@@ -2292,7 +2292,7 @@ struct sg_proc_leaf {
- 	const struct file_operations * fops;
- };
- 
--static struct sg_proc_leaf sg_proc_leaf_arr[] = {
-+static const struct sg_proc_leaf sg_proc_leaf_arr[] = {
- 	{"allow_dio", &adio_fops},
- 	{"debug", &debug_fops},
- 	{"def_reserved_size", &dressz_fops},
-@@ -2307,7 +2307,7 @@ sg_proc_init(void)
- {
- 	int k, mask;
- 	int num_leaves = ARRAY_SIZE(sg_proc_leaf_arr);
--	struct sg_proc_leaf * leaf;
-+	const struct sg_proc_leaf * leaf;
- 
- 	sg_proc_sgp = proc_mkdir(sg_proc_sg_dirname, NULL);
- 	if (!sg_proc_sgp)
-diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
-index c19ca5e..3eb5959 100644
---- a/drivers/scsi/sym53c8xx_2/sym_glue.c
-+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
-@@ -1758,6 +1758,8 @@ static int __devinit sym2_probe(struct pci_dev *pdev,
- 	int do_iounmap = 0;
- 	int do_disable_device = 1;
- 
-+	pax_track_stack();
++struct PVSCSICmdDescResetDevice {
++	u32	target;
++	u8	lun[8];
++} __packed;
 +
- 	memset(&sym_dev, 0, sizeof(sym_dev));
- 	memset(&nvram, 0, sizeof(nvram));
- 	sym_dev.pdev = pdev;
++/*
++ * Command descriptor for PVSCSI_CMD_ABORT_CMD --
++ *
++ * - currently does not support specifying the LUN.
++ * - _pad should be 0.
++ */
++
++struct PVSCSICmdDescAbortCmd {
++	u64	context;
++	u32	target;
++	u32	_pad;
++} __packed;
++
++/*
++ * Command descriptor for PVSCSI_CMD_SETUP_RINGS --
++ *
++ * Notes:
++ * - reqRingNumPages and cmpRingNumPages need to be power of two.
++ * - reqRingNumPages and cmpRingNumPages need to be different from 0,
++ * - reqRingNumPages and cmpRingNumPages need to be inferior to
++ *   PVSCSI_SETUP_RINGS_MAX_NUM_PAGES.
++ */
++
++#define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES        32
++struct PVSCSICmdDescSetupRings {
++	u32	reqRingNumPages;
++	u32	cmpRingNumPages;
++	u64	ringsStatePPN;
++	u64	reqRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
++	u64	cmpRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
++} __packed;
++
++/*
++ * Command descriptor for PVSCSI_CMD_SETUP_MSG_RING --
++ *
++ * Notes:
++ * - this command was not supported in the initial revision of the h/w
++ *   interface. Before using it, you need to check that it is supported by
++ *   writing PVSCSI_CMD_SETUP_MSG_RING to the 'command' register, then
++ *   immediately after read the 'command status' register:
++ *       * a value of -1 means that the cmd is NOT supported,
++ *       * a value != -1 means that the cmd IS supported.
++ *   If it's supported the 'command status' register should return:
++ *      sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(u32).
++ * - this command should be issued _after_ the usual SETUP_RINGS so that the
++ *   RingsState page is already setup. If not, the command is a nop.
++ * - numPages needs to be a power of two,
++ * - numPages needs to be different from 0,
++ * - _pad should be zero.
++ */
++
++#define PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES  16
++
++struct PVSCSICmdDescSetupMsgRing {
++	u32	numPages;
++	u32	_pad;
++	u64	ringPPNs[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES];
++} __packed;
++
++enum PVSCSIMsgType {
++	PVSCSI_MSG_DEV_ADDED          = 0,
++	PVSCSI_MSG_DEV_REMOVED        = 1,
++	PVSCSI_MSG_LAST               = 2,
++};
++
++/*
++ * Msg descriptor.
++ *
++ * sizeof(struct PVSCSIRingMsgDesc) == 128.
++ *
++ * - type is of type enum PVSCSIMsgType.
++ * - the content of args depend on the type of event being delivered.
++ */
++
++struct PVSCSIRingMsgDesc {
++	u32	type;
++	u32	args[31];
++} __packed;
++
++struct PVSCSIMsgDescDevStatusChanged {
++	u32	type;  /* PVSCSI_MSG_DEV _ADDED / _REMOVED */
++	u32	bus;
++	u32	target;
++	u8	lun[8];
++	u32	pad[27];
++} __packed;
++
++/*
++ * Rings state.
++ *
++ * - the fields:
++ *    . msgProdIdx,
++ *    . msgConsIdx,
++ *    . msgNumEntriesLog2,
++ *   .. are only used once the SETUP_MSG_RING cmd has been issued.
++ * - '_pad' helps to ensure that the msg related fields are on their own
++ *   cache-line.
++ */
++
++struct PVSCSIRingsState {
++	u32	reqProdIdx;
++	u32	reqConsIdx;
++	u32	reqNumEntriesLog2;
++
++	u32	cmpProdIdx;
++	u32	cmpConsIdx;
++	u32	cmpNumEntriesLog2;
++
++	u8	_pad[104];
++
++	u32	msgProdIdx;
++	u32	msgConsIdx;
++	u32	msgNumEntriesLog2;
++} __packed;
++
++/*
++ * Request descriptor.
++ *
++ * sizeof(RingReqDesc) = 128
++ *
++ * - context: is a unique identifier of a command. It could normally be any
++ *   64bit value, however we currently store it in the serialNumber variable
++ *   of struct SCSI_Command, so we have the following restrictions due to the
++ *   way this field is handled in the vmkernel storage stack:
++ *    * this value can't be 0,
++ *    * the upper 32bit need to be 0 since serialNumber is as a u32.
++ *   Currently tracked as PR 292060.
++ * - dataLen: contains the total number of bytes that need to be transferred.
++ * - dataAddr:
++ *   * if PVSCSI_FLAG_CMD_WITH_SG_LIST is set: dataAddr is the PA of the first
++ *     s/g table segment, each s/g segment is entirely contained on a single
++ *     page of physical memory,
++ *   * if PVSCSI_FLAG_CMD_WITH_SG_LIST is NOT set, then dataAddr is the PA of
++ *     the buffer used for the DMA transfer,
++ * - flags:
++ *   * PVSCSI_FLAG_CMD_WITH_SG_LIST: see dataAddr above,
++ *   * PVSCSI_FLAG_CMD_DIR_NONE: no DMA involved,
++ *   * PVSCSI_FLAG_CMD_DIR_TOHOST: transfer from device to main memory,
++ *   * PVSCSI_FLAG_CMD_DIR_TODEVICE: transfer from main memory to device,
++ *   * PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB: reserved to handle CDBs larger than
++ *     16bytes. To be specified.
++ * - vcpuHint: vcpuId of the processor that will be most likely waiting for the
++ *   completion of the i/o. For guest OSes that use lowest priority message
++ *   delivery mode (such as windows), we use this "hint" to deliver the
++ *   completion action to the proper vcpu. For now, we can use the vcpuId of
++ *   the processor that initiated the i/o as a likely candidate for the vcpu
++ *   that will be waiting for the completion..
++ * - bus should be 0: we currently only support bus 0 for now.
++ * - unused should be zero'd.
++ */
++
++#define PVSCSI_FLAG_CMD_WITH_SG_LIST        (1 << 0)
++#define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB     (1 << 1)
++#define PVSCSI_FLAG_CMD_DIR_NONE            (1 << 2)
++#define PVSCSI_FLAG_CMD_DIR_TOHOST          (1 << 3)
++#define PVSCSI_FLAG_CMD_DIR_TODEVICE        (1 << 4)
++
++struct PVSCSIRingReqDesc {
++	u64	context;
++	u64	dataAddr;
++	u64	dataLen;
++	u64	senseAddr;
++	u32	senseLen;
++	u32	flags;
++	u8	cdb[16];
++	u8	cdbLen;
++	u8	lun[8];
++	u8	tag;
++	u8	bus;
++	u8	target;
++	u8	vcpuHint;
++	u8	unused[59];
++} __packed;
++
++/*
++ * Scatter-gather list management.
++ *
++ * As described above, when PVSCSI_FLAG_CMD_WITH_SG_LIST is set in the
++ * RingReqDesc.flags, then RingReqDesc.dataAddr is the PA of the first s/g
++ * table segment.
++ *
++ * - each segment of the s/g table contain a succession of struct
++ *   PVSCSISGElement.
++ * - each segment is entirely contained on a single physical page of memory.
++ * - a "chain" s/g element has the flag PVSCSI_SGE_FLAG_CHAIN_ELEMENT set in
++ *   PVSCSISGElement.flags and in this case:
++ *     * addr is the PA of the next s/g segment,
++ *     * length is undefined, assumed to be 0.
++ */
++
++struct PVSCSISGElement {
++	u64	addr;
++	u32	length;
++	u32	flags;
++} __packed;
++
++/*
++ * Completion descriptor.
++ *
++ * sizeof(RingCmpDesc) = 32
++ *
++ * - context: identifier of the command. The same thing that was specified
++ *   under "context" as part of struct RingReqDesc at initiation time,
++ * - dataLen: number of bytes transferred for the actual i/o operation,
++ * - senseLen: number of bytes written into the sense buffer,
++ * - hostStatus: adapter status,
++ * - scsiStatus: device status,
++ * - _pad should be zero.
++ */
++
++struct PVSCSIRingCmpDesc {
++	u64	context;
++	u64	dataLen;
++	u32	senseLen;
++	u16	hostStatus;
++	u16	scsiStatus;
++	u32	_pad[2];
++} __packed;
++
++/*
++ * Interrupt status / IRQ bits.
++ */
++
++#define PVSCSI_INTR_CMPL_0                 (1 << 0)
++#define PVSCSI_INTR_CMPL_1                 (1 << 1)
++#define PVSCSI_INTR_CMPL_MASK              MASK(2)
++
++#define PVSCSI_INTR_MSG_0                  (1 << 2)
++#define PVSCSI_INTR_MSG_1                  (1 << 3)
++#define PVSCSI_INTR_MSG_MASK               (MASK(2) << 2)
++
++#define PVSCSI_INTR_ALL_SUPPORTED          MASK(4)
++
++/*
++ * Number of MSI-X vectors supported.
++ */
++#define PVSCSI_MAX_INTRS        24
++
++/*
++ * Enumeration of supported MSI-X vectors
++ */
++#define PVSCSI_VECTOR_COMPLETION   0
++
++/*
++ * Misc constants for the rings.
++ */
++
++#define PVSCSI_MAX_NUM_PAGES_REQ_RING   PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
++#define PVSCSI_MAX_NUM_PAGES_CMP_RING   PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
++#define PVSCSI_MAX_NUM_PAGES_MSG_RING   PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES
++
++#define PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \
++				(PAGE_SIZE / sizeof(struct PVSCSIRingReqDesc))
++
++#define PVSCSI_MAX_REQ_QUEUE_DEPTH \
++	(PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE)
++
++#define PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES     1
++#define PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES 1
++#define PVSCSI_MEM_SPACE_MISC_NUM_PAGES        2
++#define PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES     2
++#define PVSCSI_MEM_SPACE_MSIX_NUM_PAGES        2
++
++enum PVSCSIMemSpace {
++	PVSCSI_MEM_SPACE_COMMAND_PAGE		= 0,
++	PVSCSI_MEM_SPACE_INTR_STATUS_PAGE	= 1,
++	PVSCSI_MEM_SPACE_MISC_PAGE		= 2,
++	PVSCSI_MEM_SPACE_KICK_IO_PAGE		= 4,
++	PVSCSI_MEM_SPACE_MSIX_TABLE_PAGE	= 6,
++	PVSCSI_MEM_SPACE_MSIX_PBA_PAGE		= 7,
++};
++
++#define PVSCSI_MEM_SPACE_NUM_PAGES \
++	(PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES +       \
++	 PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES +   \
++	 PVSCSI_MEM_SPACE_MISC_NUM_PAGES +          \
++	 PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES +       \
++	 PVSCSI_MEM_SPACE_MSIX_NUM_PAGES)
++
++#define PVSCSI_MEM_SPACE_SIZE        (PVSCSI_MEM_SPACE_NUM_PAGES * PAGE_SIZE)
++
++#endif /* _VMW_PVSCSI_H_ */
 diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
 index eadc1ab..2d81457 100644
 --- a/drivers/serial/kgdboc.c
@@ -48256,7 +65997,7 @@ index a5bf577..6d19845 100644
          return hit;
  }
 diff --git a/fs/compat.c b/fs/compat.c
-index d1e2411..c2ef8ed 100644
+index d1e2411..9a958d2 100644
 --- a/fs/compat.c
 +++ b/fs/compat.c
 @@ -133,8 +133,8 @@ asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval _
@@ -48377,18 +66118,7 @@ index d1e2411..c2ef8ed 100644
  		goto out;
  	if (!file->f_op)
  		goto out;
-@@ -1454,6 +1472,10 @@ out:
- 	return ret;
- }
- 
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+extern atomic64_unchecked_t global_exec_counter;
-+#endif
-+
- /*
-  * compat_do_execve() is mostly a copy of do_execve(), with the exception
-  * that it processes 32 bit argv and envp pointers.
-@@ -1463,11 +1485,35 @@ int compat_do_execve(char * filename,
+@@ -1463,11 +1481,35 @@ int compat_do_execve(char * filename,
  	compat_uptr_t __user *envp,
  	struct pt_regs * regs)
  {
@@ -48424,7 +66154,7 @@ index d1e2411..c2ef8ed 100644
  
  	retval = unshare_files(&displaced);
  	if (retval)
-@@ -1493,12 +1539,26 @@ int compat_do_execve(char * filename,
+@@ -1493,12 +1535,26 @@ int compat_do_execve(char * filename,
  	if (IS_ERR(file))
  		goto out_unmark;
  
@@ -48451,24 +66181,10 @@ index d1e2411..c2ef8ed 100644
  	retval = bprm_mm_init(bprm);
  	if (retval)
  		goto out_file;
-@@ -1528,11 +1588,45 @@ int compat_do_execve(char * filename,
+@@ -1515,24 +1571,63 @@ int compat_do_execve(char * filename,
  	if (retval < 0)
  		goto out;
  
-+	if (!gr_tpe_allow(file)) {
-+		retval = -EACCES;
-+		goto out;
-+	}
-+
-+	if (gr_check_crash_exec(file)) {
-+		retval = -EACCES;
-+		goto out;
-+	}
-+
-+	gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
-+
-+	gr_handle_exec_args_compat(bprm, argv);
-+
 +#ifdef CONFIG_GRKERNSEC
 +	old_acl = current->acl;
 +	memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
@@ -48476,12 +66192,49 @@ index d1e2411..c2ef8ed 100644
 +	get_file(file);
 +	current->exec_file = file;
 +#endif
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++	/* limit suid stack to 8MB
++	   we saved the old limits above and will restore them if this exec fails
++	*/
++	if ((bprm->cred->euid != current_euid()) || (bprm->cred->egid != current_egid()))
++		current->signal->rlim[RLIMIT_STACK].rlim_cur = 8 * 1024 * 1024;
++#endif
++
++	if (!gr_tpe_allow(file)) {
++		retval = -EACCES;
++		goto out_fail;
++	}
++
++	if (gr_check_crash_exec(file)) {
++		retval = -EACCES;
++		goto out_fail;
++	}
 +
 +	retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
 +				   bprm->unsafe);
 +	if (retval < 0)
 +		goto out_fail;
 +
+ 	retval = copy_strings_kernel(1, &bprm->filename, bprm);
+ 	if (retval < 0)
+-		goto out;
++		goto out_fail;
+ 
+ 	bprm->exec = bprm->p;
+ 	retval = compat_copy_strings(bprm->envc, envp, bprm);
+ 	if (retval < 0)
+-		goto out;
++		goto out_fail;
+ 
+ 	retval = compat_copy_strings(bprm->argc, argv, bprm);
+ 	if (retval < 0)
+-		goto out;
++		goto out_fail;
++
++	gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
++
++	gr_handle_exec_args_compat(bprm, argv);
+ 
  	retval = search_binary_handler(bprm, regs);
  	if (retval < 0)
 -		goto out;
@@ -48492,13 +66245,11 @@ index d1e2411..c2ef8ed 100644
 +#endif
  
  	/* execve succeeded */
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+        current->exec_id = atomic64_inc_return_unchecked(&global_exec_counter);
-+#endif
++	increment_exec_counter();
  	current->fs->in_exec = 0;
  	current->in_execve = 0;
  	acct_update_integrals(current);
-@@ -1541,6 +1635,14 @@ int compat_do_execve(char * filename,
+@@ -1541,6 +1636,14 @@ int compat_do_execve(char * filename,
  		put_files_struct(displaced);
  	return retval;
  
@@ -48513,7 +66264,7 @@ index d1e2411..c2ef8ed 100644
  out:
  	if (bprm->mm) {
  		acct_arg_size(bprm, 0);
-@@ -1711,6 +1813,8 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
+@@ -1711,6 +1814,8 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
  	struct fdtable *fdt;
  	long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
  
@@ -48522,7 +66273,7 @@ index d1e2411..c2ef8ed 100644
  	if (n < 0)
  		goto out_nofds;
  
-@@ -2151,7 +2255,7 @@ asmlinkage long compat_sys_nfsservctl(int cmd,
+@@ -2151,7 +2256,7 @@ asmlinkage long compat_sys_nfsservctl(int cmd,
  	oldfs = get_fs();
  	set_fs(KERNEL_DS);
  	/* The __user pointer casts are valid because of the set_fs() */
@@ -48871,7 +66622,7 @@ index 4434e8f..fa05803 100644
  	}
  	mutex_unlock(&crypt_stat->cs_mutex);
 diff --git a/fs/exec.c b/fs/exec.c
-index 86fafc6..6272c0e 100644
+index 86fafc6..6a041a8 100644
 --- a/fs/exec.c
 +++ b/fs/exec.c
 @@ -56,12 +56,28 @@
@@ -48930,11 +66681,11 @@ index 86fafc6..6272c0e 100644
  			return page;
  
 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+		// only allow 1MB for argv+env on suid/sgid binaries
++		// only allow 512KB for argv+env on suid/sgid binaries
 +		// to prevent easy ASLR exhaustion
 +		if (((bprm->cred->euid != current_euid()) ||
 +		     (bprm->cred->egid != current_egid())) &&
-+		    (size > (1024 * 1024))) {
++		    (size > (512 * 1024))) {
 +			put_page(page);
 +			return NULL;
 +		}
@@ -48962,7 +66713,7 @@ index 86fafc6..6272c0e 100644
 +
 +#ifdef CONFIG_PAX_RANDUSTACK
 +	if (randomize_va_space)
-+		bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
++		bprm->p ^= random32() & ~PAGE_MASK;
 +#endif
 +
  	return 0;
@@ -49135,18 +66886,29 @@ index 86fafc6..6272c0e 100644
  		bprm->unsafe |= LSM_UNSAFE_SHARE;
  	} else {
  		res = -EAGAIN;
-@@ -1339,6 +1384,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
+@@ -1339,6 +1384,21 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
  
  EXPORT_SYMBOL(search_binary_handler);
  
 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+atomic64_unchecked_t global_exec_counter = ATOMIC64_INIT(0);
++DEFINE_PER_CPU(u64, exec_counter);
++static int __init init_exec_counters(void)
++{
++	unsigned int cpu;
++
++	for_each_possible_cpu(cpu) {
++		per_cpu(exec_counter, cpu) = (u64)cpu;
++	}
++
++	return 0;
++}
++early_initcall(init_exec_counters);
 +#endif
 +
  /*
   * sys_execve() executes a new program.
   */
-@@ -1347,11 +1396,35 @@ int do_execve(char * filename,
+@@ -1347,11 +1407,35 @@ int do_execve(char * filename,
  	char __user *__user *envp,
  	struct pt_regs * regs)
  {
@@ -49182,7 +66944,7 @@ index 86fafc6..6272c0e 100644
  
  	retval = unshare_files(&displaced);
  	if (retval)
-@@ -1377,12 +1450,27 @@ int do_execve(char * filename,
+@@ -1377,12 +1461,27 @@ int do_execve(char * filename,
  	if (IS_ERR(file))
  		goto out_unmark;
  
@@ -49210,24 +66972,10 @@ index 86fafc6..6272c0e 100644
  	retval = bprm_mm_init(bprm);
  	if (retval)
  		goto out_file;
-@@ -1412,12 +1500,47 @@ int do_execve(char * filename,
+@@ -1399,25 +1498,66 @@ int do_execve(char * filename,
  	if (retval < 0)
  		goto out;
  
-+	if (!gr_tpe_allow(file)) {
-+		retval = -EACCES;
-+		goto out;
-+	}
-+
-+	if (gr_check_crash_exec(file)) {
-+		retval = -EACCES;
-+		goto out;
-+	}
-+
-+	gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
-+
-+	gr_handle_exec_args(bprm, (const char __user *const __user *)argv);
-+
 +#ifdef CONFIG_GRKERNSEC
 +	old_acl = current->acl;
 +	memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
@@ -49235,12 +66983,50 @@ index 86fafc6..6272c0e 100644
 +	get_file(file);
 +	current->exec_file = file;
 +#endif
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++	/* limit suid stack to 8MB
++	   we saved the old limits above and will restore them if this exec fails
++	*/
++	if (((bprm->cred->euid != current_euid()) || (bprm->cred->egid != current_egid())) &&
++	    (old_rlim[RLIMIT_STACK].rlim_cur > (8 * 1024 * 1024)))
++		current->signal->rlim[RLIMIT_STACK].rlim_cur = 8 * 1024 * 1024;
++#endif
++
++	if (!gr_tpe_allow(file)) {
++		retval = -EACCES;
++		goto out_fail;
++	}
++
++	if (gr_check_crash_exec(file)) {
++		retval = -EACCES;
++		goto out_fail;
++	}
 +
 +	retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
 +				   bprm->unsafe);
 +	if (retval < 0)
 +		goto out_fail;
 +
+ 	retval = copy_strings_kernel(1, &bprm->filename, bprm);
+ 	if (retval < 0)
+-		goto out;
++		goto out_fail;
+ 
+ 	bprm->exec = bprm->p;
+ 	retval = copy_strings(bprm->envc, envp, bprm);
+ 	if (retval < 0)
+-		goto out;
++		goto out_fail;
+ 
+ 	retval = copy_strings(bprm->argc, argv, bprm);
+ 	if (retval < 0)
+-		goto out;
++		goto out_fail;
++
++	gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
++
++	gr_handle_exec_args(bprm, (const char __user *const __user *)argv);
+ 
  	current->flags &= ~PF_KTHREAD;
  	retval = search_binary_handler(bprm,regs);
  	if (retval < 0)
@@ -49252,14 +67038,12 @@ index 86fafc6..6272c0e 100644
 +#endif
  
  	/* execve succeeded */
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+	current->exec_id = atomic64_inc_return_unchecked(&global_exec_counter);
-+#endif
 +
++	increment_exec_counter();
  	current->fs->in_exec = 0;
  	current->in_execve = 0;
  	acct_update_integrals(current);
-@@ -1426,6 +1549,14 @@ int do_execve(char * filename,
+@@ -1426,6 +1566,14 @@ int do_execve(char * filename,
  		put_files_struct(displaced);
  	return retval;
  
@@ -49274,7 +67058,7 @@ index 86fafc6..6272c0e 100644
  out:
  	if (bprm->mm) {
  		acct_arg_size(bprm, 0);
-@@ -1591,6 +1722,220 @@ out:
+@@ -1591,6 +1739,219 @@ out:
  	return ispipe;
  }
  
@@ -49465,8 +67249,7 @@ index 86fafc6..6272c0e 100644
 +#endif
 +}
 +
-+
-+NORET_TYPE void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
++__noreturn void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
 +{
 +	if (current->signal->curr_ip)
 +		printk(KERN_ERR "PAX: From %pI4: kernel memory %s attempt detected %s %p (%s) (%lu bytes)\n",
@@ -49495,7 +67278,7 @@ index 86fafc6..6272c0e 100644
  static int zap_process(struct task_struct *start)
  {
  	struct task_struct *t;
-@@ -1793,17 +2138,17 @@ static void wait_for_dump_helpers(struct file *file)
+@@ -1793,17 +2154,17 @@ static void wait_for_dump_helpers(struct file *file)
  	pipe = file->f_path.dentry->d_inode->i_pipe;
  
  	pipe_lock(pipe);
@@ -49518,7 +67301,7 @@ index 86fafc6..6272c0e 100644
  	pipe_unlock(pipe);
  
  }
-@@ -1826,10 +2171,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -1826,10 +2187,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
  	char **helper_argv = NULL;
  	int helper_argc = 0;
  	int dump_count = 0;
@@ -49533,7 +67316,7 @@ index 86fafc6..6272c0e 100644
  	binfmt = mm->binfmt;
  	if (!binfmt || !binfmt->core_dump)
  		goto fail;
-@@ -1874,6 +2222,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -1874,6 +2238,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
  	 */
  	clear_thread_flag(TIF_SIGPENDING);
  
@@ -49542,7 +67325,7 @@ index 86fafc6..6272c0e 100644
  	/*
  	 * lock_kernel() because format_corename() is controlled by sysctl, which
  	 * uses lock_kernel()
-@@ -1908,7 +2258,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -1908,7 +2274,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
  			goto fail_unlock;
  		}
  
@@ -49551,7 +67334,7 @@ index 86fafc6..6272c0e 100644
  		if (core_pipe_limit && (core_pipe_limit < dump_count)) {
  			printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n",
  			       task_tgid_vnr(current), current->comm);
-@@ -1972,7 +2322,7 @@ close_fail:
+@@ -1972,7 +2338,7 @@ close_fail:
  	filp_close(file, NULL);
  fail_dropcount:
  	if (dump_count)
@@ -55467,10 +73250,10 @@ index 8f32f50..b6a41e8 100644
  		link[pathlen] = '\0';
 diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
 new file mode 100644
-index 0000000..7026cbd
+index 0000000..50819f8
 --- /dev/null
 +++ b/grsecurity/Kconfig
-@@ -0,0 +1,1074 @@
+@@ -0,0 +1,1077 @@
 +#
 +# grecurity configuration
 +#
@@ -55745,11 +73528,13 @@ index 0000000..7026cbd
 +	  dangerous sources of information, this option causes reads of sensitive
 +	  /proc/<pid> entries where the file descriptor was opened in a different
 +	  task than the one performing the read.  Such attempts are logged.
-+	  Finally, this option limits argv/env strings for suid/sgid binaries
-+	  to 1MB to prevent a complete exhaustion of the stack entropy provided
-+	  by ASLR.
++	  This option also limits argv/env strings for suid/sgid binaries
++	  to 512KB to prevent a complete exhaustion of the stack entropy provided
++	  by ASLR.  Finally, it places an 8MB stack resource limit on suid/sgid
++	  binaries to prevent alternative mmap layouts from being abused.
++
 +	  If you use PaX it is essential that you say Y here as it closes up
-+	  several holes that make full ASLR useless for suid/sgid binaries.
++	  several holes that make full ASLR useless locally.
 +
 +config GRKERNSEC_BRUTE
 +	bool "Deter exploit bruteforcing"
@@ -55888,8 +73673,9 @@ index 0000000..7026cbd
 +	  Depending upon the option you choose, you can either restrict users to
 +	  see only the processes they themselves run, or choose a group that can
 +	  view all processes and files normally restricted to root if you choose
-+	  the "restrict to user only" option.  NOTE: If you're running identd as
-+	  a non-root user, you will have to run it as the group you specify here.
++	  the "restrict to user only" option.  NOTE: If you're running identd or
++	  ntpd as a non-root user, you will have to run it as the group you
++	  specify here.
 +
 +config GRKERNSEC_PROC_USER
 +	bool "Restrict /proc to user only"
@@ -69115,6 +86901,18 @@ index 81c9689..a567a55 100644
  
  	/*
  	 * Protect attach/detach and child_list:
+diff --git a/include/linux/personality.h b/include/linux/personality.h
+index 1261208..ddef96f 100644
+--- a/include/linux/personality.h
++++ b/include/linux/personality.h
+@@ -43,6 +43,7 @@ enum {
+ #define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC  | \
+ 			    ADDR_NO_RANDOMIZE  | \
+ 			    ADDR_COMPAT_LAYOUT | \
++			    ADDR_LIMIT_3GB     | \
+ 			    MMAP_PAGE_ZERO)
+ 
+ /*
 diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
 index b43a9e0..b77d869 100644
 --- a/include/linux/pipe_fs_i.h
@@ -69174,6 +86972,18 @@ index 72b1a10..13303a9 100644
  
  /**
   * preempt_notifier - key for installing preemption notifiers
+diff --git a/include/linux/prefetch.h b/include/linux/prefetch.h
+index af7c36a..a93005c 100644
+--- a/include/linux/prefetch.h
++++ b/include/linux/prefetch.h
+@@ -11,6 +11,7 @@
+ #define _LINUX_PREFETCH_H
+ 
+ #include <linux/types.h>
++#include <linux/const.h>
+ #include <asm/processor.h>
+ #include <asm/cache.h>
+ 
 diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
 index 379eaed..1bf73e3 100644
 --- a/include/linux/proc_fs.h
@@ -69392,7 +87202,7 @@ index 3392c59..a746428 100644
  #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
  /**
 diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 71849bf..2ef383dc3 100644
+index 71849bf..8cf9dd2 100644
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
 @@ -101,6 +101,7 @@ struct bio;
@@ -69594,7 +87404,7 @@ index 71849bf..2ef383dc3 100644
 +extern void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
 +extern void pax_report_insns(struct pt_regs *regs, void *pc, void *sp);
 +extern void pax_report_refcount_overflow(struct pt_regs *regs);
-+extern NORET_TYPE void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type) ATTRIB_NORET;
++extern __noreturn void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type);
 +
 +#ifdef CONFIG_PAX_MEMORY_STACKLEAK
 +extern void pax_track_stack(void);
@@ -69637,7 +87447,7 @@ index 71849bf..2ef383dc3 100644
  extern void flush_itimer_signals(void);
  
 -extern NORET_TYPE void do_group_exit(int);
-+extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
++extern __noreturn void do_group_exit(int);
  
  extern void daemonize(const char *, ...);
  extern int allow_signal(int);
@@ -69661,6 +87471,30 @@ index 71849bf..2ef383dc3 100644
  extern void thread_info_cache_init(void);
  
  #ifdef CONFIG_DEBUG_STACK_USAGE
+@@ -2616,6 +2720,23 @@ static inline unsigned long rlimit_max(unsigned int limit)
+ 	return task_rlimit_max(current, limit);
+ }
+ 
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++DECLARE_PER_CPU(u64, exec_counter);
++static inline void increment_exec_counter(void)
++{
++	unsigned int cpu;
++	u64 *exec_id_ptr;
++        BUILD_BUG_ON(NR_CPUS > (1 << 16));
++	cpu = get_cpu();
++	exec_id_ptr = &per_cpu(exec_counter, cpu);
++	*exec_id_ptr += 1ULL << 16;
++        current->exec_id = *exec_id_ptr;
++	put_cpu();
++}
++#else
++static inline void increment_exec_counter(void) {}
++#endif
++
+ #endif /* __KERNEL__ */
+ 
+ #endif
 diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
 index 1ee2c05..81b7ec4 100644
 --- a/include/linux/screen_info.h
@@ -69772,7 +87606,7 @@ index eca6235..c7417ed 100644
  
  /* shm_mode upper byte flags */
 diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
-index bcdd660..6e12e11 100644
+index bcdd660..fd2e332 100644
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
 @@ -14,6 +14,7 @@
@@ -69819,6 +87653,29 @@ index bcdd660..6e12e11 100644
  #endif
  
  extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
+@@ -1489,6 +1490,22 @@ static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev,
+ 	return __netdev_alloc_skb(dev, length, GFP_ATOMIC);
+ }
+ 
++static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
++		unsigned int length, gfp_t gfp)
++{
++	struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp);
++
++	if (NET_IP_ALIGN && skb)
++		skb_reserve(skb, NET_IP_ALIGN);
++	return skb;
++}
++
++static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev,
++		unsigned int length)
++{
++	return __netdev_alloc_skb_ip_align(dev, length, GFP_ATOMIC);
++}
++
+ extern struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask);
+ 
+ /**
 diff --git a/include/linux/slab.h b/include/linux/slab.h
 index 2da8372..a3be824 100644
 --- a/include/linux/slab.h
@@ -71002,6 +88859,23 @@ index de8e180..f15e0d7 100644
  
  	struct device		sdev_gendev,
  				sdev_dev;
+diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
+index 0b4baba..0106e9e 100644
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -43,6 +43,12 @@ struct blk_queue_tags;
+ #define DISABLE_CLUSTERING 0
+ #define ENABLE_CLUSTERING 1
+ 
++enum {
++        SCSI_QDEPTH_DEFAULT,    /* default requested change, e.g. from sysfs */
++        SCSI_QDEPTH_QFULL,      /* scsi-ml requested due to queue full */
++        SCSI_QDEPTH_RAMP_UP,    /* scsi-ml requested due to threshhold event */
++};
++
+ struct scsi_host_template {
+ 	struct module *module;
+ 	const char *name;
 diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
 index fc50bd6..81ba9cb 100644
 --- a/include/scsi/scsi_transport_fc.h
@@ -72479,7 +90353,7 @@ index 0b5b5fc..f7fe51a 100644
  	if (ret < 0)
  		return ret;
 diff --git a/kernel/exit.c b/kernel/exit.c
-index 0f8fae3..7916abf 100644
+index 0f8fae3..66af9b1 100644
 --- a/kernel/exit.c
 +++ b/kernel/exit.c
 @@ -55,6 +55,10 @@
@@ -72589,6 +90463,15 @@ index 0f8fae3..7916abf 100644
  
  	if (tsk->splice_pipe)
  		__free_pipe_info(tsk->splice_pipe);
+@@ -1059,7 +1088,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
+  * Take down every thread in the group.  This is called by fatal signals
+  * as well as by sys_exit_group (below).
+  */
+-NORET_TYPE void
++__noreturn void
+ do_group_exit(int exit_code)
+ {
+ 	struct signal_struct *sig = current->signal;
 @@ -1188,7 +1217,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
  
  	if (unlikely(wo->wo_flags & WNOWAIT)) {
@@ -73405,7 +91288,7 @@ index d4aba4f..02a353f 100644
  
  	if (!name) {
 diff --git a/kernel/module.c b/kernel/module.c
-index 4b270e6..2226274 100644
+index 4b270e6..2efdb65 100644
 --- a/kernel/module.c
 +++ b/kernel/module.c
 @@ -55,6 +55,7 @@
@@ -73736,7 +91619,7 @@ index 4b270e6..2226274 100644
 +	license = get_modinfo(sechdrs, infoindex, "license");
 +#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
 +	if (!license || !license_is_gpl_compatible(license)) {
-+		err -ENOEXEC;
++		err = -ENOEXEC;
 +		goto free_hdr;
 +	}
 +#endif
@@ -82899,6 +100782,19 @@ index 9cc6289..052c521 100644
  }
  
  int udp6_seq_show(struct seq_file *seq, void *v)
+diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
+index 48bb1e3..5980e6e 100644
+--- a/net/ipv6/xfrm6_tunnel.c
++++ b/net/ipv6/xfrm6_tunnel.c
+@@ -258,7 +258,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb)
+ 	__be32 spi;
+ 
+ 	spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
+-	return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0;
++	return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi);
+ }
+ 
+ static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
 index 811984d..11f59b7 100644
 --- a/net/irda/ircomm/ircomm_tty.c
@@ -85334,7 +103230,7 @@ index d52f7a0..269eb1b 100755
  		rm -f tags
  		xtags ctags
 diff --git a/security/Kconfig b/security/Kconfig
-index fb363cd..886ace4 100644
+index fb363cd..90fc8f4 100644
 --- a/security/Kconfig
 +++ b/security/Kconfig
 @@ -4,6 +4,626 @@
@@ -85910,7 +103806,7 @@ index fb363cd..886ace4 100644
 +
 +config PAX_REFCOUNT
 +	bool "Prevent various kernel object reference counter overflows"
-+	depends on GRKERNSEC && (X86 || SPARC64)
++	depends on GRKERNSEC && ((ARM && (CPU_32v6 || CPU_32v6K || CPU_32v7)) || SPARC64 || X86)
 +	help
 +	  By saying Y here the kernel will detect and prevent overflowing
 +	  various (but not all) kinds of object reference counters.  Such
@@ -87245,10 +105141,10 @@ index 79633ea..9732e90 100644
  	}
 diff --git a/tools/gcc/Makefile b/tools/gcc/Makefile
 new file mode 100644
-index 0000000..469b06a
+index 0000000..894c8bf
 --- /dev/null
 +++ b/tools/gcc/Makefile
-@@ -0,0 +1,21 @@
+@@ -0,0 +1,23 @@
 +#CC := gcc
 +#PLUGIN_SOURCE_FILES := pax_plugin.c
 +#PLUGIN_OBJECT_FILES := $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES))
@@ -87262,6 +105158,7 @@ index 0000000..469b06a
 +hostlibs-$(CONFIG_KALLOCSTAT_PLUGIN) += kallocstat_plugin.so
 +hostlibs-$(CONFIG_PAX_KERNEXEC_PLUGIN) += kernexec_plugin.so
 +hostlibs-$(CONFIG_CHECKER_PLUGIN) += checker_plugin.so
++hostlibs-y += colorize_plugin.so
 +
 +always := $(hostlibs-y)
 +
@@ -87270,6 +105167,7 @@ index 0000000..469b06a
 +kallocstat_plugin-objs := kallocstat_plugin.o
 +kernexec_plugin-objs := kernexec_plugin.o
 +checker_plugin-objs := checker_plugin.o
++colorize_plugin-objs := colorize_plugin.o
 diff --git a/tools/gcc/checker_plugin.c b/tools/gcc/checker_plugin.c
 new file mode 100644
 index 0000000..d41b5af
@@ -87447,6 +105345,159 @@ index 0000000..d41b5af
 +
 +	return 0;
 +}
+diff --git a/tools/gcc/colorize_plugin.c b/tools/gcc/colorize_plugin.c
+new file mode 100644
+index 0000000..ee950d0
+--- /dev/null
++++ b/tools/gcc/colorize_plugin.c
+@@ -0,0 +1,147 @@
++/*
++ * Copyright 2012 by PaX Team <pageexec@freemail.hu>
++ * Licensed under the GPL v2
++ *
++ * Note: the choice of the license means that the compilation process is
++ *       NOT 'eligible' as defined by gcc's library exception to the GPL v3,
++ *       but for the kernel it doesn't matter since it doesn't link against
++ *       any of the gcc libraries
++ *
++ * gcc plugin to colorize diagnostic output
++ *
++ */
++
++#include "gcc-plugin.h"
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tree.h"
++#include "tree-pass.h"
++#include "flags.h"
++#include "intl.h"
++#include "toplev.h"
++#include "plugin.h"
++#include "diagnostic.h"
++#include "plugin-version.h"
++#include "tm.h"
++
++int plugin_is_GPL_compatible;
++
++static struct plugin_info colorize_plugin_info = {
++	.version	= "201203092200",
++};
++
++#define GREEN		"\033[32m\033[2m"
++#define LIGHTGREEN	"\033[32m\033[1m"
++#define YELLOW		"\033[33m\033[2m"
++#define LIGHTYELLOW	"\033[33m\033[1m"
++#define RED		"\033[31m\033[2m"
++#define LIGHTRED	"\033[31m\033[1m"
++#define BLUE		"\033[34m\033[2m"
++#define LIGHTBLUE	"\033[34m\033[1m"
++#define BRIGHT		"\033[m\033[1m"
++#define NORMAL		"\033[m"
++
++static diagnostic_starter_fn old_starter;
++static diagnostic_finalizer_fn old_finalizer;
++
++static void start_colorize(diagnostic_context *context, diagnostic_info *diagnostic)
++{
++	const char *color;
++	char *newprefix;
++
++	switch (diagnostic->kind) {
++	case DK_NOTE:
++		color = LIGHTBLUE;
++		break;
++
++	case DK_PEDWARN:
++	case DK_WARNING:
++		color = LIGHTYELLOW;
++		break;
++
++	case DK_ERROR:
++	case DK_FATAL:
++	case DK_ICE:
++	case DK_PERMERROR:
++	case DK_SORRY:
++		color = LIGHTRED;
++		break;
++
++	default:
++		color = NORMAL;
++	}
++
++	old_starter(context, diagnostic);
++	if (-1 == asprintf(&newprefix, "%s%s" NORMAL, color, context->printer->prefix))
++		return;
++	pp_destroy_prefix(context->printer);
++	pp_set_prefix(context->printer, newprefix);
++}
++
++static void finalize_colorize(diagnostic_context *context, diagnostic_info *diagnostic)
++{
++	old_finalizer(context, diagnostic);
++}
++
++static void colorize_arm(void)
++{
++	old_starter = diagnostic_starter(global_dc);
++	old_finalizer = diagnostic_finalizer(global_dc);
++
++	diagnostic_starter(global_dc) = start_colorize;
++	diagnostic_finalizer(global_dc) = finalize_colorize;
++}
++
++static unsigned int execute_colorize_rearm(void)
++{
++	if (diagnostic_starter(global_dc) == start_colorize)
++		return 0;
++
++	colorize_arm();
++	return 0;
++}
++
++struct simple_ipa_opt_pass pass_ipa_colorize_rearm = {
++	.pass = {
++		.type			= SIMPLE_IPA_PASS,
++		.name			= "colorize_rearm",
++		.gate			= NULL,
++		.execute		= execute_colorize_rearm,
++		.sub			= NULL,
++		.next			= NULL,
++		.static_pass_number	= 0,
++		.tv_id			= TV_NONE,
++		.properties_required	= 0,
++		.properties_provided	= 0,
++		.properties_destroyed	= 0,
++		.todo_flags_start	= 0,
++		.todo_flags_finish	= 0
++	}
++};
++
++static void colorize_start_unit(void *gcc_data, void *user_data)
++{
++	colorize_arm();
++}
++
++int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
++{
++	const char * const plugin_name = plugin_info->base_name;
++	struct register_pass_info colorize_rearm_pass_info = {
++		.pass				= &pass_ipa_colorize_rearm.pass,
++		.reference_pass_name		= "*free_lang_data",
++		.ref_pass_instance_number	= 0,
++		.pos_op 			= PASS_POS_INSERT_AFTER
++	};
++
++	if (!plugin_default_version_check(version, &gcc_version)) {
++		error(G_("incompatible gcc/plugin versions"));
++		return 1;
++	}
++
++	register_callback(plugin_name, PLUGIN_INFO, NULL, &colorize_plugin_info);
++	register_callback(plugin_name, PLUGIN_START_UNIT, &colorize_start_unit, NULL);
++	register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &colorize_rearm_pass_info);
++	return 0;
++}
 diff --git a/tools/gcc/constify_plugin.c b/tools/gcc/constify_plugin.c
 new file mode 100644
 index 0000000..704a564
@@ -88364,7 +106415,7 @@ index 0000000..008f159
 +}
 diff --git a/tools/gcc/stackleak_plugin.c b/tools/gcc/stackleak_plugin.c
 new file mode 100644
-index 0000000..4a9b187
+index 0000000..ea79948
 --- /dev/null
 +++ b/tools/gcc/stackleak_plugin.c
 @@ -0,0 +1,326 @@
@@ -88618,7 +106669,7 @@ index 0000000..4a9b187
 +	return 0;
 +}
 +
-+static void stackleak_start_unit(void *gcc_data, void *user_dat)
++static void stackleak_start_unit(void *gcc_data, void *user_data)
 +{
 +	tree fntype;
 +
@@ -88688,7 +106739,7 @@ index 0000000..4a9b187
 +		error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
 +	}
 +
-+	register_callback("start_unit", PLUGIN_START_UNIT, &stackleak_start_unit, NULL);
++	register_callback(plugin_name, PLUGIN_START_UNIT, &stackleak_start_unit, NULL);
 +	register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &stackleak_tree_instrument_pass_info);
 +	register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &stackleak_final_pass_info);
 +

diff --git a/2.6.32/4445_grsec-pax-without-grsec.patch b/2.6.32/4445_grsec-pax-without-grsec.patch
index 591a120..f07b2df 100644
--- a/2.6.32/4445_grsec-pax-without-grsec.patch
+++ b/2.6.32/4445_grsec-pax-without-grsec.patch
@@ -3,6 +3,9 @@ From: Anthony G. Basile <blueness@gentoo.org>
 With grsecurity-2.2.2-2.6.32.38-201104171745, the functions pax_report_leak_to_user and
 pax_report_overflow_from_user in fs/exec.c were consolidated into pax_report_usercopy.
 This patch has been updated to reflect that change.
+
+With grsecurity-2.9-2.6.32.58-201203131839, NORET_TYPE has been replaced by __noreturn.
+This patch has been updated to reflect that change.
 --
 From: Jory Pratt <anarchy@gentoo.org>
 Updated patch for kernel 2.6.32
@@ -36,7 +39,7 @@ diff -Naur a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
 diff -Naur a/fs/exec.c b/fs/exec.c
 --- a/fs/exec.c	2011-04-17 18:15:55.000000000 -0400
 +++ b/fs/exec.c	2011-04-17 18:29:40.000000000 -0400
-@@ -1832,9 +1832,11 @@
+@@ -1849,9 +1849,11 @@
  		}
  		up_read(&mm->mmap_sem);
  	}
@@ -48,7 +51,7 @@ diff -Naur a/fs/exec.c b/fs/exec.c
  		printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
  	printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
  			"PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
-@@ -1849,10 +1851,12 @@
+@@ -1866,10 +1868,12 @@
  #ifdef CONFIG_PAX_REFCOUNT
  void pax_report_refcount_overflow(struct pt_regs *regs)
  {
@@ -61,9 +64,9 @@ diff -Naur a/fs/exec.c b/fs/exec.c
  		printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
  				 current->comm, task_pid_nr(current), current_uid(), current_euid());
  	print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
-@@ -1912,10 +1916,12 @@
+@@ -1928,10 +1932,12 @@
  
- NORET_TYPE void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
+ __noreturn void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
  {
 +#ifdef CONFIG_GRKERNSEC
  	if (current->signal->curr_ip)

diff --git a/2.6.32/4450_grsec-kconfig-default-gids.patch b/2.6.32/4450_grsec-kconfig-default-gids.patch
index 498adb6..8c6f609 100644
--- a/2.6.32/4450_grsec-kconfig-default-gids.patch
+++ b/2.6.32/4450_grsec-kconfig-default-gids.patch
@@ -12,7 +12,7 @@ from shooting themselves in the foot.
 diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
 --- a/grsecurity/Kconfig	2011-12-12 15:11:47.000000000 -0500
 +++ b/grsecurity/Kconfig	2011-12-12 15:13:17.000000000 -0500
-@@ -439,7 +439,7 @@
+@@ -442,7 +442,7 @@
  config GRKERNSEC_PROC_GID
  	int "GID for special group"
  	depends on GRKERNSEC_PROC_USERGROUP
@@ -21,7 +21,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  
  config GRKERNSEC_PROC_ADD
  	bool "Additional restrictions"
-@@ -667,7 +667,7 @@
+@@ -670,7 +670,7 @@
  config GRKERNSEC_AUDIT_GID
  	int "GID for auditing"
  	depends on GRKERNSEC_AUDIT_GROUP
@@ -30,7 +30,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  
  config GRKERNSEC_EXECLOG
  	bool "Exec logging"
-@@ -871,7 +871,7 @@
+@@ -874,7 +874,7 @@
  config GRKERNSEC_TPE_GID
  	int "GID for untrusted users"
  	depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
@@ -39,7 +39,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  	help
  	  Setting this GID determines what group TPE restrictions will be
  	  *enabled* for.  If the sysctl option is enabled, a sysctl option
-@@ -880,7 +880,7 @@
+@@ -883,7 +883,7 @@
  config GRKERNSEC_TPE_GID
  	int "GID for trusted users"
  	depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
@@ -48,7 +48,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  	help
  	  Setting this GID determines what group TPE restrictions will be
  	  *disabled* for.  If the sysctl option is enabled, a sysctl option
-@@ -953,7 +953,7 @@
+@@ -956,7 +956,7 @@
  config GRKERNSEC_SOCKET_ALL_GID
  	int "GID to deny all sockets for"
  	depends on GRKERNSEC_SOCKET_ALL
@@ -57,7 +57,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  	help
  	  Here you can choose the GID to disable socket access for. Remember to
  	  add the users you want socket access disabled for to the GID
-@@ -974,7 +974,7 @@
+@@ -977,7 +977,7 @@
  config GRKERNSEC_SOCKET_CLIENT_GID
  	int "GID to deny client sockets for"
  	depends on GRKERNSEC_SOCKET_CLIENT
@@ -66,7 +66,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  	help
  	  Here you can choose the GID to disable client socket access for.
  	  Remember to add the users you want client socket access disabled for to
-@@ -992,7 +992,7 @@
+@@ -995,7 +995,7 @@
  config GRKERNSEC_SOCKET_SERVER_GID
  	int "GID to deny server sockets for"
  	depends on GRKERNSEC_SOCKET_SERVER

diff --git a/2.6.32/4460-grsec-kconfig-proc-user.patch b/2.6.32/4460-grsec-kconfig-proc-user.patch
index 1e181f3..b94ee69 100644
--- a/2.6.32/4460-grsec-kconfig-proc-user.patch
+++ b/2.6.32/4460-grsec-kconfig-proc-user.patch
@@ -6,7 +6,7 @@ in a different way to avoid bug #366019.  This patch should eventually go upstre
 diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
 --- a/grsecurity/Kconfig	2011-06-29 07:46:02.000000000 -0400
 +++ b/grsecurity/Kconfig	2011-06-29 07:47:20.000000000 -0400
-@@ -673,7 +673,7 @@
+@@ -676,7 +676,7 @@
  
  config GRKERNSEC_PROC_USER
  	bool "Restrict /proc to user only"
@@ -15,7 +15,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  	help
  	  If you say Y here, non-root users will only be able to view their own
  	  processes, and restricts them from viewing network-related information,
-@@ -681,7 +681,7 @@
+@@ -684,7 +684,7 @@
  
  config GRKERNSEC_PROC_USERGROUP
  	bool "Allow special group"

diff --git a/2.6.32/4465_selinux-avc_audit-log-curr_ip.patch b/2.6.32/4465_selinux-avc_audit-log-curr_ip.patch
index fe2f190..11d9263 100644
--- a/2.6.32/4465_selinux-avc_audit-log-curr_ip.patch
+++ b/2.6.32/4465_selinux-avc_audit-log-curr_ip.patch
@@ -28,7 +28,7 @@ Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@gnu.org>
 diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
 --- a/grsecurity/Kconfig	2011-04-17 18:47:02.000000000 -0400
 +++ b/grsecurity/Kconfig	2011-04-17 18:51:15.000000000 -0400
-@@ -1302,6 +1302,27 @@
+@@ -1305,6 +1305,27 @@
  menu "Logging Options"
  depends on GRKERNSEC
  

diff --git a/3.2.9/0000_README b/3.2.11/0000_README
similarity index 97%
rename from 3.2.9/0000_README
rename to 3.2.11/0000_README
index c6fa1e9..b641520 100644
--- a/3.2.9/0000_README
+++ b/3.2.11/0000_README
@@ -2,7 +2,7 @@ README
 -----------------------------------------------------------------------------
 Individual Patch Descriptions:
 -----------------------------------------------------------------------------
-Patch:	4420_grsecurity-2.9-3.2.9-201203062051.patch
+Patch:	4420_grsecurity-2.9-3.2.11-201203141956.patch
 From:	http://www.grsecurity.net
 Desc:	hardened-sources base patch from upstream grsecurity
 

diff --git a/3.2.9/4420_grsecurity-2.9-3.2.9-201203062051.patch b/3.2.11/4420_grsecurity-2.9-3.2.11-201203141956.patch
similarity index 97%
rename from 3.2.9/4420_grsecurity-2.9-3.2.9-201203062051.patch
rename to 3.2.11/4420_grsecurity-2.9-3.2.11-201203141956.patch
index 7a64df3..ba37ae4 100644
--- a/3.2.9/4420_grsecurity-2.9-3.2.9-201203062051.patch
+++ b/3.2.11/4420_grsecurity-2.9-3.2.11-201203141956.patch
@@ -1,5 +1,5 @@
 diff --git a/Documentation/dontdiff b/Documentation/dontdiff
-index dfa6fc6..0095943 100644
+index dfa6fc6..6af9546 100644
 --- a/Documentation/dontdiff
 +++ b/Documentation/dontdiff
 @@ -5,6 +5,7 @@
@@ -63,7 +63,11 @@ index dfa6fc6..0095943 100644
  conmakehash
  consolemap_deftbl.c*
  cpustr.h
-@@ -119,6 +129,7 @@ dslm
+@@ -116,9 +126,11 @@ devlist.h*
+ dnotify_test
+ docproc
+ dslm
++dtc-lexer.lex.c
  elf2ecoff
  elfconfig.h*
  evergreen_reg_safe.h
@@ -71,7 +75,7 @@ index dfa6fc6..0095943 100644
  fixdep
  flask.h
  fore200e_mkfirm
-@@ -126,12 +137,15 @@ fore200e_pca_fw.c*
+@@ -126,12 +138,15 @@ fore200e_pca_fw.c*
  gconf
  gconf.glade.h
  gen-devlist
@@ -87,7 +91,7 @@ index dfa6fc6..0095943 100644
  hpet_example
  hugepage-mmap
  hugepage-shm
-@@ -146,7 +160,7 @@ int32.c
+@@ -146,7 +161,7 @@ int32.c
  int4.c
  int8.c
  kallsyms
@@ -96,15 +100,16 @@ index dfa6fc6..0095943 100644
  keywords.c
  ksym.c*
  ksym.h*
-@@ -154,7 +168,6 @@ kxgettext
+@@ -154,7 +169,7 @@ kxgettext
  lkc_defs.h
  lex.c
  lex.*.c
 -linux
++lib1funcs.S
  logo_*.c
  logo_*_clut224.c
  logo_*_mono.c
-@@ -166,14 +179,15 @@ machtypes.h
+@@ -166,14 +181,15 @@ machtypes.h
  map
  map_hugetlb
  maui_boot.h
@@ -121,7 +126,7 @@ index dfa6fc6..0095943 100644
  mkprep
  mkregtable
  mktables
-@@ -209,6 +223,7 @@ r300_reg_safe.h
+@@ -209,6 +225,7 @@ r300_reg_safe.h
  r420_reg_safe.h
  r600_reg_safe.h
  recordmcount
@@ -129,7 +134,7 @@ index dfa6fc6..0095943 100644
  relocs
  rlim_names.h
  rn50_reg_safe.h
-@@ -219,6 +234,7 @@ setup
+@@ -219,6 +236,7 @@ setup
  setup.bin
  setup.elf
  sImage
@@ -137,7 +142,7 @@ index dfa6fc6..0095943 100644
  sm_tbl*
  split-include
  syscalltab.h
-@@ -229,6 +245,7 @@ tftpboot.img
+@@ -229,6 +247,7 @@ tftpboot.img
  timeconst.h
  times.h*
  trix_boot.h
@@ -145,7 +150,7 @@ index dfa6fc6..0095943 100644
  utsrelease.h*
  vdso-syms.lds
  vdso.lds
-@@ -246,7 +263,9 @@ vmlinux
+@@ -246,7 +265,9 @@ vmlinux
  vmlinux-*
  vmlinux.aout
  vmlinux.bin.all
@@ -155,7 +160,7 @@ index dfa6fc6..0095943 100644
  vmlinuz
  voffset.h
  vsyscall.lds
-@@ -254,9 +273,11 @@ vsyscall_32.lds
+@@ -254,9 +275,11 @@ vsyscall_32.lds
  wanxlfw.inc
  uImage
  unifdef
@@ -186,7 +191,7 @@ index 81c287f..d456d02 100644
  
  	pcd.		[PARIDE]
 diff --git a/Makefile b/Makefile
-index 5f1739b..1831396 100644
+index 4b76371..53aa79c 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -245,8 +245,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -212,7 +217,7 @@ index 5f1739b..1831396 100644
  	$(Q)$(MAKE) $(build)=scripts/basic
  	$(Q)rm -f .tmp_quiet_recordmcount
  
-@@ -564,6 +565,48 @@ else
+@@ -564,6 +565,50 @@ else
  KBUILD_CFLAGS	+= -O2
  endif
  
@@ -238,7 +243,9 @@ index 5f1739b..1831396 100644
 +CHECKER_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/checker_plugin.so -DCHECKER_PLUGIN
 +endif
 +endif
-+GCC_PLUGINS_CFLAGS := $(CONSTIFY_PLUGIN_CFLAGS) $(STACKLEAK_PLUGIN_CFLAGS) $(KALLOCSTAT_PLUGIN_CFLAGS) $(KERNEXEC_PLUGIN_CFLAGS) $(CHECKER_PLUGIN_CFLAGS)
++COLORIZE_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/colorize_plugin.so
++GCC_PLUGINS_CFLAGS := $(CONSTIFY_PLUGIN_CFLAGS) $(STACKLEAK_PLUGIN_CFLAGS) $(KALLOCSTAT_PLUGIN_CFLAGS)
++GCC_PLUGINS_CFLAGS += $(KERNEXEC_PLUGIN_CFLAGS) $(CHECKER_PLUGIN_CFLAGS) $(COLORIZE_PLUGIN_CFLAGS)
 +GCC_PLUGINS_AFLAGS := $(KERNEXEC_PLUGIN_AFLAGS)
 +export CONSTIFY_PLUGIN STACKLEAK_PLUGIN KERNEXEC_PLUGIN CHECKER_PLUGIN
 +ifeq ($(KBUILD_EXTMOD),)
@@ -261,7 +268,7 @@ index 5f1739b..1831396 100644
  include $(srctree)/arch/$(SRCARCH)/Makefile
  
  ifneq ($(CONFIG_FRAME_WARN),0)
-@@ -708,7 +751,7 @@ export mod_strip_cmd
+@@ -708,7 +753,7 @@ export mod_strip_cmd
  
  
  ifeq ($(KBUILD_EXTMOD),)
@@ -270,7 +277,7 @@ index 5f1739b..1831396 100644
  
  vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
  		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
-@@ -932,6 +975,8 @@ vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
+@@ -932,6 +977,8 @@ vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
  
  # The actual objects are generated when descending, 
  # make sure no implicit rule kicks in
@@ -279,7 +286,7 @@ index 5f1739b..1831396 100644
  $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
  
  # Handle descending into subdirectories listed in $(vmlinux-dirs)
-@@ -941,7 +986,7 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
+@@ -941,7 +988,7 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
  # Error messages still appears in the original language
  
  PHONY += $(vmlinux-dirs)
@@ -288,7 +295,7 @@ index 5f1739b..1831396 100644
  	$(Q)$(MAKE) $(build)=$@
  
  # Store (new) KERNELRELASE string in include/config/kernel.release
-@@ -985,6 +1030,7 @@ prepare0: archprepare FORCE
+@@ -985,6 +1032,7 @@ prepare0: archprepare FORCE
  	$(Q)$(MAKE) $(build)=.
  
  # All the preparing..
@@ -296,7 +303,7 @@ index 5f1739b..1831396 100644
  prepare: prepare0
  
  # Generate some files
-@@ -1086,6 +1132,8 @@ all: modules
+@@ -1086,6 +1134,8 @@ all: modules
  #	using awk while concatenating to the final file.
  
  PHONY += modules
@@ -305,7 +312,7 @@ index 5f1739b..1831396 100644
  modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
  	$(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
  	@$(kecho) '  Building modules, stage 2.';
-@@ -1101,7 +1149,7 @@ modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
+@@ -1101,7 +1151,7 @@ modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
  
  # Target to prepare building external modules
  PHONY += modules_prepare
@@ -314,7 +321,7 @@ index 5f1739b..1831396 100644
  
  # Target to install modules
  PHONY += modules_install
-@@ -1198,6 +1246,7 @@ distclean: mrproper
+@@ -1198,6 +1248,7 @@ distclean: mrproper
  		\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
  		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
  		-o -name '.*.rej' \
@@ -322,7 +329,7 @@ index 5f1739b..1831396 100644
  		-o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
  		-type f -print | xargs rm -f
  
-@@ -1358,6 +1407,8 @@ PHONY += $(module-dirs) modules
+@@ -1358,6 +1409,8 @@ PHONY += $(module-dirs) modules
  $(module-dirs): crmodverdir $(objtree)/Module.symvers
  	$(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)
  
@@ -331,7 +338,7 @@ index 5f1739b..1831396 100644
  modules: $(module-dirs)
  	@$(kecho) '  Building modules, stage 2.';
  	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
-@@ -1484,17 +1535,21 @@ else
+@@ -1484,17 +1537,21 @@ else
          target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@))
  endif
  
@@ -357,7 +364,7 @@ index 5f1739b..1831396 100644
  	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
  %.symtypes: %.c prepare scripts FORCE
  	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
-@@ -1504,11 +1559,15 @@ endif
+@@ -1504,11 +1561,15 @@ endif
  	$(cmd_crmodverdir)
  	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
  	$(build)=$(build-dir)
@@ -396,6 +403,32 @@ index 640f909..48b6597 100644
  #define smp_mb__before_atomic_dec()	smp_mb()
  #define smp_mb__after_atomic_dec()	smp_mb()
  #define smp_mb__before_atomic_inc()	smp_mb()
+diff --git a/arch/alpha/include/asm/cache.h b/arch/alpha/include/asm/cache.h
+index ad368a9..fbe0f25 100644
+--- a/arch/alpha/include/asm/cache.h
++++ b/arch/alpha/include/asm/cache.h
+@@ -4,19 +4,19 @@
+ #ifndef __ARCH_ALPHA_CACHE_H
+ #define __ARCH_ALPHA_CACHE_H
+ 
++#include <linux/const.h>
+ 
+ /* Bytes per L1 (data) cache line. */
+ #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6)
+-# define L1_CACHE_BYTES     64
+ # define L1_CACHE_SHIFT     6
+ #else
+ /* Both EV4 and EV5 are write-through, read-allocate,
+    direct-mapped, physical.
+ */
+-# define L1_CACHE_BYTES     32
+ # define L1_CACHE_SHIFT     5
+ #endif
+ 
++#define L1_CACHE_BYTES     (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define SMP_CACHE_BYTES    L1_CACHE_BYTES
+ 
+ #endif
 diff --git a/arch/alpha/include/asm/elf.h b/arch/alpha/include/asm/elf.h
 index da5449e..7418343 100644
 --- a/arch/alpha/include/asm/elf.h
@@ -645,7 +678,7 @@ index fadd5f8..904e73a 100644
  		/* Allow reads even for write-only mappings */
  		if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
 diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
-index 86976d0..6610950 100644
+index 86976d0..683de93 100644
 --- a/arch/arm/include/asm/atomic.h
 +++ b/arch/arm/include/asm/atomic.h
 @@ -15,6 +15,10 @@
@@ -659,7 +692,234 @@ index 86976d0..6610950 100644
  #define ATOMIC_INIT(i)	{ (i) }
  
  #ifdef __KERNEL__
-@@ -239,6 +243,14 @@ typedef struct {
+@@ -25,7 +29,15 @@
+  * atomic_set() is the clrex or dummy strex done on every exception return.
+  */
+ #define atomic_read(v)	(*(volatile int *)&(v)->counter)
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++	return v->counter;
++}
+ #define atomic_set(v,i)	(((v)->counter) = (i))
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++	v->counter = i;
++}
+ 
+ #if __LINUX_ARM_ARCH__ >= 6
+ 
+@@ -40,6 +52,35 @@ static inline void atomic_add(int i, atomic_t *v)
+ 	int result;
+ 
+ 	__asm__ __volatile__("@ atomic_add\n"
++"1:	ldrex	%1, [%3]\n"
++"	adds	%0, %1, %4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strex	%1, %0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "Ir" (i)
++	: "cc");
++}
++
++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
++{
++	unsigned long tmp;
++	int result;
++
++	__asm__ __volatile__("@ atomic_add_unchecked\n"
+ "1:	ldrex	%0, [%3]\n"
+ "	add	%0, %0, %4\n"
+ "	strex	%1, %0, [%3]\n"
+@@ -58,6 +99,42 @@ static inline int atomic_add_return(int i, atomic_t *v)
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic_add_return\n"
++"1:	ldrex	%1, [%3]\n"
++"	adds	%0, %1, %4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"2:	bkpt 0xf103\n"
++"3:\n"
++#endif
++
++"	strex	%1, %0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "Ir" (i)
++	: "cc");
++
++	smp_mb();
++
++	return result;
++}
++
++static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
++{
++	unsigned long tmp;
++	int result;
++
++	smp_mb();
++
++	__asm__ __volatile__("@ atomic_add_return_unchecked\n"
+ "1:	ldrex	%0, [%3]\n"
+ "	add	%0, %0, %4\n"
+ "	strex	%1, %0, [%3]\n"
+@@ -78,6 +155,35 @@ static inline void atomic_sub(int i, atomic_t *v)
+ 	int result;
+ 
+ 	__asm__ __volatile__("@ atomic_sub\n"
++"1:	ldrex	%1, [%3]\n"
++"	subs	%0, %1, %4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strex	%1, %0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "Ir" (i)
++	: "cc");
++}
++
++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
++{
++	unsigned long tmp;
++	int result;
++
++	__asm__ __volatile__("@ atomic_sub_unchecked\n"
+ "1:	ldrex	%0, [%3]\n"
+ "	sub	%0, %0, %4\n"
+ "	strex	%1, %0, [%3]\n"
+@@ -96,11 +202,25 @@ static inline int atomic_sub_return(int i, atomic_t *v)
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic_sub_return\n"
+-"1:	ldrex	%0, [%3]\n"
+-"	sub	%0, %0, %4\n"
++"1:	ldrex	%1, [%3]\n"
++"	sub	%0, %1, %4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
+ "	strex	%1, %0, [%3]\n"
+ "	teq	%1, #0\n"
+ "	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
+ 	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ 	: "r" (&v->counter), "Ir" (i)
+ 	: "cc");
+@@ -132,6 +252,28 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
+ 	return oldval;
+ }
+ 
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *ptr, int old, int new)
++{
++	unsigned long oldval, res;
++
++	smp_mb();
++
++	do {
++		__asm__ __volatile__("@ atomic_cmpxchg_unchecked\n"
++		"ldrex	%1, [%3]\n"
++		"mov	%0, #0\n"
++		"teq	%1, %4\n"
++		"strexeq %0, %5, [%3]\n"
++		    : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
++		    : "r" (&ptr->counter), "Ir" (old), "r" (new)
++		    : "cc");
++	} while (res);
++
++	smp_mb();
++
++	return oldval;
++}
++
+ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+ {
+ 	unsigned long tmp, tmp2;
+@@ -207,6 +349,10 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+ #endif /* __LINUX_ARM_ARCH__ */
+ 
+ #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
++static inline int atomic_xchg_unchecked(atomic_unchecked_t *v, int new)
++{
++	return xchg(&v->counter, new);
++}
+ 
+ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+ {
+@@ -219,11 +365,27 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+ }
+ 
+ #define atomic_inc(v)		atomic_add(1, v)
++static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
++{
++	atomic_add_unchecked(1, v);
++}
+ #define atomic_dec(v)		atomic_sub(1, v)
++static inline void atomic_dec_unchecked(atomic_unchecked_t *v)
++{
++	atomic_sub_unchecked(1, v);
++}
+ 
+ #define atomic_inc_and_test(v)	(atomic_add_return(1, v) == 0)
++static inline int atomic_inc_and_test_unchecked(atomic_unchecked_t *v)
++{
++	return atomic_add_return_unchecked(1, v) == 0;
++}
+ #define atomic_dec_and_test(v)	(atomic_sub_return(1, v) == 0)
+ #define atomic_inc_return(v)    (atomic_add_return(1, v))
++static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
++{
++	return atomic_add_return_unchecked(1, v);
++}
+ #define atomic_dec_return(v)    (atomic_sub_return(1, v))
+ #define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+ 
+@@ -239,6 +401,14 @@ typedef struct {
  	u64 __aligned(8) counter;
  } atomic64_t;
  
@@ -674,23 +934,355 @@ index 86976d0..6610950 100644
  #define ATOMIC64_INIT(i) { (i) }
  
  static inline u64 atomic64_read(atomic64_t *v)
-@@ -459,6 +471,16 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+@@ -254,6 +424,19 @@ static inline u64 atomic64_read(atomic64_t *v)
+ 	return result;
+ }
+ 
++static inline u64 atomic64_read_unchecked(atomic64_unchecked_t *v)
++{
++	u64 result;
++
++	__asm__ __volatile__("@ atomic64_read_unchecked\n"
++"	ldrexd	%0, %H0, [%1]"
++	: "=&r" (result)
++	: "r" (&v->counter), "Qo" (v->counter)
++	);
++
++	return result;
++}
++
+ static inline void atomic64_set(atomic64_t *v, u64 i)
+ {
+ 	u64 tmp;
+@@ -268,6 +451,20 @@ static inline void atomic64_set(atomic64_t *v, u64 i)
+ 	: "cc");
+ }
+ 
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, u64 i)
++{
++	u64 tmp;
++
++	__asm__ __volatile__("@ atomic64_set_unchecked\n"
++"1:	ldrexd	%0, %H0, [%2]\n"
++"	strexd	%0, %3, %H3, [%2]\n"
++"	teq	%0, #0\n"
++"	bne	1b"
++	: "=&r" (tmp), "=Qo" (v->counter)
++	: "r" (&v->counter), "r" (i)
++	: "cc");
++}
++
+ static inline void atomic64_add(u64 i, atomic64_t *v)
+ {
+ 	u64 result;
+@@ -276,6 +473,36 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
+ 	__asm__ __volatile__("@ atomic64_add\n"
+ "1:	ldrexd	%0, %H0, [%3]\n"
+ "	adds	%0, %0, %4\n"
++"	adcs	%H0, %H0, %H4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strexd	%1, %0, %H0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "r" (i)
++	: "cc");
++}
++
++static inline void atomic64_add_unchecked(u64 i, atomic64_unchecked_t *v)
++{
++	u64 result;
++	unsigned long tmp;
++
++	__asm__ __volatile__("@ atomic64_add_unchecked\n"
++"1:	ldrexd	%0, %H0, [%3]\n"
++"	adds	%0, %0, %4\n"
+ "	adc	%H0, %H0, %H4\n"
+ "	strexd	%1, %0, %H0, [%3]\n"
+ "	teq	%1, #0\n"
+@@ -287,12 +514,49 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
+ 
+ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
+ {
+-	u64 result;
+-	unsigned long tmp;
++	u64 result, tmp;
+ 
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic64_add_return\n"
++"1:	ldrexd	%1, %H1, [%3]\n"
++"	adds	%0, %1, %4\n"
++"	adcs	%H0, %H1, %H4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"	mov	%H0, %H1\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strexd	%1, %0, %H0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "r" (i)
++	: "cc");
++
++	smp_mb();
++
++	return result;
++}
++
++static inline u64 atomic64_add_return_unchecked(u64 i, atomic64_unchecked_t *v)
++{
++	u64 result;
++	unsigned long tmp;
++
++	smp_mb();
++
++	__asm__ __volatile__("@ atomic64_add_return_unchecked\n"
+ "1:	ldrexd	%0, %H0, [%3]\n"
+ "	adds	%0, %0, %4\n"
+ "	adc	%H0, %H0, %H4\n"
+@@ -316,6 +580,36 @@ static inline void atomic64_sub(u64 i, atomic64_t *v)
+ 	__asm__ __volatile__("@ atomic64_sub\n"
+ "1:	ldrexd	%0, %H0, [%3]\n"
+ "	subs	%0, %0, %4\n"
++"	sbcs	%H0, %H0, %H4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strexd	%1, %0, %H0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "r" (i)
++	: "cc");
++}
++
++static inline void atomic64_sub_unchecked(u64 i, atomic64_unchecked_t *v)
++{
++	u64 result;
++	unsigned long tmp;
++
++	__asm__ __volatile__("@ atomic64_sub_unchecked\n"
++"1:	ldrexd	%0, %H0, [%3]\n"
++"	subs	%0, %0, %4\n"
+ "	sbc	%H0, %H0, %H4\n"
+ "	strexd	%1, %0, %H0, [%3]\n"
+ "	teq	%1, #0\n"
+@@ -327,18 +621,32 @@ static inline void atomic64_sub(u64 i, atomic64_t *v)
+ 
+ static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
+ {
+-	u64 result;
+-	unsigned long tmp;
++	u64 result, tmp;
+ 
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic64_sub_return\n"
+-"1:	ldrexd	%0, %H0, [%3]\n"
+-"	subs	%0, %0, %4\n"
+-"	sbc	%H0, %H0, %H4\n"
++"1:	ldrexd	%1, %H1, [%3]\n"
++"	subs	%0, %1, %4\n"
++"	sbc	%H0, %H1, %H4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"	mov	%H0, %H1\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
+ "	strexd	%1, %0, %H0, [%3]\n"
+ "	teq	%1, #0\n"
+ "	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
+ 	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ 	: "r" (&v->counter), "r" (i)
+ 	: "cc");
+@@ -372,6 +680,30 @@ static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
+ 	return oldval;
+ }
+ 
++static inline u64 atomic64_cmpxchg_unchecked(atomic64_unchecked_t *ptr, u64 old, u64 new)
++{
++	u64 oldval;
++	unsigned long res;
++
++	smp_mb();
++
++	do {
++		__asm__ __volatile__("@ atomic64_cmpxchg_unchecked\n"
++		"ldrexd		%1, %H1, [%3]\n"
++		"mov		%0, #0\n"
++		"teq		%1, %4\n"
++		"teqeq		%H1, %H4\n"
++		"strexdeq	%0, %5, %H5, [%3]"
++		: "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
++		: "r" (&ptr->counter), "r" (old), "r" (new)
++		: "cc");
++	} while (res);
++
++	smp_mb();
++
++	return oldval;
++}
++
+ static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
+ {
+ 	u64 result;
+@@ -395,21 +727,34 @@ static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
+ 
+ static inline u64 atomic64_dec_if_positive(atomic64_t *v)
+ {
+-	u64 result;
+-	unsigned long tmp;
++	u64 result, tmp;
+ 
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic64_dec_if_positive\n"
+-"1:	ldrexd	%0, %H0, [%3]\n"
+-"	subs	%0, %0, #1\n"
+-"	sbc	%H0, %H0, #0\n"
++"1:	ldrexd	%1, %H1, [%3]\n"
++"	subs	%0, %1, #1\n"
++"	sbc	%H0, %H1, #0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"	mov	%H0, %H1\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
+ "	teq	%H0, #0\n"
+-"	bmi	2f\n"
++"	bmi	4f\n"
+ "	strexd	%1, %0, %H0, [%3]\n"
+ "	teq	%1, #0\n"
+ "	bne	1b\n"
+-"2:"
++"4:\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
+ 	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ 	: "r" (&v->counter)
+ 	: "cc");
+@@ -432,13 +777,25 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+ "	teq	%0, %5\n"
+ "	teqeq	%H0, %H5\n"
+ "	moveq	%1, #0\n"
+-"	beq	2f\n"
++"	beq	4f\n"
+ "	adds	%0, %0, %6\n"
+ "	adc	%H0, %H0, %H6\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
+ "	strexd	%2, %0, %H0, [%4]\n"
+ "	teq	%2, #0\n"
+ "	bne	1b\n"
+-"2:"
++"4:\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
+ 	: "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter)
+ 	: "r" (&v->counter), "r" (u), "r" (a)
+ 	: "cc");
+@@ -451,10 +808,13 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+ 
+ #define atomic64_add_negative(a, v)	(atomic64_add_return((a), (v)) < 0)
+ #define atomic64_inc(v)			atomic64_add(1LL, (v))
++#define atomic64_inc_unchecked(v)	atomic64_add_unchecked(1LL, (v))
+ #define atomic64_inc_return(v)		atomic64_add_return(1LL, (v))
++#define atomic64_inc_return_unchecked(v)	atomic64_add_return_unchecked(1LL, (v))
+ #define atomic64_inc_and_test(v)	(atomic64_inc_return(v) == 0)
+ #define atomic64_sub_and_test(a, v)	(atomic64_sub_return((a), (v)) == 0)
+ #define atomic64_dec(v)			atomic64_sub(1LL, (v))
++#define atomic64_dec_unchecked(v)	atomic64_sub_unchecked(1LL, (v))
+ #define atomic64_dec_return(v)		atomic64_sub_return(1LL, (v))
  #define atomic64_dec_and_test(v)	(atomic64_dec_return((v)) == 0)
  #define atomic64_inc_not_zero(v)	atomic64_add_unless((v), 1LL, 0LL)
+diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
+index 75fe66b..2255c86 100644
+--- a/arch/arm/include/asm/cache.h
++++ b/arch/arm/include/asm/cache.h
+@@ -4,8 +4,10 @@
+ #ifndef __ASMARM_CACHE_H
+ #define __ASMARM_CACHE_H
  
-+#define atomic64_read_unchecked(v)		atomic64_read(v)
-+#define atomic64_set_unchecked(v, i)		atomic64_set((v), (i))
-+#define atomic64_add_unchecked(a, v)		atomic64_add((a), (v))
-+#define atomic64_add_return_unchecked(a, v)	atomic64_add_return((a), (v))
-+#define atomic64_sub_unchecked(a, v)		atomic64_sub((a), (v))
-+#define atomic64_inc_unchecked(v)		atomic64_inc(v)
-+#define atomic64_inc_return_unchecked(v)	atomic64_inc_return(v)
-+#define atomic64_dec_unchecked(v)		atomic64_dec(v)
-+#define atomic64_cmpxchg_unchecked(v, o, n)	atomic64_cmpxchg((v), (o), (n))
++#include <linux/const.h>
 +
- #endif /* !CONFIG_GENERIC_ATOMIC64 */
- #endif
- #endif
+ #define L1_CACHE_SHIFT		CONFIG_ARM_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ /*
+  * Memory returned by kmalloc() may be used for DMA, so we must make
+diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
+index d5d8d5c..ad92c96 100644
+--- a/arch/arm/include/asm/cacheflush.h
++++ b/arch/arm/include/asm/cacheflush.h
+@@ -108,7 +108,7 @@ struct cpu_cache_fns {
+ 	void (*dma_unmap_area)(const void *, size_t, int);
+ 
+ 	void (*dma_flush_range)(const void *, const void *);
+-};
++} __no_const;
+ 
+ /*
+  * Select the calling method
 diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
 index 0e9ce8d..6ef1e03 100644
 --- a/arch/arm/include/asm/elf.h
@@ -734,6 +1326,68 @@ index e51b1e8..32a3113 100644
  	KM_TYPE_NR
  };
  
+diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
+index 53426c6..c7baff3 100644
+--- a/arch/arm/include/asm/outercache.h
++++ b/arch/arm/include/asm/outercache.h
+@@ -35,7 +35,7 @@ struct outer_cache_fns {
+ #endif
+ 	void (*set_debug)(unsigned long);
+ 	void (*resume)(void);
+-};
++} __no_const;
+ 
+ #ifdef CONFIG_OUTER_CACHE
+ 
+diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
+index ca94653..6ac0d56 100644
+--- a/arch/arm/include/asm/page.h
++++ b/arch/arm/include/asm/page.h
+@@ -123,7 +123,7 @@ struct cpu_user_fns {
+ 	void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr);
+ 	void (*cpu_copy_user_highpage)(struct page *to, struct page *from,
+ 			unsigned long vaddr, struct vm_area_struct *vma);
+-};
++} __no_const;
+ 
+ #ifdef MULTI_USER
+ extern struct cpu_user_fns cpu_user;
+diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
+index 984014b..a6d914f 100644
+--- a/arch/arm/include/asm/system.h
++++ b/arch/arm/include/asm/system.h
+@@ -90,6 +90,8 @@ void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
+ 
+ #define xchg(ptr,x) \
+ 	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
++#define xchg_unchecked(ptr,x) \
++	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+ 
+ extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
+ 
+@@ -101,7 +103,7 @@ extern int __pure cpu_architecture(void);
+ extern void cpu_init(void);
+ 
+ void arm_machine_restart(char mode, const char *cmd);
+-extern void (*arm_pm_restart)(char str, const char *cmd);
++extern void (*arm_pm_restart)(char str, const char *cmd) __noreturn;
+ 
+ #define UDBG_UNDEFINED	(1 << 0)
+ #define UDBG_SYSCALL	(1 << 1)
+@@ -526,6 +528,13 @@ static inline unsigned long long __cmpxchg64_mb(volatile void *ptr,
+ 
+ #endif	/* __LINUX_ARM_ARCH__ >= 6 */
+ 
++#define _ASM_EXTABLE(from, to)		\
++"	.pushsection __ex_table,\"a\"\n"\
++"	.align	3\n"			\
++"	.long	" #from ", " #to"\n"	\
++"	.popsection"
++
++
+ #endif /* __ASSEMBLY__ */
+ 
+ #define arch_align_stack(x) (x)
 diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
 index b293616..96310e5 100644
 --- a/arch/arm/include/asm/uaccess.h
@@ -809,7 +1463,7 @@ index 5b0bce6..becd81c 100644
  
  EXPORT_SYMBOL(__get_user_1);
 diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
-index 3d0c6fb..3dcae52 100644
+index 3d0c6fb..9d326fa 100644
 --- a/arch/arm/kernel/process.c
 +++ b/arch/arm/kernel/process.c
 @@ -28,7 +28,6 @@
@@ -820,7 +1474,33 @@ index 3d0c6fb..3dcae52 100644
  #include <linux/hw_breakpoint.h>
  #include <linux/cpuidle.h>
  
-@@ -484,12 +483,6 @@ unsigned long get_wchan(struct task_struct *p)
+@@ -92,7 +91,7 @@ static int __init hlt_setup(char *__unused)
+ __setup("nohlt", nohlt_setup);
+ __setup("hlt", hlt_setup);
+ 
+-void arm_machine_restart(char mode, const char *cmd)
++__noreturn void arm_machine_restart(char mode, const char *cmd)
+ {
+ 	/* Disable interrupts first */
+ 	local_irq_disable();
+@@ -134,7 +133,7 @@ void arm_machine_restart(char mode, const char *cmd)
+ void (*pm_power_off)(void);
+ EXPORT_SYMBOL(pm_power_off);
+ 
+-void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
++void (*arm_pm_restart)(char str, const char *cmd) __noreturn = arm_machine_restart;
+ EXPORT_SYMBOL_GPL(arm_pm_restart);
+ 
+ static void do_nothing(void *unused)
+@@ -248,6 +247,7 @@ void machine_power_off(void)
+ 	machine_shutdown();
+ 	if (pm_power_off)
+ 		pm_power_off();
++	BUG();
+ }
+ 
+ void machine_restart(char *cmd)
+@@ -484,12 +484,6 @@ unsigned long get_wchan(struct task_struct *p)
  	return 0;
  }
  
@@ -833,6 +1513,27 @@ index 3d0c6fb..3dcae52 100644
  #ifdef CONFIG_MMU
  /*
   * The vectors page is always readable from user space for the
+diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
+index 8fc2c8f..064c150 100644
+--- a/arch/arm/kernel/setup.c
++++ b/arch/arm/kernel/setup.c
+@@ -108,13 +108,13 @@ struct processor processor __read_mostly;
+ struct cpu_tlb_fns cpu_tlb __read_mostly;
+ #endif
+ #ifdef MULTI_USER
+-struct cpu_user_fns cpu_user __read_mostly;
++struct cpu_user_fns cpu_user __read_only;
+ #endif
+ #ifdef MULTI_CACHE
+-struct cpu_cache_fns cpu_cache __read_mostly;
++struct cpu_cache_fns cpu_cache __read_only;
+ #endif
+ #ifdef CONFIG_OUTER_CACHE
+-struct outer_cache_fns outer_cache __read_mostly;
++struct outer_cache_fns outer_cache __read_only;
+ EXPORT_SYMBOL(outer_cache);
+ #endif
+ 
 diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
 index 99a5727..a3d5bb1 100644
 --- a/arch/arm/kernel/traps.c
@@ -883,6 +1584,18 @@ index 66a477a..bee61d3 100644
  
  	.pushsection .fixup,"ax"
  	.align 0
+diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
+index 6ee2f67..d1cce76 100644
+--- a/arch/arm/lib/copy_page.S
++++ b/arch/arm/lib/copy_page.S
+@@ -10,6 +10,7 @@
+  *  ASM optimised string functions
+  */
+ #include <linux/linkage.h>
++#include <linux/const.h>
+ #include <asm/assembler.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/cache.h>
 diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
 index d066df6..df28194 100644
 --- a/arch/arm/lib/copy_to_user.S
@@ -980,6 +1693,19 @@ index 025f742..8432b08 100644
  {
  	/*
  	 * This test is stubbed out of the main function above to keep
+diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
+index e9d5f4a..f099699 100644
+--- a/arch/arm/mach-omap2/board-n8x0.c
++++ b/arch/arm/mach-omap2/board-n8x0.c
+@@ -593,7 +593,7 @@ static int n8x0_menelaus_late_init(struct device *dev)
+ }
+ #endif
+ 
+-static struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
++static struct menelaus_platform_data n8x0_menelaus_platform_data __initconst = {
+ 	.late_init = n8x0_menelaus_late_init,
+ };
+ 
 diff --git a/arch/arm/mach-ux500/mbox-db5500.c b/arch/arm/mach-ux500/mbox-db5500.c
 index 2b2d51c..0127490 100644
 --- a/arch/arm/mach-ux500/mbox-db5500.c
@@ -994,7 +1720,7 @@ index 2b2d51c..0127490 100644
  static int mbox_show(struct seq_file *s, void *data)
  {
 diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
-index aa33949..b242a2f 100644
+index aa33949..d366075 100644
 --- a/arch/arm/mm/fault.c
 +++ b/arch/arm/mm/fault.c
 @@ -183,6 +183,13 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
@@ -1045,6 +1771,27 @@ index aa33949..b242a2f 100644
  /*
   * First Level Translation Fault Handler
   *
+@@ -628,6 +662,20 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
+ 	const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
+ 	struct siginfo info;
+ 
++#ifdef CONFIG_PAX_REFCOUNT
++	if (fsr_fs(ifsr) == 2) {
++		unsigned int bkpt;
++
++		if (!probe_kernel_address((unsigned int *)addr, bkpt) && bkpt == 0xe12f1073) {
++			current->thread.error_code = ifsr;
++			current->thread.trap_no = 0;
++			pax_report_refcount_overflow(regs);
++			fixup_exception(regs);
++			return;
++		}
++	}
++#endif
++
+ 	if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
+ 		return;
+ 
 diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
 index 44b628e..623ee2a 100644
 --- a/arch/arm/mm/mmap.c
@@ -1098,6 +1845,48 @@ index 44b628e..623ee2a 100644
  			/*
  			 * Remember the place where we stopped the search:
  			 */
+diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
+index 4c1a363..df311d0 100644
+--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
++++ b/arch/arm/plat-samsung/include/plat/dma-ops.h
+@@ -41,7 +41,7 @@ struct samsung_dma_ops {
+ 	int (*started)(unsigned ch);
+ 	int (*flush)(unsigned ch);
+ 	int (*stop)(unsigned ch);
+-};
++} __no_const;
+ 
+ extern void *samsung_dmadev_get_ops(void);
+ extern void *s3c_dma_get_ops(void);
+diff --git a/arch/arm/plat-samsung/include/plat/ehci.h b/arch/arm/plat-samsung/include/plat/ehci.h
+index 5f28cae..3d23723 100644
+--- a/arch/arm/plat-samsung/include/plat/ehci.h
++++ b/arch/arm/plat-samsung/include/plat/ehci.h
+@@ -14,7 +14,7 @@
+ struct s5p_ehci_platdata {
+ 	int (*phy_init)(struct platform_device *pdev, int type);
+ 	int (*phy_exit)(struct platform_device *pdev, int type);
+-};
++} __no_const;
+ 
+ extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd);
+ 
+diff --git a/arch/avr32/include/asm/cache.h b/arch/avr32/include/asm/cache.h
+index c3a58a1..78fbf54 100644
+--- a/arch/avr32/include/asm/cache.h
++++ b/arch/avr32/include/asm/cache.h
+@@ -1,8 +1,10 @@
+ #ifndef __ASM_AVR32_CACHE_H
+ #define __ASM_AVR32_CACHE_H
+ 
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT 5
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ /*
+  * Memory returned by kmalloc() may be used for DMA, so we must make
 diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h
 index 3b3159b..425ea94 100644
 --- a/arch/avr32/include/asm/elf.h
@@ -1177,6 +1966,60 @@ index f7040a1..db9f300 100644
  		if (exception_trace && printk_ratelimit())
  			printk("%s%s[%d]: segfault at %08lx pc %08lx "
  			       "sp %08lx ecr %lu\n",
+diff --git a/arch/blackfin/include/asm/cache.h b/arch/blackfin/include/asm/cache.h
+index 568885a..f8008df 100644
+--- a/arch/blackfin/include/asm/cache.h
++++ b/arch/blackfin/include/asm/cache.h
+@@ -7,6 +7,7 @@
+ #ifndef __ARCH_BLACKFIN_CACHE_H
+ #define __ARCH_BLACKFIN_CACHE_H
+ 
++#include <linux/const.h>
+ #include <linux/linkage.h>	/* for asmlinkage */
+ 
+ /*
+@@ -14,7 +15,7 @@
+  * Blackfin loads 32 bytes for cache
+  */
+ #define L1_CACHE_SHIFT	5
+-#define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES	(_AC(1,UL) << L1_CACHE_SHIFT)
+ #define SMP_CACHE_BYTES	L1_CACHE_BYTES
+ 
+ #define ARCH_DMA_MINALIGN	L1_CACHE_BYTES
+diff --git a/arch/cris/include/arch-v10/arch/cache.h b/arch/cris/include/arch-v10/arch/cache.h
+index aea2718..3639a60 100644
+--- a/arch/cris/include/arch-v10/arch/cache.h
++++ b/arch/cris/include/arch-v10/arch/cache.h
+@@ -1,8 +1,9 @@
+ #ifndef _ASM_ARCH_CACHE_H
+ #define _ASM_ARCH_CACHE_H
+ 
++#include <linux/const.h>
+ /* Etrax 100LX have 32-byte cache-lines. */
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #endif /* _ASM_ARCH_CACHE_H */
+diff --git a/arch/cris/include/arch-v32/arch/cache.h b/arch/cris/include/arch-v32/arch/cache.h
+index 1de779f..336fad3 100644
+--- a/arch/cris/include/arch-v32/arch/cache.h
++++ b/arch/cris/include/arch-v32/arch/cache.h
+@@ -1,11 +1,12 @@
+ #ifndef _ASM_CRIS_ARCH_CACHE_H
+ #define _ASM_CRIS_ARCH_CACHE_H
+ 
++#include <linux/const.h>
+ #include <arch/hwregs/dma.h>
+ 
+ /* A cache-line is 32 bytes. */
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define __read_mostly __attribute__((__section__(".data.read_mostly")))
+ 
 diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h
 index 0d8a7d6..d0c9ff5 100644
 --- a/arch/frv/include/asm/atomic.h
@@ -1198,6 +2041,23 @@ index 0d8a7d6..d0c9ff5 100644
  static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
  {
  	int c, old;
+diff --git a/arch/frv/include/asm/cache.h b/arch/frv/include/asm/cache.h
+index 2797163..c2a401d 100644
+--- a/arch/frv/include/asm/cache.h
++++ b/arch/frv/include/asm/cache.h
+@@ -12,10 +12,11 @@
+ #ifndef __ASM_CACHE_H
+ #define __ASM_CACHE_H
+ 
++#include <linux/const.h>
+ 
+ /* bytes per L1 cache line */
+ #define L1_CACHE_SHIFT		(CONFIG_FRV_L1_CACHE_SHIFT)
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define __cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
+ #define ____cacheline_aligned	__attribute__((aligned(L1_CACHE_BYTES)))
 diff --git a/arch/frv/include/asm/kmap_types.h b/arch/frv/include/asm/kmap_types.h
 index f8e16b2..c73ff79 100644
 --- a/arch/frv/include/asm/kmap_types.h
@@ -1242,6 +2102,40 @@ index 385fd30..6c3d97e 100644
  				goto success;
  			addr = vma->vm_end;
  		}
+diff --git a/arch/h8300/include/asm/cache.h b/arch/h8300/include/asm/cache.h
+index c635028..6d9445a 100644
+--- a/arch/h8300/include/asm/cache.h
++++ b/arch/h8300/include/asm/cache.h
+@@ -1,8 +1,10 @@
+ #ifndef __ARCH_H8300_CACHE_H
+ #define __ARCH_H8300_CACHE_H
+ 
++#include <linux/const.h>
++
+ /* bytes per L1 cache line */
+-#define        L1_CACHE_BYTES  4
++#define        L1_CACHE_BYTES  _AC(4,UL)
+ 
+ /* m68k-elf-gcc  2.95.2 doesn't like these */
+ 
+diff --git a/arch/hexagon/include/asm/cache.h b/arch/hexagon/include/asm/cache.h
+index 0f01de2..d37d309 100644
+--- a/arch/hexagon/include/asm/cache.h
++++ b/arch/hexagon/include/asm/cache.h
+@@ -21,9 +21,11 @@
+ #ifndef __ASM_CACHE_H
+ #define __ASM_CACHE_H
+ 
++#include <linux/const.h>
++
+ /* Bytes per L1 cache line */
+-#define L1_CACHE_SHIFT		(5)
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_SHIFT		5
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define __cacheline_aligned	__aligned(L1_CACHE_BYTES)
+ #define ____cacheline_aligned	__aligned(L1_CACHE_BYTES)
 diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h
 index 3fad89e..3047da5 100644
 --- a/arch/ia64/include/asm/atomic.h
@@ -1263,6 +2157,27 @@ index 3fad89e..3047da5 100644
  /* Atomic operations are already serializing */
  #define smp_mb__before_atomic_dec()	barrier()
  #define smp_mb__after_atomic_dec()	barrier()
+diff --git a/arch/ia64/include/asm/cache.h b/arch/ia64/include/asm/cache.h
+index 988254a..e1ee885 100644
+--- a/arch/ia64/include/asm/cache.h
++++ b/arch/ia64/include/asm/cache.h
+@@ -1,6 +1,7 @@
+ #ifndef _ASM_IA64_CACHE_H
+ #define _ASM_IA64_CACHE_H
+ 
++#include <linux/const.h>
+ 
+ /*
+  * Copyright (C) 1998-2000 Hewlett-Packard Co
+@@ -9,7 +10,7 @@
+ 
+ /* Bytes per L1 (data) cache line.  */
+ #define L1_CACHE_SHIFT		CONFIG_IA64_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #ifdef CONFIG_SMP
+ # define SMP_CACHE_SHIFT	L1_CACHE_SHIFT
 diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
 index b5298eb..67c6e62 100644
 --- a/arch/ia64/include/asm/elf.h
@@ -1578,6 +2493,22 @@ index 00cb0e2..2ad8024 100644
  		vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
  		down_write(&current->mm->mmap_sem);
  		if (insert_vm_struct(current->mm, vma)) {
+diff --git a/arch/m32r/include/asm/cache.h b/arch/m32r/include/asm/cache.h
+index 40b3ee9..8c2c112 100644
+--- a/arch/m32r/include/asm/cache.h
++++ b/arch/m32r/include/asm/cache.h
+@@ -1,8 +1,10 @@
+ #ifndef _ASM_M32R_CACHE_H
+ #define _ASM_M32R_CACHE_H
+ 
++#include <linux/const.h>
++
+ /* L1 cache line size */
+ #define L1_CACHE_SHIFT		4
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #endif  /* _ASM_M32R_CACHE_H */
 diff --git a/arch/m32r/lib/usercopy.c b/arch/m32r/lib/usercopy.c
 index 82abd15..d95ae5d 100644
 --- a/arch/m32r/lib/usercopy.c
@@ -1602,6 +2533,41 @@ index 82abd15..d95ae5d 100644
  	prefetchw(to);
  	if (access_ok(VERIFY_READ, from, n))
  		__copy_user_zeroing(to,from,n);
+diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h
+index 0395c51..5f26031 100644
+--- a/arch/m68k/include/asm/cache.h
++++ b/arch/m68k/include/asm/cache.h
+@@ -4,9 +4,11 @@
+ #ifndef __ARCH_M68K_CACHE_H
+ #define __ARCH_M68K_CACHE_H
+ 
++#include <linux/const.h>
++
+ /* bytes per L1 cache line */
+ #define        L1_CACHE_SHIFT  4
+-#define        L1_CACHE_BYTES  (1<< L1_CACHE_SHIFT)
++#define        L1_CACHE_BYTES  (_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define ARCH_DMA_MINALIGN	L1_CACHE_BYTES
+ 
+diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h
+index 4efe96a..60e8699 100644
+--- a/arch/microblaze/include/asm/cache.h
++++ b/arch/microblaze/include/asm/cache.h
+@@ -13,11 +13,12 @@
+ #ifndef _ASM_MICROBLAZE_CACHE_H
+ #define _ASM_MICROBLAZE_CACHE_H
+ 
++#include <linux/const.h>
+ #include <asm/registers.h>
+ 
+ #define L1_CACHE_SHIFT 5
+ /* word-granular cache in microblaze */
+-#define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES	(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define SMP_CACHE_BYTES	L1_CACHE_BYTES
+ 
 diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
 index 1d93f81..67794d0 100644
 --- a/arch/mips/include/asm/atomic.h
@@ -1634,6 +2600,23 @@ index 1d93f81..67794d0 100644
  #endif /* CONFIG_64BIT */
  
  /*
+diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h
+index b4db69f..8f3b093 100644
+--- a/arch/mips/include/asm/cache.h
++++ b/arch/mips/include/asm/cache.h
+@@ -9,10 +9,11 @@
+ #ifndef _ASM_CACHE_H
+ #define _ASM_CACHE_H
+ 
++#include <linux/const.h>
+ #include <kmalloc.h>
+ 
+ #define L1_CACHE_SHIFT		CONFIG_MIPS_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define SMP_CACHE_SHIFT		L1_CACHE_SHIFT
+ #define SMP_CACHE_BYTES		L1_CACHE_BYTES
 diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
 index 455c0ac..ad65fbe 100644
 --- a/arch/mips/include/asm/elf.h
@@ -1852,6 +2835,66 @@ index 302d779..7d35bf8 100644
 -
 -	return ret;
 -}
+diff --git a/arch/mn10300/proc-mn103e010/include/proc/cache.h b/arch/mn10300/proc-mn103e010/include/proc/cache.h
+index 967d144..db12197 100644
+--- a/arch/mn10300/proc-mn103e010/include/proc/cache.h
++++ b/arch/mn10300/proc-mn103e010/include/proc/cache.h
+@@ -11,12 +11,14 @@
+ #ifndef _ASM_PROC_CACHE_H
+ #define _ASM_PROC_CACHE_H
+ 
++#include <linux/const.h>
++
+ /* L1 cache */
+ 
+ #define L1_CACHE_NWAYS		4	/* number of ways in caches */
+ #define L1_CACHE_NENTRIES	256	/* number of entries in each way */
+-#define L1_CACHE_BYTES		16	/* bytes per entry */
+ #define L1_CACHE_SHIFT		4	/* shift for bytes per entry */
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)	/* bytes per entry */
+ #define L1_CACHE_WAYDISP	0x1000	/* displacement of one way from the next */
+ 
+ #define L1_CACHE_TAG_VALID	0x00000001	/* cache tag valid bit */
+diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/cache.h b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
+index bcb5df2..84fabd2 100644
+--- a/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
++++ b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
+@@ -16,13 +16,15 @@
+ #ifndef _ASM_PROC_CACHE_H
+ #define _ASM_PROC_CACHE_H
+ 
++#include <linux/const.h>
++
+ /*
+  * L1 cache
+  */
+ #define L1_CACHE_NWAYS		4		/* number of ways in caches */
+ #define L1_CACHE_NENTRIES	128		/* number of entries in each way */
+-#define L1_CACHE_BYTES		32		/* bytes per entry */
+ #define L1_CACHE_SHIFT		5		/* shift for bytes per entry */
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)	/* bytes per entry */
+ #define L1_CACHE_WAYDISP	0x1000		/* distance from one way to the next */
+ 
+ #define L1_CACHE_TAG_VALID	0x00000001	/* cache tag valid bit */
+diff --git a/arch/openrisc/include/asm/cache.h b/arch/openrisc/include/asm/cache.h
+index 4ce7a01..449202a 100644
+--- a/arch/openrisc/include/asm/cache.h
++++ b/arch/openrisc/include/asm/cache.h
+@@ -19,11 +19,13 @@
+ #ifndef __ASM_OPENRISC_CACHE_H
+ #define __ASM_OPENRISC_CACHE_H
+ 
++#include <linux/const.h>
++
+ /* FIXME: How can we replace these with values from the CPU...
+  * they shouldn't be hard-coded!
+  */
+ 
+-#define L1_CACHE_BYTES 16
+ #define L1_CACHE_SHIFT 4
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #endif /* __ASM_OPENRISC_CACHE_H */
 diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
 index 4054b31..a10c105 100644
 --- a/arch/parisc/include/asm/atomic.h
@@ -1873,6 +2916,34 @@ index 4054b31..a10c105 100644
  #endif /* !CONFIG_64BIT */
  
  
+diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
+index 47f11c7..3420df2 100644
+--- a/arch/parisc/include/asm/cache.h
++++ b/arch/parisc/include/asm/cache.h
+@@ -5,6 +5,7 @@
+ #ifndef __ARCH_PARISC_CACHE_H
+ #define __ARCH_PARISC_CACHE_H
+ 
++#include <linux/const.h>
+ 
+ /*
+  * PA 2.0 processors have 64-byte cachelines; PA 1.1 processors have
+@@ -15,13 +16,13 @@
+  * just ruin performance.
+  */
+ #ifdef CONFIG_PA20
+-#define L1_CACHE_BYTES 64
+ #define L1_CACHE_SHIFT 6
+ #else
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
+ #endif
+ 
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
++
+ #ifndef __ASSEMBLY__
+ 
+ #define SMP_CACHE_BYTES L1_CACHE_BYTES
 diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
 index 19f6cb1..6c78cf2 100644
 --- a/arch/parisc/include/asm/elf.h
@@ -2256,6 +3327,27 @@ index 02e41b5..ec6e26c 100644
  #endif /* __powerpc64__ */
  
  #endif /* __KERNEL__ */
+diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
+index 4b50941..5605819 100644
+--- a/arch/powerpc/include/asm/cache.h
++++ b/arch/powerpc/include/asm/cache.h
+@@ -3,6 +3,7 @@
+ 
+ #ifdef __KERNEL__
+ 
++#include <linux/const.h>
+ 
+ /* bytes per L1 cache line */
+ #if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
+@@ -22,7 +23,7 @@
+ #define L1_CACHE_SHIFT		7
+ #endif
+ 
+-#define	L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define	L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define	SMP_CACHE_BYTES		L1_CACHE_BYTES
+ 
 diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
 index 3bf9cca..e7457d0 100644
 --- a/arch/powerpc/include/asm/elf.h
@@ -2636,6 +3728,34 @@ index cf9c69b..ebc9640 100644
  	mr	r5,r3
  	addi	r3,r1,STACK_FRAME_OVERHEAD
  	lwz	r4,_DAR(r1)
+diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
+index 745c1e7..59d97a6 100644
+--- a/arch/powerpc/kernel/irq.c
++++ b/arch/powerpc/kernel/irq.c
+@@ -547,9 +547,6 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
+ 	host->ops = ops;
+ 	host->of_node = of_node_get(of_node);
+ 
+-	if (host->ops->match == NULL)
+-		host->ops->match = default_irq_host_match;
+-
+ 	raw_spin_lock_irqsave(&irq_big_lock, flags);
+ 
+ 	/* If it's a legacy controller, check for duplicates and
+@@ -622,7 +619,12 @@ struct irq_host *irq_find_host(struct device_node *node)
+ 	 */
+ 	raw_spin_lock_irqsave(&irq_big_lock, flags);
+ 	list_for_each_entry(h, &irq_hosts, link)
+-		if (h->ops->match(h, node)) {
++		if (h->ops->match) {
++			if (h->ops->match(h, node)) {
++				found = h;
++				break;
++			}
++		} else if (default_irq_host_match(h, node)) {
+ 			found = h;
+ 			break;
+ 		}
 diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
 index 0b6d796..d760ddb 100644
 --- a/arch/powerpc/kernel/module_32.c
@@ -3104,6 +4224,22 @@ index 8517d2a..d2738d4 100644
  #define smp_mb__before_atomic_dec()	smp_mb()
  #define smp_mb__after_atomic_dec()	smp_mb()
  #define smp_mb__before_atomic_inc()	smp_mb()
+diff --git a/arch/s390/include/asm/cache.h b/arch/s390/include/asm/cache.h
+index 2a30d5a..5e5586f 100644
+--- a/arch/s390/include/asm/cache.h
++++ b/arch/s390/include/asm/cache.h
+@@ -11,8 +11,10 @@
+ #ifndef __ARCH_S390_CACHE_H
+ #define __ARCH_S390_CACHE_H
+ 
+-#define L1_CACHE_BYTES     256
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT     8
++#define L1_CACHE_BYTES     (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define NET_SKB_PAD	   32
+ 
+ #define __read_mostly __attribute__((__section__(".data..read_mostly")))
 diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
 index 547f1a6..0b22b53 100644
 --- a/arch/s390/include/asm/elf.h
@@ -3258,10 +4394,10 @@ index dfcb343..eda788a 100644
  		if (r_type == R_390_GOTPC)
  			*(unsigned int *) loc = val;
 diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
-index 9451b21..ed8956f 100644
+index 53088e2..9f44a36 100644
 --- a/arch/s390/kernel/process.c
 +++ b/arch/s390/kernel/process.c
-@@ -321,39 +321,3 @@ unsigned long get_wchan(struct task_struct *p)
+@@ -320,39 +320,3 @@ unsigned long get_wchan(struct task_struct *p)
  	}
  	return 0;
  }
@@ -3302,7 +4438,7 @@ index 9451b21..ed8956f 100644
 -	return ret;
 -}
 diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
-index f09c748..cf9ec1d 100644
+index a0155c0..34cc491 100644
 --- a/arch/s390/mm/mmap.c
 +++ b/arch/s390/mm/mmap.c
 @@ -92,10 +92,22 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
@@ -3351,6 +4487,21 @@ index f09c748..cf9ec1d 100644
  		mm->get_unmapped_area = s390_get_unmapped_area_topdown;
  		mm->unmap_area = arch_unmap_area_topdown;
  	}
+diff --git a/arch/score/include/asm/cache.h b/arch/score/include/asm/cache.h
+index ae3d59f..f65f075 100644
+--- a/arch/score/include/asm/cache.h
++++ b/arch/score/include/asm/cache.h
+@@ -1,7 +1,9 @@
+ #ifndef _ASM_SCORE_CACHE_H
+ #define _ASM_SCORE_CACHE_H
+ 
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT		4
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #endif /* _ASM_SCORE_CACHE_H */
 diff --git a/arch/score/include/asm/system.h b/arch/score/include/asm/system.h
 index 589d5c7..669e274 100644
 --- a/arch/score/include/asm/system.h
@@ -3377,6 +4528,23 @@ index 25d0803..d6c8e36 100644
 -{
 -	return sp;
 -}
+diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h
+index ef9e555..331bd29 100644
+--- a/arch/sh/include/asm/cache.h
++++ b/arch/sh/include/asm/cache.h
+@@ -9,10 +9,11 @@
+ #define __ASM_SH_CACHE_H
+ #ifdef __KERNEL__
+ 
++#include <linux/const.h>
+ #include <linux/init.h>
+ #include <cpu/cache.h>
+ 
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #define __read_mostly __attribute__((__section__(".data..read_mostly")))
+ 
 diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
 index afeb710..d1d1289 100644
 --- a/arch/sh/mm/mmap.c
@@ -3480,17 +4648,19 @@ index ad1fb5d..fc5315b 100644
  VMLINUX_MAIN += $(patsubst %/, %/lib.a, $(libs-y)) $(libs-y)
  VMLINUX_MAIN += $(drivers-y) $(net-y)
  
-diff --git a/arch/sparc/include/asm/atomic.h b/arch/sparc/include/asm/atomic.h
-index 8ff83d8..4a459c2 100644
---- a/arch/sparc/include/asm/atomic.h
-+++ b/arch/sparc/include/asm/atomic.h
-@@ -4,5 +4,6 @@
- #include <asm/atomic_64.h>
- #else
- #include <asm/atomic_32.h>
+diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h
+index 5c3c8b6..ba822fa 100644
+--- a/arch/sparc/include/asm/atomic_32.h
++++ b/arch/sparc/include/asm/atomic_32.h
+@@ -13,6 +13,8 @@
+ 
+ #include <linux/types.h>
+ 
 +#include <asm-generic/atomic64.h>
- #endif
- #endif
++
+ #ifdef __KERNEL__
+ 
+ #include <asm/system.h>
 diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
 index 9f421df..b81fc12 100644
 --- a/arch/sparc/include/asm/atomic_64.h
@@ -3682,15 +4852,20 @@ index 9f421df..b81fc12 100644
  
  #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
 diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h
-index 69358b5..17b4745 100644
+index 69358b5..9d0d492 100644
 --- a/arch/sparc/include/asm/cache.h
 +++ b/arch/sparc/include/asm/cache.h
-@@ -10,7 +10,7 @@
+@@ -7,10 +7,12 @@
+ #ifndef _SPARC_CACHE_H
+ #define _SPARC_CACHE_H
+ 
++#include <linux/const.h>
++
  #define ARCH_SLAB_MINALIGN	__alignof__(unsigned long long)
  
  #define L1_CACHE_SHIFT 5
 -#define L1_CACHE_BYTES 32
-+#define L1_CACHE_BYTES 32UL
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
  
  #ifdef CONFIG_SPARC32
  #define SMP_CACHE_BYTES_SHIFT 5
@@ -5739,6 +6914,24 @@ index 27fe667..36d474c 100644
  /* Atomic dec and inc don't implement barrier, so provide them if needed. */
  #define smp_mb__before_atomic_dec()	smp_mb()
  #define smp_mb__after_atomic_dec()	smp_mb()
+diff --git a/arch/tile/include/asm/cache.h b/arch/tile/include/asm/cache.h
+index 392e533..536b092 100644
+--- a/arch/tile/include/asm/cache.h
++++ b/arch/tile/include/asm/cache.h
+@@ -15,11 +15,12 @@
+ #ifndef _ASM_TILE_CACHE_H
+ #define _ASM_TILE_CACHE_H
+ 
++#include <linux/const.h>
+ #include <arch/chip.h>
+ 
+ /* bytes per L1 data cache line */
+ #define L1_CACHE_SHIFT		CHIP_L1D_LOG_LINE_SIZE()
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ /* bytes per L2 cache line */
+ #define L2_CACHE_SHIFT		CHIP_L2_LOG_LINE_SIZE()
 diff --git a/arch/um/Makefile b/arch/um/Makefile
 index 7730af6..cce5b19 100644
 --- a/arch/um/Makefile
@@ -5754,6 +6947,26 @@ index 7730af6..cce5b19 100644
  #This will adjust *FLAGS accordingly to the platform.
  include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
  
+diff --git a/arch/um/include/asm/cache.h b/arch/um/include/asm/cache.h
+index 19e1bdd..3665b77 100644
+--- a/arch/um/include/asm/cache.h
++++ b/arch/um/include/asm/cache.h
+@@ -1,6 +1,7 @@
+ #ifndef __UM_CACHE_H
+ #define __UM_CACHE_H
+ 
++#include <linux/const.h>
+ 
+ #if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
+ # define L1_CACHE_SHIFT		(CONFIG_X86_L1_CACHE_SHIFT)
+@@ -12,6 +13,6 @@
+ # define L1_CACHE_SHIFT		5
+ #endif
+ 
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ #endif
 diff --git a/arch/um/include/asm/kmap_types.h b/arch/um/include/asm/kmap_types.h
 index 6c03acd..a5e0215 100644
 --- a/arch/um/include/asm/kmap_types.h
@@ -5807,6 +7020,23 @@ index c533835..84db18e 100644
  unsigned long get_wchan(struct task_struct *p)
  {
  	unsigned long stack_page, sp, ip;
+diff --git a/arch/unicore32/include/asm/cache.h b/arch/unicore32/include/asm/cache.h
+index ad8f795..2c7eec6 100644
+--- a/arch/unicore32/include/asm/cache.h
++++ b/arch/unicore32/include/asm/cache.h
+@@ -12,8 +12,10 @@
+ #ifndef __UNICORE_CACHE_H__
+ #define __UNICORE_CACHE_H__
+ 
+-#define L1_CACHE_SHIFT		(5)
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#include <linux/const.h>
++
++#define L1_CACHE_SHIFT		5
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ /*
+  * Memory returned by kmalloc() may be used for DMA, so we must make
 diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
 index efb4294..61bc18c 100644
 --- a/arch/x86/Kconfig
@@ -18517,10 +19747,10 @@ index 9299410..ade2f9b 100644
  	spin_unlock(&vcpu->kvm->mmu_lock);
  
 diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
-index e32243e..a6e6172 100644
+index 94a4672..5c6b853 100644
 --- a/arch/x86/kvm/svm.c
 +++ b/arch/x86/kvm/svm.c
-@@ -3400,7 +3400,11 @@ static void reload_tss(struct kvm_vcpu *vcpu)
+@@ -3405,7 +3405,11 @@ static void reload_tss(struct kvm_vcpu *vcpu)
  	int cpu = raw_smp_processor_id();
  
  	struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
@@ -18532,7 +19762,7 @@ index e32243e..a6e6172 100644
  	load_TR_desc();
  }
  
-@@ -3778,6 +3782,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+@@ -3783,6 +3787,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
  #endif
  #endif
  
@@ -25137,6 +26367,67 @@ index b095739..8c17bcd 100644
  struct trap_info;
  void xen_copy_trap_info(struct trap_info *traps);
  
+diff --git a/arch/xtensa/variants/dc232b/include/variant/core.h b/arch/xtensa/variants/dc232b/include/variant/core.h
+index 525bd3d..ef888b1 100644
+--- a/arch/xtensa/variants/dc232b/include/variant/core.h
++++ b/arch/xtensa/variants/dc232b/include/variant/core.h
+@@ -119,9 +119,9 @@
+   ----------------------------------------------------------------------*/
+ 
+ #define XCHAL_ICACHE_LINESIZE		32	/* I-cache line size in bytes */
+-#define XCHAL_DCACHE_LINESIZE		32	/* D-cache line size in bytes */
+ #define XCHAL_ICACHE_LINEWIDTH		5	/* log2(I line size in bytes) */
+ #define XCHAL_DCACHE_LINEWIDTH		5	/* log2(D line size in bytes) */
++#define XCHAL_DCACHE_LINESIZE		(_AC(1,UL) << XCHAL_DCACHE_LINEWIDTH)	/* D-cache line size in bytes */
+ 
+ #define XCHAL_ICACHE_SIZE		16384	/* I-cache size in bytes or 0 */
+ #define XCHAL_DCACHE_SIZE		16384	/* D-cache size in bytes or 0 */
+diff --git a/arch/xtensa/variants/fsf/include/variant/core.h b/arch/xtensa/variants/fsf/include/variant/core.h
+index 2f33760..835e50a 100644
+--- a/arch/xtensa/variants/fsf/include/variant/core.h
++++ b/arch/xtensa/variants/fsf/include/variant/core.h
+@@ -11,6 +11,7 @@
+ #ifndef _XTENSA_CORE_H
+ #define _XTENSA_CORE_H
+ 
++#include <linux/const.h>
+ 
+ /****************************************************************************
+ 	    Parameters Useful for Any Code, USER or PRIVILEGED
+@@ -112,9 +113,9 @@
+   ----------------------------------------------------------------------*/
+ 
+ #define XCHAL_ICACHE_LINESIZE		16	/* I-cache line size in bytes */
+-#define XCHAL_DCACHE_LINESIZE		16	/* D-cache line size in bytes */
+ #define XCHAL_ICACHE_LINEWIDTH		4	/* log2(I line size in bytes) */
+ #define XCHAL_DCACHE_LINEWIDTH		4	/* log2(D line size in bytes) */
++#define XCHAL_DCACHE_LINESIZE		(_AC(1,UL) << XCHAL_DCACHE_LINEWIDTH) /* D-cache line size in bytes */
+ 
+ #define XCHAL_ICACHE_SIZE		8192	/* I-cache size in bytes or 0 */
+ #define XCHAL_DCACHE_SIZE		8192	/* D-cache size in bytes or 0 */
+diff --git a/arch/xtensa/variants/s6000/include/variant/core.h b/arch/xtensa/variants/s6000/include/variant/core.h
+index af00795..2bb8105 100644
+--- a/arch/xtensa/variants/s6000/include/variant/core.h
++++ b/arch/xtensa/variants/s6000/include/variant/core.h
+@@ -11,6 +11,7 @@
+ #ifndef _XTENSA_CORE_CONFIGURATION_H
+ #define _XTENSA_CORE_CONFIGURATION_H
+ 
++#include <linux/const.h>
+ 
+ /****************************************************************************
+ 	    Parameters Useful for Any Code, USER or PRIVILEGED
+@@ -118,9 +119,9 @@
+   ----------------------------------------------------------------------*/
+ 
+ #define XCHAL_ICACHE_LINESIZE		16	/* I-cache line size in bytes */
+-#define XCHAL_DCACHE_LINESIZE		16	/* D-cache line size in bytes */
+ #define XCHAL_ICACHE_LINEWIDTH		4	/* log2(I line size in bytes) */
+ #define XCHAL_DCACHE_LINEWIDTH		4	/* log2(D line size in bytes) */
++#define XCHAL_DCACHE_LINESIZE		(_AC(1,UL) << XCHAL_DCACHE_LINEWIDTH)	/* D-cache line size in bytes */
+ 
+ #define XCHAL_ICACHE_SIZE		32768	/* I-cache size in bytes or 0 */
+ #define XCHAL_DCACHE_SIZE		32768	/* D-cache size in bytes or 0 */
 diff --git a/block/blk-iopoll.c b/block/blk-iopoll.c
 index 58916af..9cb880b 100644
 --- a/block/blk-iopoll.c
@@ -25177,7 +26468,7 @@ index 1366a89..e17f54b 100644
  	struct list_head *cpu_list, local_list;
  
 diff --git a/block/bsg.c b/block/bsg.c
-index 702f131..37808bf 100644
+index c0ab25c..9d49f8f 100644
 --- a/block/bsg.c
 +++ b/block/bsg.c
 @@ -176,16 +176,24 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
@@ -28548,7 +29839,7 @@ index d47a53b..61154c2 100644
  	INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
  	INIT_WORK(&dev_priv->error_work, i915_error_work_func);
 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index daa5743..c0757a9 100644
+index 9ec9755..6d1cf2d 100644
 --- a/drivers/gpu/drm/i915/intel_display.c
 +++ b/drivers/gpu/drm/i915/intel_display.c
 @@ -2230,7 +2230,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
@@ -31226,7 +32517,7 @@ index 4daf9e5..b8d1d0f 100644
  	.device		= PCI_ANY_ID,
  	.subvendor	= PCI_ANY_ID,
 diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
-index 31c2dc2..a2de7a6 100644
+index 1ce84ed..0fdd40a 100644
 --- a/drivers/md/dm-ioctl.c
 +++ b/drivers/md/dm-ioctl.c
 @@ -1589,7 +1589,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
@@ -31370,10 +32661,10 @@ index 8e91321..fd17aef 100644
  		       "start=%llu, len=%llu, dev_size=%llu",
  		       dm_device_name(ti->table->md), bdevname(bdev, b),
 diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
-index 59c4f04..4c7b661 100644
+index 237571a..fb6d19b 100644
 --- a/drivers/md/dm-thin-metadata.c
 +++ b/drivers/md/dm-thin-metadata.c
-@@ -431,7 +431,7 @@ static int init_pmd(struct dm_pool_metadata *pmd,
+@@ -432,7 +432,7 @@ static int init_pmd(struct dm_pool_metadata *pmd,
  
  	pmd->info.tm = tm;
  	pmd->info.levels = 2;
@@ -31382,7 +32673,7 @@ index 59c4f04..4c7b661 100644
  	pmd->info.value_type.size = sizeof(__le64);
  	pmd->info.value_type.inc = data_block_inc;
  	pmd->info.value_type.dec = data_block_dec;
-@@ -450,7 +450,7 @@ static int init_pmd(struct dm_pool_metadata *pmd,
+@@ -451,7 +451,7 @@ static int init_pmd(struct dm_pool_metadata *pmd,
  
  	pmd->bl_info.tm = tm;
  	pmd->bl_info.levels = 1;
@@ -31925,6 +33216,35 @@ index 68d1240..46b32eb 100644
  	{0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
  	{0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
  	{0, }
+diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
+index ee0d0b3..7db1a4f 100644
+--- a/drivers/media/video/omap/omap_vout.c
++++ b/drivers/media/video/omap/omap_vout.c
+@@ -64,7 +64,12 @@ enum omap_vout_channels {
+ 	OMAP_VIDEO2,
+ };
+ 
+-static struct videobuf_queue_ops video_vbq_ops;
++static struct videobuf_queue_ops video_vbq_ops = {
++	.buf_setup = omap_vout_buffer_setup,
++	.buf_prepare = omap_vout_buffer_prepare,
++	.buf_release = omap_vout_buffer_release,
++	.buf_queue = omap_vout_buffer_queue,
++};
+ /* Variables configurable through module params*/
+ static u32 video1_numbuffers = 3;
+ static u32 video2_numbuffers = 3;
+@@ -1016,10 +1021,6 @@ static int omap_vout_open(struct file *file)
+ 	vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ 
+ 	q = &vout->vbq;
+-	video_vbq_ops.buf_setup = omap_vout_buffer_setup;
+-	video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
+-	video_vbq_ops.buf_release = omap_vout_buffer_release;
+-	video_vbq_ops.buf_queue = omap_vout_buffer_queue;
+ 	spin_lock_init(&vout->vbq_lock);
+ 
+ 	videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev,
 diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
 index 305e6aa..0143317 100644
 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -32755,6 +34075,32 @@ index bf266a0..e024af7 100644
  }
  
  void be_parse_stats(struct be_adapter *adapter)
+diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
+index fb5579a..debdffa 100644
+--- a/drivers/net/ethernet/faraday/ftgmac100.c
++++ b/drivers/net/ethernet/faraday/ftgmac100.c
+@@ -30,6 +30,8 @@
+ #include <linux/netdevice.h>
+ #include <linux/phy.h>
+ #include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/irqreturn.h>
+ #include <net/ip.h>
+ 
+ #include "ftgmac100.h"
+diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c
+index a127cb2..0d043cd 100644
+--- a/drivers/net/ethernet/faraday/ftmac100.c
++++ b/drivers/net/ethernet/faraday/ftmac100.c
+@@ -30,6 +30,8 @@
+ #include <linux/module.h>
+ #include <linux/netdevice.h>
+ #include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/irqreturn.h>
+ 
+ #include "ftmac100.h"
+ 
 diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c
 index 61d2bdd..7f1154a 100644
 --- a/drivers/net/ethernet/fealnx.c
@@ -33130,6 +34476,21 @@ index 1b4658c..a30dabb 100644
  	struct sis190_private *tp = netdev_priv(dev);
  	struct pci_dev *isa_bridge;
  	u8 reg, tmp8;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
+index 41e6b33..8e89b0f 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
+@@ -139,8 +139,8 @@ void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode)
+ 
+ 	writel(value, ioaddr + MMC_CNTRL);
+ 
+-	pr_debug("stmmac: MMC ctrl register (offset 0x%x): 0x%08x\n",
+-		 MMC_CNTRL, value);
++//	pr_debug("stmmac: MMC ctrl register (offset 0x%x): 0x%08x\n",
++//		 MMC_CNTRL, value);
+ }
+ 
+ /* To mask all all interrupts.*/
 diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
 index edfa15d..002bfa9 100644
 --- a/drivers/net/ppp/ppp_generic.c
@@ -33561,7 +34922,7 @@ index f5ae3c6..7936af3 100644
  
  static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
 diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
-index f389b3c..7359e18 100644
+index 1bd8edf..10c6d30 100644
 --- a/drivers/net/wireless/ath/ath9k/hw.h
 +++ b/drivers/net/wireless/ath/ath9k/hw.h
 @@ -605,7 +605,7 @@ struct ath_hw_private_ops {
@@ -39729,7 +41090,7 @@ index 79e2ca7..5828ad1 100644
  	  A.out (Assembler.OUTput) is a set of formats for libraries and
  	  executables used in the earliest versions of UNIX.  Linux used
 diff --git a/fs/aio.c b/fs/aio.c
-index 969beb0..09fab51 100644
+index 67e4b90..fbb09dc 100644
 --- a/fs/aio.c
 +++ b/fs/aio.c
 @@ -119,7 +119,7 @@ static int aio_setup_ring(struct kioctx *ctx)
@@ -39741,7 +41102,7 @@ index 969beb0..09fab51 100644
  		return -EINVAL;
  
  	nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
-@@ -1461,22 +1461,27 @@ static ssize_t aio_fsync(struct kiocb *iocb)
+@@ -1463,22 +1463,27 @@ static ssize_t aio_fsync(struct kiocb *iocb)
  static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat)
  {
  	ssize_t ret;
@@ -39784,7 +41145,7 @@ index 7ee7ba4..0c61a60 100644
  			goto out_sig;
  		if (offset > inode->i_sb->s_maxbytes)
 diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
-index e1fbdee..cd5ea56 100644
+index 6861f61..a25f010 100644
 --- a/fs/autofs4/waitq.c
 +++ b/fs/autofs4/waitq.c
 @@ -60,7 +60,7 @@ static int autofs4_write(struct file *file, const void *addr, int bytes)
@@ -39914,7 +41275,7 @@ index a6395bd..f1e376a 100644
  		(unsigned long) create_aout_tables((char __user *) bprm->p, bprm);
  #ifdef __alpha__
 diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
-index 21ac5ee..dbf63ee 100644
+index 6ff96c6..dbf63ee 100644
 --- a/fs/binfmt_elf.c
 +++ b/fs/binfmt_elf.c
 @@ -32,6 +32,7 @@
@@ -40605,15 +41966,6 @@ index 21ac5ee..dbf63ee 100644
  	fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
  }
  
-@@ -1421,7 +1886,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
- 	for (i = 1; i < view->n; ++i) {
- 		const struct user_regset *regset = &view->regsets[i];
- 		do_thread_regset_writeback(t->task, regset);
--		if (regset->core_note_type &&
-+		if (regset->core_note_type && regset->get &&
- 		    (!regset->active || regset->active(t->task, regset))) {
- 			int ret;
- 			size_t size = regset->n * regset->size;
 @@ -1862,14 +2327,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
  }
  
@@ -41747,7 +43099,7 @@ index 608c1c3..7d040a8 100644
  	return rc;
  }
 diff --git a/fs/exec.c b/fs/exec.c
-index 3625464..04855f9 100644
+index 3625464..cdeecdb 100644
 --- a/fs/exec.c
 +++ b/fs/exec.c
 @@ -55,12 +55,28 @@
@@ -41815,11 +43167,11 @@ index 3625464..04855f9 100644
  			return page;
  
 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+		// only allow 1MB for argv+env on suid/sgid binaries
++		// only allow 512KB for argv+env on suid/sgid binaries
 +		// to prevent easy ASLR exhaustion
 +		if (((bprm->cred->euid != current_euid()) ||
 +		     (bprm->cred->egid != current_egid())) &&
-+		    (size > (1024 * 1024))) {
++		    (size > (512 * 1024))) {
 +			put_page(page);
 +			return NULL;
 +		}
@@ -41847,7 +43199,7 @@ index 3625464..04855f9 100644
 +
 +#ifdef CONFIG_PAX_RANDUSTACK
 +	if (randomize_va_space)
-+		bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
++		bprm->p ^= random32() & ~PAGE_MASK;
 +#endif
 +
  	return 0;
@@ -42072,18 +43424,36 @@ index 3625464..04855f9 100644
  		bprm->unsafe |= LSM_UNSAFE_SHARE;
  	} else {
  		res = -EAGAIN;
-@@ -1442,6 +1475,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
+@@ -1442,6 +1475,28 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
  
  EXPORT_SYMBOL(search_binary_handler);
  
 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+static atomic64_unchecked_t global_exec_counter = ATOMIC64_INIT(0);
++static DEFINE_PER_CPU(u64, exec_counter);
++static int __init init_exec_counters(void)
++{
++	unsigned int cpu;
++
++	for_each_possible_cpu(cpu) {
++		per_cpu(exec_counter, cpu) = (u64)cpu;
++	}
++
++	return 0;
++}
++early_initcall(init_exec_counters);
++static inline void increment_exec_counter(void)
++{
++	BUILD_BUG_ON(NR_CPUS > (1 << 16));
++	current->exec_id = this_cpu_add_return(exec_counter, 1 << 16);
++}
++#else
++static inline void increment_exec_counter(void) {}
 +#endif
 +
  /*
   * sys_execve() executes a new program.
   */
-@@ -1450,6 +1487,11 @@ static int do_execve_common(const char *filename,
+@@ -1450,6 +1505,11 @@ static int do_execve_common(const char *filename,
  				struct user_arg_ptr envp,
  				struct pt_regs *regs)
  {
@@ -42095,7 +43465,7 @@ index 3625464..04855f9 100644
  	struct linux_binprm *bprm;
  	struct file *file;
  	struct files_struct *displaced;
-@@ -1457,6 +1499,8 @@ static int do_execve_common(const char *filename,
+@@ -1457,6 +1517,8 @@ static int do_execve_common(const char *filename,
  	int retval;
  	const struct cred *cred = current_cred();
  
@@ -42104,7 +43474,7 @@ index 3625464..04855f9 100644
  	/*
  	 * We move the actual failure in case of RLIMIT_NPROC excess from
  	 * set*uid() to execve() because too many poorly written programs
-@@ -1497,12 +1541,27 @@ static int do_execve_common(const char *filename,
+@@ -1497,12 +1559,27 @@ static int do_execve_common(const char *filename,
  	if (IS_ERR(file))
  		goto out_unmark;
  
@@ -42132,24 +43502,10 @@ index 3625464..04855f9 100644
  	retval = bprm_mm_init(bprm);
  	if (retval)
  		goto out_file;
-@@ -1532,11 +1591,46 @@ static int do_execve_common(const char *filename,
+@@ -1519,24 +1596,65 @@ static int do_execve_common(const char *filename,
  	if (retval < 0)
  		goto out;
  
-+	if (!gr_tpe_allow(file)) {
-+		retval = -EACCES;
-+		goto out;
-+	}
-+
-+	if (gr_check_crash_exec(file)) {
-+		retval = -EACCES;
-+		goto out;
-+	}
-+
-+	gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
-+
-+	gr_handle_exec_args(bprm, argv);
-+
 +#ifdef CONFIG_GRKERNSEC
 +	old_acl = current->acl;
 +	memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
@@ -42157,12 +43513,50 @@ index 3625464..04855f9 100644
 +	get_file(file);
 +	current->exec_file = file;
 +#endif
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
++	/* limit suid stack to 8MB
++	   we saved the old limits above and will restore them if this exec fails
++	*/
++	if (((bprm->cred->euid != current_euid()) || (bprm->cred->egid != current_egid())) &&
++	    (old_rlim[RLIMIT_STACK].rlim_cur > (8 * 1024 * 1024)))
++		current->signal->rlim[RLIMIT_STACK].rlim_cur = 8 * 1024 * 1024;
++#endif
++
++	if (!gr_tpe_allow(file)) {
++		retval = -EACCES;
++		goto out_fail;
++	}
++
++	if (gr_check_crash_exec(file)) {
++		retval = -EACCES;
++		goto out_fail;
++	}
 +
 +	retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt,
 +					bprm->unsafe);
 +	if (retval < 0)
 +		goto out_fail;
 +
+ 	retval = copy_strings_kernel(1, &bprm->filename, bprm);
+ 	if (retval < 0)
+-		goto out;
++		goto out_fail;
+ 
+ 	bprm->exec = bprm->p;
+ 	retval = copy_strings(bprm->envc, envp, bprm);
+ 	if (retval < 0)
+-		goto out;
++		goto out_fail;
+ 
+ 	retval = copy_strings(bprm->argc, argv, bprm);
+ 	if (retval < 0)
+-		goto out;
++		goto out_fail;
++
++	gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
++
++	gr_handle_exec_args(bprm, argv);
+ 
  	retval = search_binary_handler(bprm,regs);
  	if (retval < 0)
 -		goto out;
@@ -42173,14 +43567,12 @@ index 3625464..04855f9 100644
 +#endif
  
  	/* execve succeeded */
-+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
-+	current->exec_id = atomic64_inc_return_unchecked(&global_exec_counter);
-+#endif
 +
++	increment_exec_counter();
  	current->fs->in_exec = 0;
  	current->in_execve = 0;
  	acct_update_integrals(current);
-@@ -1545,6 +1639,14 @@ static int do_execve_common(const char *filename,
+@@ -1545,6 +1663,14 @@ static int do_execve_common(const char *filename,
  		put_files_struct(displaced);
  	return retval;
  
@@ -42195,7 +43587,7 @@ index 3625464..04855f9 100644
  out:
  	if (bprm->mm) {
  		acct_arg_size(bprm, 0);
-@@ -1618,7 +1720,7 @@ static int expand_corename(struct core_name *cn)
+@@ -1618,7 +1744,7 @@ static int expand_corename(struct core_name *cn)
  {
  	char *old_corename = cn->corename;
  
@@ -42204,7 +43596,7 @@ index 3625464..04855f9 100644
  	cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL);
  
  	if (!cn->corename) {
-@@ -1715,7 +1817,7 @@ static int format_corename(struct core_name *cn, long signr)
+@@ -1715,7 +1841,7 @@ static int format_corename(struct core_name *cn, long signr)
  	int pid_in_pattern = 0;
  	int err = 0;
  
@@ -42213,7 +43605,7 @@ index 3625464..04855f9 100644
  	cn->corename = kmalloc(cn->size, GFP_KERNEL);
  	cn->used = 0;
  
-@@ -1812,6 +1914,218 @@ out:
+@@ -1812,6 +1938,218 @@ out:
  	return ispipe;
  }
  
@@ -42404,7 +43796,7 @@ index 3625464..04855f9 100644
 +#endif
 +}
 +
-+NORET_TYPE void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
++__noreturn void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
 +{
 +	if (current->signal->curr_ip)
 +		printk(KERN_ERR "PAX: From %pI4: kernel memory %s attempt detected %s %p (%s) (%lu bytes)\n",
@@ -42432,7 +43824,7 @@ index 3625464..04855f9 100644
  static int zap_process(struct task_struct *start, int exit_code)
  {
  	struct task_struct *t;
-@@ -2023,17 +2337,17 @@ static void wait_for_dump_helpers(struct file *file)
+@@ -2023,17 +2361,17 @@ static void wait_for_dump_helpers(struct file *file)
  	pipe = file->f_path.dentry->d_inode->i_pipe;
  
  	pipe_lock(pipe);
@@ -42455,7 +43847,7 @@ index 3625464..04855f9 100644
  	pipe_unlock(pipe);
  
  }
-@@ -2094,7 +2408,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2094,7 +2432,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
  	int retval = 0;
  	int flag = 0;
  	int ispipe;
@@ -42464,7 +43856,7 @@ index 3625464..04855f9 100644
  	struct coredump_params cprm = {
  		.signr = signr,
  		.regs = regs,
-@@ -2109,6 +2423,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2109,6 +2447,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
  
  	audit_core_dumps(signr);
  
@@ -42474,7 +43866,7 @@ index 3625464..04855f9 100644
  	binfmt = mm->binfmt;
  	if (!binfmt || !binfmt->core_dump)
  		goto fail;
-@@ -2176,7 +2493,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2176,7 +2517,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
  		}
  		cprm.limit = RLIM_INFINITY;
  
@@ -42483,7 +43875,7 @@ index 3625464..04855f9 100644
  		if (core_pipe_limit && (core_pipe_limit < dump_count)) {
  			printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n",
  			       task_tgid_vnr(current), current->comm);
-@@ -2203,6 +2520,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2203,6 +2544,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
  	} else {
  		struct inode *inode;
  
@@ -42492,7 +43884,7 @@ index 3625464..04855f9 100644
  		if (cprm.limit < binfmt->min_coredump)
  			goto fail_unlock;
  
-@@ -2246,7 +2565,7 @@ close_fail:
+@@ -2246,7 +2589,7 @@ close_fail:
  		filp_close(cprm.file, NULL);
  fail_dropcount:
  	if (ispipe)
@@ -42501,7 +43893,7 @@ index 3625464..04855f9 100644
  fail_unlock:
  	kfree(cn.corename);
  fail_corename:
-@@ -2265,7 +2584,7 @@ fail:
+@@ -2265,7 +2608,7 @@ fail:
   */
  int dump_write(struct file *file, const void *addr, int nr)
  {
@@ -47392,10 +48784,10 @@ index 23ce927..e274cc1 100644
  		kfree(s);
 diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
 new file mode 100644
-index 0000000..41df561
+index 0000000..4089e05
 --- /dev/null
 +++ b/grsecurity/Kconfig
-@@ -0,0 +1,1075 @@
+@@ -0,0 +1,1078 @@
 +#
 +# grecurity configuration
 +#
@@ -47670,11 +49062,13 @@ index 0000000..41df561
 +	  dangerous sources of information, this option causes reads of sensitive
 +	  /proc/<pid> entries where the file descriptor was opened in a different
 +	  task than the one performing the read.  Such attempts are logged.
-+	  Finally, this option limits argv/env strings for suid/sgid binaries
-+	  to 1MB to prevent a complete exhaustion of the stack entropy provided
-+	  by ASLR.
++	  This option also limits argv/env strings for suid/sgid binaries
++	  to 512KB to prevent a complete exhaustion of the stack entropy provided
++	  by ASLR.  Finally, it places an 8MB stack resource limit on suid/sgid
++	  binaries to prevent alternative mmap layouts from being abused.
++
 +	  If you use PaX it is essential that you say Y here as it closes up
-+	  several holes that make full ASLR useless for suid/sgid binaries.
++	  several holes that make full ASLR useless locally.
 +
 +config GRKERNSEC_BRUTE
 +	bool "Deter exploit bruteforcing"
@@ -47814,8 +49208,9 @@ index 0000000..41df561
 +	  Depending upon the option you choose, you can either restrict users to
 +	  see only the processes they themselves run, or choose a group that can
 +	  view all processes and files normally restricted to root if you choose
-+	  the "restrict to user only" option.  NOTE: If you're running identd as
-+	  a non-root user, you will have to run it as the group you specify here.
++	  the "restrict to user only" option.  NOTE: If you're running identd or
++	  ntpd as a non-root user, you will have to run it as the group you
++	  specify here.
 +
 +config GRKERNSEC_PROC_USER
 +	bool "Restrict /proc to user only"
@@ -48473,10 +49868,10 @@ index 0000000..41df561
 +endmenu
 diff --git a/grsecurity/Makefile b/grsecurity/Makefile
 new file mode 100644
-index 0000000..496e60d
+index 0000000..1b9afa9
 --- /dev/null
 +++ b/grsecurity/Makefile
-@@ -0,0 +1,40 @@
+@@ -0,0 +1,38 @@
 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
 +# during 2001-2009 it has been completely redesigned by Brad Spengler
 +# into an RBAC system
@@ -48485,9 +49880,7 @@ index 0000000..496e60d
 +# are copyright Brad Spengler - Open Source Security, Inc., and released 
 +# under the GPL v2 or higher
 +
-+ifndef CONFIG_IA64
 +KBUILD_CFLAGS += -Werror
-+endif
 +
 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
 +	grsec_mount.o grsec_sig.o grsec_sysctl.o \
@@ -57705,6 +59098,19 @@ index 1bfcfe5..e04c5c9 100644
 +#define L1_CACHE_BYTES		(1UL << L1_CACHE_SHIFT)
  
  #endif /* __ASM_GENERIC_CACHE_H */
+diff --git a/include/asm-generic/emergency-restart.h b/include/asm-generic/emergency-restart.h
+index 0d68a1e..b74a761 100644
+--- a/include/asm-generic/emergency-restart.h
++++ b/include/asm-generic/emergency-restart.h
+@@ -1,7 +1,7 @@
+ #ifndef _ASM_GENERIC_EMERGENCY_RESTART_H
+ #define _ASM_GENERIC_EMERGENCY_RESTART_H
+ 
+-static inline void machine_emergency_restart(void)
++static inline __noreturn void machine_emergency_restart(void)
+ {
+ 	machine_restart(NULL);
+ }
 diff --git a/include/asm-generic/int-l64.h b/include/asm-generic/int-l64.h
 index 1ca3efc..e3dc852 100644
 --- a/include/asm-generic/int-l64.h
@@ -57748,6 +59154,18 @@ index 0232ccb..13d9165 100644
  };
  
  #undef KMAP_D
+diff --git a/include/asm-generic/local.h b/include/asm-generic/local.h
+index 9ceb03b..2efbcbd 100644
+--- a/include/asm-generic/local.h
++++ b/include/asm-generic/local.h
+@@ -39,6 +39,7 @@ typedef struct
+ #define local_add_return(i, l) atomic_long_add_return((i), (&(l)->a))
+ #define local_sub_return(i, l) atomic_long_sub_return((i), (&(l)->a))
+ #define local_inc_return(l) atomic_long_inc_return(&(l)->a)
++#define local_dec_return(l) atomic_long_dec_return(&(l)->a)
+ 
+ #define local_cmpxchg(l, o, n) atomic_long_cmpxchg((&(l)->a), (o), (n))
+ #define local_xchg(l, n) atomic_long_xchg((&(l)->a), (n))
 diff --git a/include/asm-generic/pgtable-nopmd.h b/include/asm-generic/pgtable-nopmd.h
 index 725612b..9cc513a 100644
 --- a/include/asm-generic/pgtable-nopmd.h
@@ -60354,6 +61772,18 @@ index 7939f63..ec6df57 100644
  	= { .max = ARRAY_SIZE(array), .num = nump,                      \
  	    .ops = &param_ops_##type,					\
  	    .elemsize = sizeof(array[0]), .elem = array };		\
+diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
+index a9e6ba4..0f9e29b 100644
+--- a/include/linux/mtd/map.h
++++ b/include/linux/mtd/map.h
+@@ -25,6 +25,7 @@
+ #include <linux/types.h>
+ #include <linux/list.h>
+ #include <linux/string.h>
++#include <linux/kernel.h>
+ #include <linux/bug.h>
+ 
+ 
 diff --git a/include/linux/namei.h b/include/linux/namei.h
 index ffc0213..2c1f2cb 100644
 --- a/include/linux/namei.h
@@ -60486,6 +61916,18 @@ index b1f8912..c955bff 100644
  
  	/*
  	 * Protect attach/detach and child_list:
+diff --git a/include/linux/personality.h b/include/linux/personality.h
+index 8fc7dd1a..c19d89e 100644
+--- a/include/linux/personality.h
++++ b/include/linux/personality.h
+@@ -44,6 +44,7 @@ enum {
+ #define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC  | \
+ 			    ADDR_NO_RANDOMIZE  | \
+ 			    ADDR_COMPAT_LAYOUT | \
++			    ADDR_LIMIT_3GB     | \
+ 			    MMAP_PAGE_ZERO)
+ 
+ /*
 diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
 index 77257c9..51d473a 100644
 --- a/include/linux/pipe_fs_i.h
@@ -60658,30 +62100,6 @@ index e0879a7..a12f962 100644
  #include <asm/emergency-restart.h>
  
  #endif
-diff --git a/include/linux/regset.h b/include/linux/regset.h
-index 8abee65..5150fd1 100644
---- a/include/linux/regset.h
-+++ b/include/linux/regset.h
-@@ -335,6 +335,9 @@ static inline int copy_regset_to_user(struct task_struct *target,
- {
- 	const struct user_regset *regset = &view->regsets[setno];
- 
-+	if (!regset->get)
-+		return -EOPNOTSUPP;
-+
- 	if (!access_ok(VERIFY_WRITE, data, size))
- 		return -EIO;
- 
-@@ -358,6 +361,9 @@ static inline int copy_regset_from_user(struct task_struct *target,
- {
- 	const struct user_regset *regset = &view->regsets[setno];
- 
-+	if (!regset->set)
-+		return -EOPNOTSUPP;
-+
- 	if (!access_ok(VERIFY_READ, data, size))
- 		return -EIO;
- 
 diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
 index 96d465f..b084e05 100644
 --- a/include/linux/reiserfs_fs.h
@@ -60762,7 +62180,7 @@ index 2148b12..519b820 100644
  
  static inline void anon_vma_merge(struct vm_area_struct *vma,
 diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 1c4f3e9..b4e4851 100644
+index 1c4f3e9..342eb1f 100644
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
 @@ -101,6 +101,7 @@ struct bio_list;
@@ -60946,7 +62364,7 @@ index 1c4f3e9..b4e4851 100644
 +extern void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
 +extern void pax_report_insns(struct pt_regs *regs, void *pc, void *sp);
 +extern void pax_report_refcount_overflow(struct pt_regs *regs);
-+extern NORET_TYPE void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type) ATTRIB_NORET;
++extern __noreturn void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type);
 +
  /* Future-safe accessor for struct task_struct's cpus_allowed. */
  #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
@@ -60987,7 +62405,7 @@ index 1c4f3e9..b4e4851 100644
  extern void flush_itimer_signals(void);
  
 -extern NORET_TYPE void do_group_exit(int);
-+extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
++extern __noreturn void do_group_exit(int);
  
  extern void daemonize(const char *, ...);
  extern int allow_signal(int);
@@ -63630,7 +65048,7 @@ index 58690af..d903d75 100644
  
  	/*
 diff --git a/kernel/exit.c b/kernel/exit.c
-index e6e01b9..619f837 100644
+index e6e01b9..0a21b0a 100644
 --- a/kernel/exit.c
 +++ b/kernel/exit.c
 @@ -57,6 +57,10 @@
@@ -63709,6 +65127,15 @@ index e6e01b9..619f837 100644
  	exit_mm(tsk);
  
  	if (group_dead)
+@@ -1068,7 +1091,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
+  * Take down every thread in the group.  This is called by fatal signals
+  * as well as by sys_exit_group (below).
+  */
+-NORET_TYPE void
++__noreturn void
+ do_group_exit(int exit_code)
+ {
+ 	struct signal_struct *sig = current->signal;
 diff --git a/kernel/fork.c b/kernel/fork.c
 index 0acf42c0..9e40e2e 100644
 --- a/kernel/fork.c
@@ -64409,7 +65836,7 @@ index a4bea97..7a1ae9a 100644
  		/*
  		 * If ret is 0, either ____call_usermodehelper failed and the
 diff --git a/kernel/kprobes.c b/kernel/kprobes.c
-index faa39d1..d7ad37e 100644
+index bc90b87..43c7d8c 100644
 --- a/kernel/kprobes.c
 +++ b/kernel/kprobes.c
 @@ -185,7 +185,7 @@ static kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c)
@@ -64430,7 +65857,7 @@ index faa39d1..d7ad37e 100644
  			kfree(kip);
  		}
  		return 1;
-@@ -1953,7 +1953,7 @@ static int __init init_kprobes(void)
+@@ -1955,7 +1955,7 @@ static int __init init_kprobes(void)
  {
  	int i, err = 0;
  	unsigned long offset = 0, size = 0;
@@ -64439,7 +65866,7 @@ index faa39d1..d7ad37e 100644
  	const char *symbol_name;
  	void *addr;
  	struct kprobe_blackpoint *kb;
-@@ -2079,7 +2079,7 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
+@@ -2081,7 +2081,7 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
  	const char *sym = NULL;
  	unsigned int i = *(loff_t *) v;
  	unsigned long offset = 0;
@@ -65860,6 +67287,28 @@ index 78ab24a..332c915 100644
  		goto out_put_task_struct;
  	}
  
+diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
+index 636af6d..8af70ab 100644
+--- a/kernel/rcutiny.c
++++ b/kernel/rcutiny.c
+@@ -46,7 +46,7 @@
+ struct rcu_ctrlblk;
+ static void invoke_rcu_callbacks(void);
+ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp);
+-static void rcu_process_callbacks(struct softirq_action *unused);
++static void rcu_process_callbacks(void);
+ static void __call_rcu(struct rcu_head *head,
+ 		       void (*func)(struct rcu_head *rcu),
+ 		       struct rcu_ctrlblk *rcp);
+@@ -186,7 +186,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
+ 	RCU_TRACE(trace_rcu_batch_end(rcp->name, cb_count));
+ }
+ 
+-static void rcu_process_callbacks(struct softirq_action *unused)
++static void rcu_process_callbacks(void)
+ {
+ 	__rcu_process_callbacks(&rcu_sched_ctrlblk);
+ 	__rcu_process_callbacks(&rcu_bh_ctrlblk);
 diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
 index 764825c..3aa6ac4 100644
 --- a/kernel/rcutorture.c
@@ -67983,10 +69432,10 @@ index 57d82c6..e9e0552 100644
  	set_page_address(page, (void *)vaddr);
  
 diff --git a/mm/huge_memory.c b/mm/huge_memory.c
-index 33141f5..e56bef9 100644
+index 8f005e9..1cb1036 100644
 --- a/mm/huge_memory.c
 +++ b/mm/huge_memory.c
-@@ -703,7 +703,7 @@ out:
+@@ -704,7 +704,7 @@ out:
  	 * run pte_offset_map on the pmd, if an huge pmd could
  	 * materialize from under us from a different thread.
  	 */
@@ -70753,7 +72202,7 @@ index 7fa41b4..6087460 100644
  	return count;
  }
 diff --git a/mm/nommu.c b/mm/nommu.c
-index ee7e57e..cae4e40 100644
+index f59e170..34e2a2b 100644
 --- a/mm/nommu.c
 +++ b/mm/nommu.c
 @@ -62,7 +62,6 @@ int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */
@@ -70764,7 +72213,7 @@ index ee7e57e..cae4e40 100644
  
  atomic_long_t mmap_pages_allocated;
  
-@@ -829,15 +828,6 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+@@ -827,15 +826,6 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
  EXPORT_SYMBOL(find_vma);
  
  /*
@@ -70780,7 +72229,7 @@ index ee7e57e..cae4e40 100644
   * expand a stack to a given address
   * - not supported under NOMMU conditions
   */
-@@ -1557,6 +1547,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -1555,6 +1545,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
  
  	/* most fields are the same, copy all, and then fixup */
  	*new = *vma;
@@ -72510,7 +73959,7 @@ index a5f4e57..910ee6d 100644
  
  	/* Okay, we found ICMPv6 header */
 diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
-index 5864cc4..121f3a3 100644
+index 5864cc4..121f3a30 100644
 --- a/net/bridge/netfilter/ebtables.c
 +++ b/net/bridge/netfilter/ebtables.c
 @@ -1513,7 +1513,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
@@ -74392,7 +75841,7 @@ index 9ee7164..56c5061 100644
  
   suspend:
 diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
-index 5a5a776..9600b11 100644
+index 7d84b87..6a69cd9 100644
 --- a/net/mac80211/rate.c
 +++ b/net/mac80211/rate.c
 @@ -401,7 +401,7 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
@@ -76374,7 +77823,7 @@ index 5c11312..72742b5 100644
      write_hex_cnt = 0;
      for (i = 0; i < logo_clutsize; i++) {
 diff --git a/security/Kconfig b/security/Kconfig
-index 51bd5a0..eeabc9f 100644
+index 51bd5a0..3a4ebd0 100644
 --- a/security/Kconfig
 +++ b/security/Kconfig
 @@ -4,6 +4,627 @@
@@ -76952,7 +78401,7 @@ index 51bd5a0..eeabc9f 100644
 +
 +config PAX_REFCOUNT
 +	bool "Prevent various kernel object reference counter overflows"
-+	depends on GRKERNSEC && (X86 || SPARC64)
++	depends on GRKERNSEC && ((ARM && (CPU_32v6 || CPU_32v6K || CPU_32v7)) || SPARC64 || X86)
 +	help
 +	  By saying Y here the kernel will detect and prevent overflowing
 +	  various (but not all) kinds of object reference counters.  Such
@@ -77795,10 +79244,10 @@ index 09d4648..cf234c7 100644
                  list_add(&s->list, &cs4297a_devs);
  
 diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
-index 5644711..a2aebc1 100644
+index 71f6744..d8aeae7 100644
 --- a/sound/pci/hda/hda_codec.h
 +++ b/sound/pci/hda/hda_codec.h
-@@ -611,7 +611,7 @@ struct hda_bus_ops {
+@@ -614,7 +614,7 @@ struct hda_bus_ops {
  	/* notify power-up/down from codec to controller */
  	void (*pm_notify)(struct hda_bus *bus);
  #endif
@@ -77807,7 +79256,7 @@ index 5644711..a2aebc1 100644
  
  /* template to pass to the bus constructor */
  struct hda_bus_template {
-@@ -713,6 +713,7 @@ struct hda_codec_ops {
+@@ -716,6 +716,7 @@ struct hda_codec_ops {
  #endif
  	void (*reboot_notify)(struct hda_codec *codec);
  };
@@ -77815,7 +79264,7 @@ index 5644711..a2aebc1 100644
  
  /* record for amp information cache */
  struct hda_cache_head {
-@@ -743,7 +744,7 @@ struct hda_pcm_ops {
+@@ -746,7 +747,7 @@ struct hda_pcm_ops {
  		       struct snd_pcm_substream *substream);
  	int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
  		       struct snd_pcm_substream *substream);
@@ -77824,7 +79273,7 @@ index 5644711..a2aebc1 100644
  
  /* PCM information for each substream */
  struct hda_pcm_stream {
-@@ -801,7 +802,7 @@ struct hda_codec {
+@@ -804,7 +805,7 @@ struct hda_codec {
  	const char *modelname;	/* model name for preset */
  
  	/* set by patch */
@@ -77935,10 +79384,10 @@ index a39edcc..1014050 100644
  };
 diff --git a/tools/gcc/Makefile b/tools/gcc/Makefile
 new file mode 100644
-index 0000000..469b06a
+index 0000000..894c8bf
 --- /dev/null
 +++ b/tools/gcc/Makefile
-@@ -0,0 +1,21 @@
+@@ -0,0 +1,23 @@
 +#CC := gcc
 +#PLUGIN_SOURCE_FILES := pax_plugin.c
 +#PLUGIN_OBJECT_FILES := $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES))
@@ -77952,6 +79401,7 @@ index 0000000..469b06a
 +hostlibs-$(CONFIG_KALLOCSTAT_PLUGIN) += kallocstat_plugin.so
 +hostlibs-$(CONFIG_PAX_KERNEXEC_PLUGIN) += kernexec_plugin.so
 +hostlibs-$(CONFIG_CHECKER_PLUGIN) += checker_plugin.so
++hostlibs-y += colorize_plugin.so
 +
 +always := $(hostlibs-y)
 +
@@ -77960,6 +79410,7 @@ index 0000000..469b06a
 +kallocstat_plugin-objs := kallocstat_plugin.o
 +kernexec_plugin-objs := kernexec_plugin.o
 +checker_plugin-objs := checker_plugin.o
++colorize_plugin-objs := colorize_plugin.o
 diff --git a/tools/gcc/checker_plugin.c b/tools/gcc/checker_plugin.c
 new file mode 100644
 index 0000000..d41b5af
@@ -78137,6 +79588,159 @@ index 0000000..d41b5af
 +
 +	return 0;
 +}
+diff --git a/tools/gcc/colorize_plugin.c b/tools/gcc/colorize_plugin.c
+new file mode 100644
+index 0000000..ee950d0
+--- /dev/null
++++ b/tools/gcc/colorize_plugin.c
+@@ -0,0 +1,147 @@
++/*
++ * Copyright 2012 by PaX Team <pageexec@freemail.hu>
++ * Licensed under the GPL v2
++ *
++ * Note: the choice of the license means that the compilation process is
++ *       NOT 'eligible' as defined by gcc's library exception to the GPL v3,
++ *       but for the kernel it doesn't matter since it doesn't link against
++ *       any of the gcc libraries
++ *
++ * gcc plugin to colorize diagnostic output
++ *
++ */
++
++#include "gcc-plugin.h"
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tree.h"
++#include "tree-pass.h"
++#include "flags.h"
++#include "intl.h"
++#include "toplev.h"
++#include "plugin.h"
++#include "diagnostic.h"
++#include "plugin-version.h"
++#include "tm.h"
++
++int plugin_is_GPL_compatible;
++
++static struct plugin_info colorize_plugin_info = {
++	.version	= "201203092200",
++};
++
++#define GREEN		"\033[32m\033[2m"
++#define LIGHTGREEN	"\033[32m\033[1m"
++#define YELLOW		"\033[33m\033[2m"
++#define LIGHTYELLOW	"\033[33m\033[1m"
++#define RED		"\033[31m\033[2m"
++#define LIGHTRED	"\033[31m\033[1m"
++#define BLUE		"\033[34m\033[2m"
++#define LIGHTBLUE	"\033[34m\033[1m"
++#define BRIGHT		"\033[m\033[1m"
++#define NORMAL		"\033[m"
++
++static diagnostic_starter_fn old_starter;
++static diagnostic_finalizer_fn old_finalizer;
++
++static void start_colorize(diagnostic_context *context, diagnostic_info *diagnostic)
++{
++	const char *color;
++	char *newprefix;
++
++	switch (diagnostic->kind) {
++	case DK_NOTE:
++		color = LIGHTBLUE;
++		break;
++
++	case DK_PEDWARN:
++	case DK_WARNING:
++		color = LIGHTYELLOW;
++		break;
++
++	case DK_ERROR:
++	case DK_FATAL:
++	case DK_ICE:
++	case DK_PERMERROR:
++	case DK_SORRY:
++		color = LIGHTRED;
++		break;
++
++	default:
++		color = NORMAL;
++	}
++
++	old_starter(context, diagnostic);
++	if (-1 == asprintf(&newprefix, "%s%s" NORMAL, color, context->printer->prefix))
++		return;
++	pp_destroy_prefix(context->printer);
++	pp_set_prefix(context->printer, newprefix);
++}
++
++static void finalize_colorize(diagnostic_context *context, diagnostic_info *diagnostic)
++{
++	old_finalizer(context, diagnostic);
++}
++
++static void colorize_arm(void)
++{
++	old_starter = diagnostic_starter(global_dc);
++	old_finalizer = diagnostic_finalizer(global_dc);
++
++	diagnostic_starter(global_dc) = start_colorize;
++	diagnostic_finalizer(global_dc) = finalize_colorize;
++}
++
++static unsigned int execute_colorize_rearm(void)
++{
++	if (diagnostic_starter(global_dc) == start_colorize)
++		return 0;
++
++	colorize_arm();
++	return 0;
++}
++
++struct simple_ipa_opt_pass pass_ipa_colorize_rearm = {
++	.pass = {
++		.type			= SIMPLE_IPA_PASS,
++		.name			= "colorize_rearm",
++		.gate			= NULL,
++		.execute		= execute_colorize_rearm,
++		.sub			= NULL,
++		.next			= NULL,
++		.static_pass_number	= 0,
++		.tv_id			= TV_NONE,
++		.properties_required	= 0,
++		.properties_provided	= 0,
++		.properties_destroyed	= 0,
++		.todo_flags_start	= 0,
++		.todo_flags_finish	= 0
++	}
++};
++
++static void colorize_start_unit(void *gcc_data, void *user_data)
++{
++	colorize_arm();
++}
++
++int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
++{
++	const char * const plugin_name = plugin_info->base_name;
++	struct register_pass_info colorize_rearm_pass_info = {
++		.pass				= &pass_ipa_colorize_rearm.pass,
++		.reference_pass_name		= "*free_lang_data",
++		.ref_pass_instance_number	= 0,
++		.pos_op 			= PASS_POS_INSERT_AFTER
++	};
++
++	if (!plugin_default_version_check(version, &gcc_version)) {
++		error(G_("incompatible gcc/plugin versions"));
++		return 1;
++	}
++
++	register_callback(plugin_name, PLUGIN_INFO, NULL, &colorize_plugin_info);
++	register_callback(plugin_name, PLUGIN_START_UNIT, &colorize_start_unit, NULL);
++	register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &colorize_rearm_pass_info);
++	return 0;
++}
 diff --git a/tools/gcc/constify_plugin.c b/tools/gcc/constify_plugin.c
 new file mode 100644
 index 0000000..704a564
@@ -79054,10 +80658,10 @@ index 0000000..008f159
 +}
 diff --git a/tools/gcc/stackleak_plugin.c b/tools/gcc/stackleak_plugin.c
 new file mode 100644
-index 0000000..4a9b187
+index 0000000..4e82b16
 --- /dev/null
 +++ b/tools/gcc/stackleak_plugin.c
-@@ -0,0 +1,326 @@
+@@ -0,0 +1,311 @@
 +/*
 + * Copyright 2011 by the PaX Team <pageexec@freemail.hu>
 + * Licensed under the GPL v2
@@ -79104,12 +80708,10 @@ index 0000000..4a9b187
 +static int track_frame_size = -1;
 +static const char track_function[] = "pax_track_stack";
 +static const char check_function[] = "pax_check_alloca";
-+static tree pax_check_alloca_decl;
-+static tree pax_track_stack_decl;
 +static bool init_locals;
 +
 +static struct plugin_info stackleak_plugin_info = {
-+	.version	= "201203021600",
++	.version	= "201203140940",
 +	.help		= "track-lowest-sp=nn\ttrack sp in functions whose frame size is at least nn bytes\n"
 +//			  "initialize-locals\t\tforcibly initialize all stack frames\n"
 +};
@@ -79162,20 +80764,29 @@ index 0000000..4a9b187
 +static void stackleak_check_alloca(gimple_stmt_iterator *gsi)
 +{
 +	gimple check_alloca;
-+	tree alloca_size;
++	tree fntype, fndecl, alloca_size;
++
++	fntype = build_function_type_list(void_type_node, long_unsigned_type_node, NULL_TREE);
++	fndecl = build_fn_decl(check_function, fntype);
++	DECL_ASSEMBLER_NAME(fndecl); // for LTO
 +
 +	// insert call to void pax_check_alloca(unsigned long size)
 +	alloca_size = gimple_call_arg(gsi_stmt(*gsi), 0);
-+	check_alloca = gimple_build_call(pax_check_alloca_decl, 1, alloca_size);
++	check_alloca = gimple_build_call(fndecl, 1, alloca_size);
 +	gsi_insert_before(gsi, check_alloca, GSI_SAME_STMT);
 +}
 +
 +static void stackleak_add_instrumentation(gimple_stmt_iterator *gsi)
 +{
 +	gimple track_stack;
++	tree fntype, fndecl;
++
++	fntype = build_function_type_list(void_type_node, NULL_TREE);
++	fndecl = build_fn_decl(track_function, fntype);
++	DECL_ASSEMBLER_NAME(fndecl); // for LTO
 +
 +	// insert call to void pax_track_stack(void)
-+	track_stack = gimple_build_call(pax_track_stack_decl, 0);
++	track_stack = gimple_build_call(fndecl, 0);
 +	gsi_insert_after(gsi, track_stack, GSI_CONTINUE_LINKING);
 +}
 +
@@ -79308,27 +80919,6 @@ index 0000000..4a9b187
 +	return 0;
 +}
 +
-+static void stackleak_start_unit(void *gcc_data, void *user_dat)
-+{
-+	tree fntype;
-+
-+	// declare void pax_check_alloca(unsigned long size)
-+	fntype = build_function_type_list(void_type_node, long_unsigned_type_node, NULL_TREE);
-+	pax_check_alloca_decl = build_fn_decl(check_function, fntype);
-+	DECL_ASSEMBLER_NAME(pax_check_alloca_decl); // for LTO
-+	TREE_PUBLIC(pax_check_alloca_decl) = 1;
-+	DECL_EXTERNAL(pax_check_alloca_decl) = 1;
-+	DECL_ARTIFICIAL(pax_check_alloca_decl) = 1;
-+
-+	// declare void pax_track_stack(void)
-+	fntype = build_function_type_list(void_type_node, NULL_TREE);
-+	pax_track_stack_decl = build_fn_decl(track_function, fntype);
-+	DECL_ASSEMBLER_NAME(pax_track_stack_decl); // for LTO
-+	TREE_PUBLIC(pax_track_stack_decl) = 1;
-+	DECL_EXTERNAL(pax_track_stack_decl) = 1;
-+	DECL_ARTIFICIAL(pax_track_stack_decl) = 1;
-+}
-+
 +int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
 +{
 +	const char * const plugin_name = plugin_info->base_name;
@@ -79378,7 +80968,6 @@ index 0000000..4a9b187
 +		error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
 +	}
 +
-+	register_callback("start_unit", PLUGIN_START_UNIT, &stackleak_start_unit, NULL);
 +	register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &stackleak_tree_instrument_pass_info);
 +	register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &stackleak_final_pass_info);
 +

diff --git a/3.2.9/4425_grsec_enable_xtpax.patch b/3.2.11/4425_grsec_enable_xtpax.patch
similarity index 100%
rename from 3.2.9/4425_grsec_enable_xtpax.patch
rename to 3.2.11/4425_grsec_enable_xtpax.patch

diff --git a/3.2.9/4430_grsec-remove-localversion-grsec.patch b/3.2.11/4430_grsec-remove-localversion-grsec.patch
similarity index 100%
rename from 3.2.9/4430_grsec-remove-localversion-grsec.patch
rename to 3.2.11/4430_grsec-remove-localversion-grsec.patch

diff --git a/3.2.9/4435_grsec-mute-warnings.patch b/3.2.11/4435_grsec-mute-warnings.patch
similarity index 100%
rename from 3.2.9/4435_grsec-mute-warnings.patch
rename to 3.2.11/4435_grsec-mute-warnings.patch

diff --git a/3.2.9/4440_grsec-remove-protected-paths.patch b/3.2.11/4440_grsec-remove-protected-paths.patch
similarity index 96%
rename from 3.2.9/4440_grsec-remove-protected-paths.patch
rename to 3.2.11/4440_grsec-remove-protected-paths.patch
index 5602e8e..637934a 100644
--- a/3.2.9/4440_grsec-remove-protected-paths.patch
+++ b/3.2.11/4440_grsec-remove-protected-paths.patch
@@ -6,7 +6,7 @@ the filesystem.
 diff -Naur a/grsecurity/Makefile b/grsecurity/Makefile
 --- a/grsecurity/Makefile	2011-10-19 20:42:50.000000000 -0400
 +++ b/grsecurity/Makefile	2011-10-19 20:45:08.000000000 -0400
-@@ -31,10 +31,4 @@
+@@ -29,10 +29,4 @@
  ifdef CONFIG_GRKERNSEC_HIDESYM
  extra-y := grsec_hidesym.o
  $(obj)/grsec_hidesym.o:

diff --git a/3.2.9/4445_grsec-pax-without-grsec.patch b/3.2.11/4445_grsec-pax-without-grsec.patch
similarity index 93%
rename from 3.2.9/4445_grsec-pax-without-grsec.patch
rename to 3.2.11/4445_grsec-pax-without-grsec.patch
index 0ef9311..58301c0 100644
--- a/3.2.9/4445_grsec-pax-without-grsec.patch
+++ b/3.2.11/4445_grsec-pax-without-grsec.patch
@@ -3,6 +3,9 @@ From: Anthony G. Basile <blueness@gentoo.org>
 With grsecurity-2.2.2-2.6.32.38-201104171745, the functions pax_report_leak_to_user and
 pax_report_overflow_from_user in fs/exec.c were consolidated into pax_report_usercopy.
 This patch has been updated to reflect that change.
+
+With grsecurity-2.9-2.6.32.58-201203131839, NORET_TYPE has been replaced by __noreturn.
+This patch has been updated to reflect that change.
 --
 From: Jory Pratt <anarchy@gentoo.org>
 Updated patch for kernel 2.6.32
@@ -36,7 +39,7 @@ diff -Naur a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
 diff -Naur a/fs/exec.c b/fs/exec.c
 --- a/fs/exec.c	2011-04-17 19:05:03.000000000 -0400
 +++ b/fs/exec.c	2011-04-17 19:20:30.000000000 -0400
-@@ -2024,9 +2024,11 @@
+@@ -2048,9 +2048,11 @@
  		}
  		up_read(&mm->mmap_sem);
  	}
@@ -48,7 +51,7 @@ diff -Naur a/fs/exec.c b/fs/exec.c
  		printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
  	printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
  			"PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
-@@ -2041,10 +2043,12 @@
+@@ -2065,10 +2067,12 @@
  #ifdef CONFIG_PAX_REFCOUNT
  void pax_report_refcount_overflow(struct pt_regs *regs)
  {
@@ -61,9 +64,9 @@ diff -Naur a/fs/exec.c b/fs/exec.c
  		printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
  				 current->comm, task_pid_nr(current), current_uid(), current_euid());
  	print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
-@@ -2103,10 +2107,12 @@
+@@ -2127,10 +2131,12 @@
  
- NORET_TYPE void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
+ __noreturn void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
  {
 +#ifdef CONFIG_GRKERNSEC
  	if (current->signal->curr_ip)

diff --git a/3.2.9/4450_grsec-kconfig-default-gids.patch b/3.2.11/4450_grsec-kconfig-default-gids.patch
similarity index 94%
rename from 3.2.9/4450_grsec-kconfig-default-gids.patch
rename to 3.2.11/4450_grsec-kconfig-default-gids.patch
index 71b2089..123f877 100644
--- a/3.2.9/4450_grsec-kconfig-default-gids.patch
+++ b/3.2.11/4450_grsec-kconfig-default-gids.patch
@@ -12,7 +12,7 @@ from shooting themselves in the foot.
 diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
 --- a/grsecurity/Kconfig	2011-12-12 16:54:30.000000000 -0500
 +++ b/grsecurity/Kconfig	2011-12-12 16:55:09.000000000 -0500
-@@ -440,7 +440,7 @@
+@@ -443,7 +443,7 @@
  config GRKERNSEC_PROC_GID
  	int "GID for special group"
  	depends on GRKERNSEC_PROC_USERGROUP
@@ -21,7 +21,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  
  config GRKERNSEC_PROC_ADD
  	bool "Additional restrictions"
-@@ -668,7 +668,7 @@
+@@ -671,7 +671,7 @@
  config GRKERNSEC_AUDIT_GID
  	int "GID for auditing"
  	depends on GRKERNSEC_AUDIT_GROUP
@@ -30,7 +30,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  
  config GRKERNSEC_EXECLOG
  	bool "Exec logging"
-@@ -872,7 +872,7 @@
+@@ -875,7 +875,7 @@
  config GRKERNSEC_TPE_GID
  	int "GID for untrusted users"
  	depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
@@ -39,7 +39,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  	help
  	  Setting this GID determines what group TPE restrictions will be
  	  *enabled* for.  If the sysctl option is enabled, a sysctl option
-@@ -881,7 +881,7 @@
+@@ -884,7 +884,7 @@
  config GRKERNSEC_TPE_GID
  	int "GID for trusted users"
  	depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
@@ -48,7 +48,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  	help
  	  Setting this GID determines what group TPE restrictions will be
  	  *disabled* for.  If the sysctl option is enabled, a sysctl option
-@@ -954,7 +954,7 @@
+@@ -957,7 +957,7 @@
  config GRKERNSEC_SOCKET_ALL_GID
  	int "GID to deny all sockets for"
  	depends on GRKERNSEC_SOCKET_ALL
@@ -57,7 +57,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  	help
  	  Here you can choose the GID to disable socket access for. Remember to
  	  add the users you want socket access disabled for to the GID
-@@ -975,7 +975,7 @@
+@@ -978,7 +978,7 @@
  config GRKERNSEC_SOCKET_CLIENT_GID
  	int "GID to deny client sockets for"
  	depends on GRKERNSEC_SOCKET_CLIENT
@@ -66,7 +66,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  	help
  	  Here you can choose the GID to disable client socket access for.
  	  Remember to add the users you want client socket access disabled for to
-@@ -993,7 +993,7 @@
+@@ -996,7 +996,7 @@
  config GRKERNSEC_SOCKET_SERVER_GID
  	int "GID to deny server sockets for"
  	depends on GRKERNSEC_SOCKET_SERVER

diff --git a/3.2.9/4455_grsec-kconfig-gentoo.patch b/3.2.11/4455_grsec-kconfig-gentoo.patch
similarity index 100%
rename from 3.2.9/4455_grsec-kconfig-gentoo.patch
rename to 3.2.11/4455_grsec-kconfig-gentoo.patch

diff --git a/3.2.9/4460-grsec-kconfig-proc-user.patch b/3.2.11/4460-grsec-kconfig-proc-user.patch
similarity index 96%
rename from 3.2.9/4460-grsec-kconfig-proc-user.patch
rename to 3.2.11/4460-grsec-kconfig-proc-user.patch
index 1081ed5..2261051 100644
--- a/3.2.9/4460-grsec-kconfig-proc-user.patch
+++ b/3.2.11/4460-grsec-kconfig-proc-user.patch
@@ -6,7 +6,7 @@ in a different way to avoid bug #366019.  This patch should eventually go upstre
 diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
 --- a/grsecurity/Kconfig	2011-06-29 10:02:56.000000000 -0400
 +++ b/grsecurity/Kconfig	2011-06-29 10:08:07.000000000 -0400
-@@ -674,7 +674,7 @@
+@@ -677,7 +677,7 @@
  
  config GRKERNSEC_PROC_USER
  	bool "Restrict /proc to user only"
@@ -15,7 +15,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
  	help
  	  If you say Y here, non-root users will only be able to view their own
  	  processes, and restricts them from viewing network-related information,
-@@ -682,7 +682,7 @@
+@@ -685,7 +685,7 @@
  
  config GRKERNSEC_PROC_USERGROUP
  	bool "Allow special group"

diff --git a/3.2.9/4465_selinux-avc_audit-log-curr_ip.patch b/3.2.11/4465_selinux-avc_audit-log-curr_ip.patch
similarity index 99%
rename from 3.2.9/4465_selinux-avc_audit-log-curr_ip.patch
rename to 3.2.11/4465_selinux-avc_audit-log-curr_ip.patch
index cbd978d..af8b7b8 100644
--- a/3.2.9/4465_selinux-avc_audit-log-curr_ip.patch
+++ b/3.2.11/4465_selinux-avc_audit-log-curr_ip.patch
@@ -28,7 +28,7 @@ Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@gnu.org>
 diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
 --- a/grsecurity/Kconfig	2011-04-17 19:25:54.000000000 -0400
 +++ b/grsecurity/Kconfig	2011-04-17 19:32:53.000000000 -0400
-@@ -1303,6 +1303,27 @@
+@@ -1306,6 +1306,27 @@
  menu "Logging Options"
  depends on GRKERNSEC
  

diff --git a/3.2.9/4470_disable-compat_vdso.patch b/3.2.11/4470_disable-compat_vdso.patch
similarity index 100%
rename from 3.2.9/4470_disable-compat_vdso.patch
rename to 3.2.11/4470_disable-compat_vdso.patch



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2012-03-15 15:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-15 15:09 [gentoo-commits] proj/hardened-patchset:master commit in: 3.2.11/, 2.6.32/, 3.2.9/ Anthony G. Basile

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