]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Sep 2009 17:37:28 +0000 (10:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Sep 2009 17:37:28 +0000 (10:37 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1623 commits)
  netxen: update copyright
  netxen: fix tx timeout recovery
  netxen: fix file firmware leak
  netxen: improve pci memory access
  netxen: change firmware write size
  tg3: Fix return ring size breakage
  netxen: build fix for INET=n
  cdc-phonet: autoconfigure Phonet address
  Phonet: back-end for autoconfigured addresses
  Phonet: fix netlink address dump error handling
  ipv6: Add IFA_F_DADFAILED flag
  net: Add DEVTYPE support for Ethernet based devices
  mv643xx_eth.c: remove unused txq_set_wrr()
  ucc_geth: Fix hangs after switching from full to half duplex
  ucc_geth: Rearrange some code to avoid forward declarations
  phy/marvell: Make non-aneg speed/duplex forcing work for 88E1111 PHYs
  drivers/net/phy: introduce missing kfree
  drivers/net/wan: introduce missing kfree
  net: force bridge module(s) to be GPL
  Subject: [PATCH] appletalk: Fix skb leak when ipddp interface is not loaded
  ...

Fixed up trivial conflicts:

 - arch/x86/include/asm/socket.h

   converted to <asm-generic/socket.h> in the x86 tree.  The generic
   header has the same new #define's, so that works out fine.

 - drivers/net/tun.c

   fix conflict between 89f56d1e9 ("tun: reuse struct sock fields") that
   switched over to using 'tun->socket.sk' instead of the redundantly
   available (and thus removed) 'tun->sk', and 2b980dbd ("lsm: Add hooks
   to the TUN driver") which added a new 'tun->sk' use.

   Noted in 'next' by Stephen Rothwell.

16 files changed:
1  2 
Documentation/feature-removal-schedule.txt
Documentation/kernel-parameters.txt
MAINTAINERS
arch/sparc/kernel/sys32.S
drivers/infiniband/hw/amso1100/c2.c
drivers/infiniband/hw/nes/nes_hw.c
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/net/cxgb3/cxgb3_main.c
drivers/net/gianfar.c
drivers/net/tun.c
drivers/s390/net/netiucv.c
include/linux/pci_ids.h
net/core/dev.c
net/ipv4/ip_output.c
net/sched/sch_api.c

index bb3a53cdfbc3153c7a30265498afd814ab72bfc8,fdb79994e79b13be03b01a3cb6a8851f004fcafc..503d21216d58195ece5d6892e8fa871cac9f7a18
@@@ -6,6 -6,35 +6,35 @@@ be removed from this file
  
  ---------------------------
  
+ What: PRISM54
+ When: 2.6.34
+ Why:  prism54 FullMAC PCI / Cardbus devices used to be supported only by the
+       prism54 wireless driver. After Intersil stopped selling these
+       devices in preference for the newer more flexible SoftMAC devices
+       a SoftMAC device driver was required and prism54 did not support
+       them. The p54pci driver now exists and has been present in the kernel for
+       a while. This driver supports both SoftMAC devices and FullMAC devices.
+       The main difference between these devices was the amount of memory which
+       could be used for the firmware. The SoftMAC devices support a smaller
+       amount of memory. Because of this the SoftMAC firmware fits into FullMAC
+       devices's memory. p54pci supports not only PCI / Cardbus but also USB
+       and SPI. Since p54pci supports all devices prism54 supports
+       you will have a conflict. I'm not quite sure how distributions are
+       handling this conflict right now. prism54 was kept around due to
+       claims users may experience issues when using the SoftMAC driver.
+       Time has passed users have not reported issues. If you use prism54
+       and for whatever reason you cannot use p54pci please let us know!
+       E-mail us at: linux-wireless@vger.kernel.org
+       For more information see the p54 wiki page:
+       http://wireless.kernel.org/en/users/Drivers/p54
+ Who:  Luis R. Rodriguez <lrodriguez@atheros.com>
+ ---------------------------
  What: IRQF_SAMPLE_RANDOM
  Check:        IRQF_SAMPLE_RANDOM
  When: July 2009
@@@ -206,6 -235,24 +235,6 @@@ Who:      Len Brown <len.brown@intel.com
  
  ---------------------------
  
 -What: libata spindown skipping and warning
 -When: Dec 2008
 -Why:  Some halt(8) implementations synchronize caches for and spin
 -      down libata disks because libata didn't use to spin down disk on
 -      system halt (only synchronized caches).
 -      Spin down on system halt is now implemented.  sysfs node
 -      /sys/class/scsi_disk/h:c:i:l/manage_start_stop is present if
 -      spin down support is available.
 -      Because issuing spin down command to an already spun down disk
 -      makes some disks spin up just to spin down again, libata tracks
 -      device spindown status to skip the extra spindown command and
 -      warn about it.
 -      This is to give userspace tools the time to get updated and will
 -      be removed after userspace is reasonably updated.
 -Who:  Tejun Heo <htejun@gmail.com>
 -
 ----------------------------
 -
  What: i386/x86_64 bzImage symlinks
  When: April 2010
  
@@@ -217,31 -264,6 +246,6 @@@ Who:      Thomas Gleixner <tglx@linutronix.d
  ---------------------------
  
  What (Why):
-       - include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files
-         (superseded by xt_TOS/xt_tos target & match)
-       - "forwarding" header files like ipt_mac.h in
-         include/linux/netfilter_ipv4/ and include/linux/netfilter_ipv6/
-       - xt_CONNMARK match revision 0
-         (superseded by xt_CONNMARK match revision 1)
-       - xt_MARK target revisions 0 and 1
-         (superseded by xt_MARK match revision 2)
-       - xt_connmark match revision 0
-         (superseded by xt_connmark match revision 1)
-       - xt_conntrack match revision 0
-         (superseded by xt_conntrack match revision 1)
-       - xt_iprange match revision 0,
-         include/linux/netfilter_ipv4/ipt_iprange.h
-         (superseded by xt_iprange match revision 1)
-       - xt_mark match revision 0
-         (superseded by xt_mark match revision 1)
        - xt_recent: the old ipt_recent proc dir
          (superseded by /proc/net/xt_recent)
  
@@@ -376,6 -398,15 +380,6 @@@ Who:      Thomas Gleixner <tglx@linutronix.d
  
  -----------------------------
  
 -What: obsolete generic irq defines and typedefs
 -When: 2.6.30
 -Why:  The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t)
 -      have been kept around for migration reasons. After more than two years
 -      it's time to remove them finally
 -Who:  Thomas Gleixner <tglx@linutronix.de>
 -
 ----------------------------
 -
  What: fakephp and associated sysfs files in /sys/bus/pci/slots/
  When: 2011
  Why:  In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to
@@@ -441,27 -472,3 +445,27 @@@ Why:     cpu_policy_rwsem has a new cleane
        cpufreq core and contained inside cpufreq.c. Other dependent
        drivers should not use it in order to safely avoid lockdep issues.
  Who:  Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
 +
 +----------------------------
 +
 +What: sound-slot/service-* module aliases and related clutters in
 +      sound/sound_core.c
 +When: August 2010
 +Why:  OSS sound_core grabs all legacy minors (0-255) of SOUND_MAJOR
 +      (14) and requests modules using custom sound-slot/service-*
 +      module aliases.  The only benefit of doing this is allowing
 +      use of custom module aliases which might as well be considered
 +      a bug at this point.  This preemptive claiming prevents
 +      alternative OSS implementations.
 +
 +      Till the feature is removed, the kernel will be requesting
 +      both sound-slot/service-* and the standard char-major-* module
 +      aliases and allow turning off the pre-claiming selectively via
 +      CONFIG_SOUND_OSS_CORE_PRECLAIM and soundcore.preclaim_oss
 +      kernel parameter.
 +
 +      After the transition phase is complete, both the custom module
 +      aliases and switches to disable it will go away.  This removal
 +      will also allow making ALSA OSS emulation independent of
 +      sound_core.  The dependency will be broken then too.
 +Who:  Tejun Heo <tj@kernel.org>
index 5d4427d17281acdb2c5f16f79f7f0c1e50e7f295,3fe614d405e0d5f6f4375e58d8ed4c828142dd92..cb3a169e372a78f72d2ae9f7f29f0aa4b34a2dd5
@@@ -1115,10 -1115,6 +1115,10 @@@ and is between 256 and 4096 characters
                        libata.dma=4      Compact Flash DMA only 
                        Combinations also work, so libata.dma=3 enables DMA
                        for disks and CDROMs, but not CFs.
 +      
 +      libata.ignore_hpa=      [LIBATA] Ignore HPA limit
 +                      libata.ignore_hpa=0       keep BIOS limits (default)
 +                      libata.ignore_hpa=1       ignore limits, using full disk
  
        libata.noacpi   [LIBATA] Disables use of ACPI in libata suspend/resume
                        when set.
                        [NFS] set the TCP port on which the NFSv4 callback
                        channel should listen.
  
 +      nfs.cache_getent=
 +                      [NFS] sets the pathname to the program which is used
 +                      to update the NFS client cache entries.
 +
 +      nfs.cache_getent_timeout=
 +                      [NFS] sets the timeout after which an attempt to
 +                      update a cache entry is deemed to have failed.
 +
        nfs.idmap_cache_timeout=
                        [NFS] set the maximum lifetime for idmapper cache
                        entries.
                        symbolic names: lapic and ioapic
                        Example: nmi_watchdog=2 or nmi_watchdog=panic,lapic
  
+       netpoll.carrier_timeout=
+                       [NET] Specifies amount of time (in seconds) that
+                       netpoll should wait for a carrier. By default netpoll
+                       waits 4 seconds.
        no387           [BUGS=X86-32] Tells the kernel to use the 387 maths
                        emulation library even if a 387 maths coprocessor
                        is present.
        stifb=          [HW]
                        Format: bpp:<bpp1>[:<bpp2>[:<bpp3>...]]
  
 +      sunrpc.min_resvport=
 +      sunrpc.max_resvport=
 +                      [NFS,SUNRPC]
 +                      SunRPC servers often require that client requests
 +                      originate from a privileged port (i.e. a port in the
 +                      range 0 < portnr < 1024).
 +                      An administrator who wishes to reserve some of these
 +                      ports for other uses may adjust the range that the
 +                      kernel's sunrpc client considers to be privileged
 +                      using these two parameters to set the minimum and
 +                      maximum port values.
 +
        sunrpc.pool_mode=
                        [NFS]
                        Control how the NFS server code allocates CPUs to
                        pernode     one pool for each NUMA node (equivalent
                                    to global on non-NUMA machines)
  
 +      sunrpc.tcp_slot_table_entries=
 +      sunrpc.udp_slot_table_entries=
 +                      [NFS,SUNRPC]
 +                      Sets the upper limit on the number of simultaneous
 +                      RPC calls that can be sent from the client to a
 +                      server. Increasing these values may allow you to
 +                      improve throughput, but will also increase the
 +                      amount of memory reserved for use by the client.
 +
        swiotlb=        [IA-64] Number of I/O TLB slabs
  
        switches=       [HW,M68k]
        trace_buf_size=nn[KMG]
                        [FTRACE] will set tracing buffer size.
  
 +      trace_event=[event-list]
 +                      [FTRACE] Set and start specified trace events in order
 +                      to facilitate early boot debugging.
 +                      See also Documentation/trace/events.txt
 +
        trix=           [HW,OSS] MediaTrix AudioTrix Pro
                        Format:
                        <io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
diff --combined MAINTAINERS
index 989ff1149390c783823cb5e671e5962574ffad9e,6e2e12fd9ef80aa016acce3ed61c00d507507486..e95cb772f93111f8e327233e662315f44a5db8a6
@@@ -439,7 -439,7 +439,7 @@@ F: drivers/hwmon/ams
  AMSO1100 RNIC DRIVER
  M:    Tom Tucker <tom@opengridcomputing.com>
  M:    Steve Wise <swise@opengridcomputing.com>
 -L:    general@lists.openfabrics.org
 +L:    linux-rdma@vger.kernel.org
  S:    Maintained
  F:    drivers/infiniband/hw/amso1100/
  
@@@ -876,6 -876,7 +876,7 @@@ M: "Luis R. Rodriguez" <lrodriguez@athe
  M:    Bob Copeland <me@bobcopeland.com>
  L:    linux-wireless@vger.kernel.org
  L:    ath5k-devel@lists.ath5k.org
+ W:    http://wireless.kernel.org/en/users/Drivers/ath5k
  S:    Maintained
  F:    drivers/net/wireless/ath/ath5k/
  
@@@ -887,6 -888,7 +888,7 @@@ M: Vasanthakumar Thiagarajan <vasanth@a
  M:    Senthil Balasubramanian <senthilkumar@atheros.com>
  L:    linux-wireless@vger.kernel.org
  L:    ath9k-devel@lists.ath9k.org
+ W:    http://wireless.kernel.org/en/users/Drivers/ath9k
  S:    Supported
  F:    drivers/net/wireless/ath/ath9k/
  
@@@ -1494,7 -1496,7 +1496,7 @@@ F:      drivers/net/cxgb3
  
  CXGB3 IWARP RNIC DRIVER (IW_CXGB3)
  M:    Steve Wise <swise@chelsio.com>
 -L:    general@lists.openfabrics.org
 +L:    linux-rdma@vger.kernel.org
  W:    http://www.openfabrics.org
  S:    Supported
  F:    drivers/infiniband/hw/cxgb3/
@@@ -1868,7 -1870,7 +1870,7 @@@ F:      fs/efs
  EHCA (IBM GX bus InfiniBand adapter) DRIVER
  M:    Hoang-Nam Nguyen <hnguyen@de.ibm.com>
  M:    Christoph Raisch <raisch@de.ibm.com>
 -L:    general@lists.openfabrics.org
 +L:    linux-rdma@vger.kernel.org
  S:    Supported
  F:    drivers/infiniband/hw/ehca/
  
@@@ -2238,13 -2240,6 +2240,13 @@@ T:    git git://git.kernel.org/pub/scm/lin
  S:    Maintained
  F:    drivers/media/video/gspca/pac207.c
  
 +GSPCA SN9C20X SUBDRIVER
 +M:    Brian Johnson <brijohn@gmail.com>
 +L:    linux-media@vger.kernel.org
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
 +S:    Maintained
 +F:    drivers/media/video/gspca/sn9c20x.c
 +
  GSPCA T613 SUBDRIVER
  M:    Leandro Costantino <lcostantino@gmail.com>
  L:    linux-media@vger.kernel.org
@@@ -2552,7 -2547,7 +2554,7 @@@ INFINIBAND SUBSYSTE
  M:    Roland Dreier <rolandd@cisco.com>
  M:    Sean Hefty <sean.hefty@intel.com>
  M:    Hal Rosenstock <hal.rosenstock@gmail.com>
 -L:    general@lists.openfabrics.org (moderated for non-subscribers)
 +L:    linux-rdma@vger.kernel.org
  W:    http://www.openib.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git
  S:    Supported
@@@ -2660,25 -2655,21 +2662,21 @@@ F:   drivers/net/ixgbe
  
  INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
  M:    Zhu Yi <yi.zhu@intel.com>
- M:    James Ketrenos <jketreno@linux.intel.com>
  M:    Reinette Chatre <reinette.chatre@intel.com>
+ M:    Intel Linux Wireless <ilw@linux.intel.com>
  L:    linux-wireless@vger.kernel.org
- L:    ipw2100-devel@lists.sourceforge.net
- W:    http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
  W:    http://ipw2100.sourceforge.net
- S:    Supported
+ S:    Odd Fixes
  F:    Documentation/networking/README.ipw2100
  F:    drivers/net/wireless/ipw2x00/ipw2100.*
  
  INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
  M:    Zhu Yi <yi.zhu@intel.com>
- M:    James Ketrenos <jketreno@linux.intel.com>
  M:    Reinette Chatre <reinette.chatre@intel.com>
+ M:    Intel Linux Wireless <ilw@linux.intel.com>
  L:    linux-wireless@vger.kernel.org
- L:    ipw2100-devel@lists.sourceforge.net
- W:    http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
  W:    http://ipw2200.sourceforge.net
- S:    Supported
+ S:    Odd Fixes
  F:    Documentation/networking/README.ipw2200
  F:    drivers/net/wireless/ipw2x00/ipw2200.*
  
@@@ -2695,8 -2686,8 +2693,8 @@@ F:      include/linux/wimax/i2400m.
  INTEL WIRELESS WIFI LINK (iwlwifi)
  M:    Zhu Yi <yi.zhu@intel.com>
  M:    Reinette Chatre <reinette.chatre@intel.com>
+ M:    Intel Linux Wireless <ilw@linux.intel.com>
  L:    linux-wireless@vger.kernel.org
- L:    ipw3945-devel@lists.sourceforge.net
  W:    http://intellinuxwireless.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
  S:    Supported
@@@ -2729,7 -2720,7 +2727,7 @@@ F:      drivers/net/ipg.
  
  IPATH DRIVER
  M:    Ralph Campbell <infinipath@qlogic.com>
 -L:    general@lists.openfabrics.org
 +L:    linux-rdma@vger.kernel.org
  T:    git git://git.qlogic.com/ipath-linux-2.6
  S:    Supported
  F:    drivers/infiniband/hw/ipath/
@@@ -3279,6 -3270,12 +3277,12 @@@ S:    Supporte
  F:    drivers/net/mv643xx_eth.*
  F:    include/linux/mv643xx.h
  
+ MARVELL MWL8K WIRELESS DRIVER
+ M:    Lennert Buytenhek <buytenh@marvell.com>
+ L:    linux-wireless@vger.kernel.org
+ S:    Supported
+ F:    drivers/net/wireless/mwl8k.c
  MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
  M:    Nicolas Pitre <nico@cam.org>
  S:    Maintained
@@@ -3428,7 -3425,6 +3432,7 @@@ F:      drivers/mfd
  
  MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
  S:    Orphan
 +L:    linux-mmc@vger.kernel.org
  F:    drivers/mmc/
  F:    include/linux/mmc/
  
@@@ -3485,7 -3481,7 +3489,7 @@@ F:      drivers/scsi/NCR_D700.
  NETEFFECT IWARP RNIC DRIVER (IW_NES)
  M:    Faisal Latif <faisal.latif@intel.com>
  M:    Chien Tung <chien.tin.tung@intel.com>
 -L:    general@lists.openfabrics.org
 +L:    linux-rdma@vger.kernel.org
  W:    http://www.neteffect.com
  S:    Supported
  F:    drivers/infiniband/hw/nes/
@@@ -3591,9 -3587,12 +3595,12 @@@ M:    "John W. Linville" <linville@tuxdriv
  L:    linux-wireless@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
  S:    Maintained
+ F:    net/mac80211/
+ F:    net/rfkill/
  F:    net/wireless/
  F:    include/net/ieee80211*
  F:    include/linux/wireless.h
+ F:    drivers/net/wireless/
  
  NETWORKING DRIVERS
  L:    netdev@vger.kernel.org
@@@ -3809,7 -3808,7 +3816,7 @@@ W:      http://open-osd.or
  T:    git git://git.open-osd.org/open-osd.git
  S:    Maintained
  F:    drivers/scsi/osd/
 -F:    drivers/include/scsi/osd_*
 +F:    include/scsi/osd_*
  F:    fs/exofs/
  
  P54 WIRELESS DRIVER
@@@ -4299,7 -4298,7 +4306,7 @@@ L:      linux-wireless@vger.kernel.or
  W:    http://linuxwireless.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
  S:    Maintained
- F:    drivers/net/wireless/rtl818*
+ F:    drivers/net/wireless/rtl818x/rtl8180*
  
  RTL8187 WIRELESS DRIVER
  M:    Herton Ronaldo Krzesinski <herton@mandriva.com.br>
@@@ -4526,9 -4525,10 +4533,10 @@@ S:    Supporte
  F:    drivers/net/benet/
  
  SFC NETWORK DRIVER
- P:    Steve Hodgson
- P:    Ben Hutchings
- M:    Robert Stonehouse <linux-net-drivers@solarflare.com>
+ M:    Solarflare linux maintainers <linux-net-drivers@solarflare.com>
+ M:    Steve Hodgson <shodgson@solarflare.com>
+ M:    Ben Hutchings <bhutchings@solarflare.com>
+ L:    netdev@vger.kernel.org
  S:    Supported
  F:    drivers/net/sfc/
  
@@@ -5578,6 -5578,24 +5586,24 @@@ M:    Miloslav Trmac <mitr@volny.cz
  S:    Maintained
  F:    drivers/input/misc/wistron_btns.c
  
+ WL1251 WIRELESS DRIVER
+ P:    Kalle Valo
+ M:    kalle.valo@nokia.com
+ L:    linux-wireless@vger.kernel.org
+ W:    http://wireless.kernel.org
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
+ S:    Maintained
+ F:    drivers/net/wireless/wl12xx/*
+ X:    drivers/net/wireless/wl12xx/wl1271*
+ WL1271 WIRELESS DRIVER
+ M:    Luciano Coelho <luciano.coelho@nokia.com>
+ L:    linux-wireless@vger.kernel.org
+ W:    http://wireless.kernel.org
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
+ S:    Maintained
+ F:    drivers/net/wireless/wl12xx/wl1271*
  WL3501 WIRELESS PCMCIA CARD DRIVER
  M:    Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
  L:    linux-wireless@vger.kernel.org
index aed94869ad6a6436b5d4848acb322d8900baf6ff,3762f6c789448c28ba996b4f86411c59174faaee..e7061138c98a03ec15b51eca77877144a9ddd9b9
@@@ -121,7 -121,7 +121,7 @@@ SIGN2(sys32_syslog, sys_syslog, %o0, %o
  SIGN1(sys32_umask, sys_umask, %o0)
  SIGN3(sys32_tgkill, sys_tgkill, %o0, %o1, %o2)
  SIGN1(sys32_sendto, sys_sendto, %o0)
- SIGN1(sys32_recvfrom, sys_recvfrom, %o0)
+ SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0)
  SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2)
  SIGN2(sys32_connect, sys_connect, %o0, %o2)
  SIGN2(sys32_bind, sys_bind, %o0, %o2)
@@@ -134,12 -134,10 +134,12 @@@ SIGN1(sys32_getpeername, sys_getpeernam
  SIGN1(sys32_getsockname, sys_getsockname, %o0)
  SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1)
  SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2)
 -SIGN2(sys32_splice, sys_splice, %o0, %o1)
 +SIGN2(sys32_splice, sys_splice, %o0, %o2)
  SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5)
  SIGN2(sys32_tee, sys_tee, %o0, %o1)
  SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0)
 +SIGN1(sys32_truncate, sys_truncate, %o1)
 +SIGN1(sys32_ftruncate, sys_ftruncate, %o1)
  
        .globl          sys32_mmap2
  sys32_mmap2:
index 8250740c94b09bce8f5c73c6928d895cd24a28c3,8c5d2842fbb5986c46774c19937e158d09497027..c61fd2b4a5563c62d18393a479f29bd72c3eae8e
@@@ -86,7 -86,11 +86,7 @@@ MODULE_DEVICE_TABLE(pci, c2_pci_table)
  
  static void c2_print_macaddr(struct net_device *netdev)
  {
 -      pr_debug("%s: MAC %02X:%02X:%02X:%02X:%02X:%02X, "
 -              "IRQ %u\n", netdev->name,
 -              netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
 -              netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5],
 -              netdev->irq);
 +      pr_debug("%s: MAC %pM, IRQ %u\n", netdev->name, netdev->dev_addr, netdev->irq);
  }
  
  static void c2_set_rxbufsize(struct c2_port *c2_port)
@@@ -526,7 -530,6 +526,6 @@@ static void c2_rx_interrupt(struct net_
  
                netif_rx(skb);
  
-               netdev->last_rx = jiffies;
                netdev->stats.rx_packets++;
                netdev->stats.rx_bytes += buflen;
        }
index 63a1a8e1e8a3d2f28631d7674188657deb2bf1f4,97d4c2a33ed623e054204c57db1fca19fada2a9b..3512d6de3019806cca3b189e32734d3e039f2cfb
@@@ -74,8 -74,6 +74,8 @@@ static void nes_process_iwarp_aeqe(stru
  static void process_critical_error(struct nes_device *nesdev);
  static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number);
  static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_Mode);
 +static void nes_terminate_timeout(unsigned long context);
 +static void nes_terminate_start_timer(struct nes_qp *nesqp);
  
  #ifdef CONFIG_INFINIBAND_NES_DEBUG
  static unsigned char *nes_iwarp_state_str[] = {
@@@ -2743,7 -2741,7 +2743,7 @@@ void nes_nic_ce_handler(struct nes_devi
                                }
  
  skip_rx_indicate0:
-                               nesvnic->netdev->last_rx = jiffies;
+                               ;
                                /* nesvnic->netstats.rx_packets++; */
                                /* nesvnic->netstats.rx_bytes += rx_pkt_size; */
                        }
@@@ -2905,417 -2903,6 +2905,417 @@@ static void nes_cqp_ce_handler(struct n
  }
  
  
 +static u8 *locate_mpa(u8 *pkt, u32 aeq_info)
 +{
 +      u16 pkt_len;
 +
 +      if (aeq_info & NES_AEQE_Q2_DATA_ETHERNET) {
 +              /* skip over ethernet header */
 +              pkt_len = be16_to_cpu(*(u16 *)(pkt + ETH_HLEN - 2));
 +              pkt += ETH_HLEN;
 +
 +              /* Skip over IP and TCP headers */
 +              pkt += 4 * (pkt[0] & 0x0f);
 +              pkt += 4 * ((pkt[12] >> 4) & 0x0f);
 +      }
 +      return pkt;
 +}
 +
 +/* Determine if incoming error pkt is rdma layer */
 +static u32 iwarp_opcode(struct nes_qp *nesqp, u32 aeq_info)
 +{
 +      u8 *pkt;
 +      u16 *mpa;
 +      u32 opcode = 0xffffffff;
 +
 +      if (aeq_info & NES_AEQE_Q2_DATA_WRITTEN) {
 +              pkt = nesqp->hwqp.q2_vbase + BAD_FRAME_OFFSET;
 +              mpa = (u16 *)locate_mpa(pkt, aeq_info);
 +              opcode = be16_to_cpu(mpa[1]) & 0xf;
 +      }
 +
 +      return opcode;
 +}
 +
 +/* Build iWARP terminate header */
 +static int nes_bld_terminate_hdr(struct nes_qp *nesqp, u16 async_event_id, u32 aeq_info)
 +{
 +      u8 *pkt = nesqp->hwqp.q2_vbase + BAD_FRAME_OFFSET;
 +      u16 ddp_seg_len;
 +      int copy_len = 0;
 +      u8 is_tagged = 0;
 +      u8 flush_code = 0;
 +      struct nes_terminate_hdr *termhdr;
 +
 +      termhdr = (struct nes_terminate_hdr *)nesqp->hwqp.q2_vbase;
 +      memset(termhdr, 0, 64);
 +
 +      if (aeq_info & NES_AEQE_Q2_DATA_WRITTEN) {
 +
 +              /* Use data from offending packet to fill in ddp & rdma hdrs */
 +              pkt = locate_mpa(pkt, aeq_info);
 +              ddp_seg_len = be16_to_cpu(*(u16 *)pkt);
 +              if (ddp_seg_len) {
 +                      copy_len = 2;
 +                      termhdr->hdrct = DDP_LEN_FLAG;
 +                      if (pkt[2] & 0x80) {
 +                              is_tagged = 1;
 +                              if (ddp_seg_len >= TERM_DDP_LEN_TAGGED) {
 +                                      copy_len += TERM_DDP_LEN_TAGGED;
 +                                      termhdr->hdrct |= DDP_HDR_FLAG;
 +                              }
 +                      } else {
 +                              if (ddp_seg_len >= TERM_DDP_LEN_UNTAGGED) {
 +                                      copy_len += TERM_DDP_LEN_UNTAGGED;
 +                                      termhdr->hdrct |= DDP_HDR_FLAG;
 +                              }
 +
 +                              if (ddp_seg_len >= (TERM_DDP_LEN_UNTAGGED + TERM_RDMA_LEN)) {
 +                                      if ((pkt[3] & RDMA_OPCODE_MASK) == RDMA_READ_REQ_OPCODE) {
 +                                              copy_len += TERM_RDMA_LEN;
 +                                              termhdr->hdrct |= RDMA_HDR_FLAG;
 +                                      }
 +                              }
 +                      }
 +              }
 +      }
 +
 +      switch (async_event_id) {
 +      case NES_AEQE_AEID_AMP_UNALLOCATED_STAG:
 +              switch (iwarp_opcode(nesqp, aeq_info)) {
 +              case IWARP_OPCODE_WRITE:
 +                      flush_code = IB_WC_LOC_PROT_ERR;
 +                      termhdr->layer_etype = (LAYER_DDP << 4) | DDP_TAGGED_BUFFER;
 +                      termhdr->error_code = DDP_TAGGED_INV_STAG;
 +                      break;
 +              default:
 +                      flush_code = IB_WC_REM_ACCESS_ERR;
 +                      termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT;
 +                      termhdr->error_code = RDMAP_INV_STAG;
 +              }
 +              break;
 +      case NES_AEQE_AEID_AMP_INVALID_STAG:
 +              flush_code = IB_WC_REM_ACCESS_ERR;
 +              termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT;
 +              termhdr->error_code = RDMAP_INV_STAG;
 +              break;
 +      case NES_AEQE_AEID_AMP_BAD_QP:
 +              flush_code = IB_WC_LOC_QP_OP_ERR;
 +              termhdr->layer_etype = (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER;
 +              termhdr->error_code = DDP_UNTAGGED_INV_QN;
 +              break;
 +      case NES_AEQE_AEID_AMP_BAD_STAG_KEY:
 +      case NES_AEQE_AEID_AMP_BAD_STAG_INDEX:
 +              switch (iwarp_opcode(nesqp, aeq_info)) {
 +              case IWARP_OPCODE_SEND_INV:
 +              case IWARP_OPCODE_SEND_SE_INV:
 +                      flush_code = IB_WC_REM_OP_ERR;
 +                      termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_OP;
 +                      termhdr->error_code = RDMAP_CANT_INV_STAG;
 +                      break;
 +              default:
 +                      flush_code = IB_WC_REM_ACCESS_ERR;
 +                      termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT;
 +                      termhdr->error_code = RDMAP_INV_STAG;
 +              }
 +              break;
 +      case NES_AEQE_AEID_AMP_BOUNDS_VIOLATION:
 +              if (aeq_info & (NES_AEQE_Q2_DATA_ETHERNET | NES_AEQE_Q2_DATA_MPA)) {
 +                      flush_code = IB_WC_LOC_PROT_ERR;
 +                      termhdr->layer_etype = (LAYER_DDP << 4) | DDP_TAGGED_BUFFER;
 +                      termhdr->error_code = DDP_TAGGED_BOUNDS;
 +              } else {
 +                      flush_code = IB_WC_REM_ACCESS_ERR;
 +                      termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT;
 +                      termhdr->error_code = RDMAP_INV_BOUNDS;
 +              }
 +              break;
 +      case NES_AEQE_AEID_AMP_RIGHTS_VIOLATION:
 +      case NES_AEQE_AEID_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS:
 +      case NES_AEQE_AEID_PRIV_OPERATION_DENIED:
 +              flush_code = IB_WC_REM_ACCESS_ERR;
 +              termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT;
 +              termhdr->error_code = RDMAP_ACCESS;
 +              break;
 +      case NES_AEQE_AEID_AMP_TO_WRAP:
 +              flush_code = IB_WC_REM_ACCESS_ERR;
 +              termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT;
 +              termhdr->error_code = RDMAP_TO_WRAP;
 +              break;
 +      case NES_AEQE_AEID_AMP_BAD_PD:
 +              switch (iwarp_opcode(nesqp, aeq_info)) {
 +              case IWARP_OPCODE_WRITE:
 +                      flush_code = IB_WC_LOC_PROT_ERR;
 +                      termhdr->layer_etype = (LAYER_DDP << 4) | DDP_TAGGED_BUFFER;
 +                      termhdr->error_code = DDP_TAGGED_UNASSOC_STAG;
 +                      break;
 +              case IWARP_OPCODE_SEND_INV:
 +              case IWARP_OPCODE_SEND_SE_INV:
 +                      flush_code = IB_WC_REM_ACCESS_ERR;
 +                      termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT;
 +                      termhdr->error_code = RDMAP_CANT_INV_STAG;
 +                      break;
 +              default:
 +                      flush_code = IB_WC_REM_ACCESS_ERR;
 +                      termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_PROT;
 +                      termhdr->error_code = RDMAP_UNASSOC_STAG;
 +              }
 +              break;
 +      case NES_AEQE_AEID_LLP_RECEIVED_MARKER_AND_LENGTH_FIELDS_DONT_MATCH:
 +              flush_code = IB_WC_LOC_LEN_ERR;
 +              termhdr->layer_etype = (LAYER_MPA << 4) | DDP_LLP;
 +              termhdr->error_code = MPA_MARKER;
 +              break;
 +      case NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR:
 +              flush_code = IB_WC_GENERAL_ERR;
 +              termhdr->layer_etype = (LAYER_MPA << 4) | DDP_LLP;
 +              termhdr->error_code = MPA_CRC;
 +              break;
 +      case NES_AEQE_AEID_LLP_SEGMENT_TOO_LARGE:
 +      case NES_AEQE_AEID_LLP_SEGMENT_TOO_SMALL:
 +              flush_code = IB_WC_LOC_LEN_ERR;
 +              termhdr->layer_etype = (LAYER_DDP << 4) | DDP_CATASTROPHIC;
 +              termhdr->error_code = DDP_CATASTROPHIC_LOCAL;
 +              break;
 +      case NES_AEQE_AEID_DDP_LCE_LOCAL_CATASTROPHIC:
 +      case NES_AEQE_AEID_DDP_NO_L_BIT:
 +              flush_code = IB_WC_FATAL_ERR;
 +              termhdr->layer_etype = (LAYER_DDP << 4) | DDP_CATASTROPHIC;
 +              termhdr->error_code = DDP_CATASTROPHIC_LOCAL;
 +              break;
 +      case NES_AEQE_AEID_DDP_INVALID_MSN_GAP_IN_MSN:
 +      case NES_AEQE_AEID_DDP_INVALID_MSN_RANGE_IS_NOT_VALID:
 +              flush_code = IB_WC_GENERAL_ERR;
 +              termhdr->layer_etype = (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER;
 +              termhdr->error_code = DDP_UNTAGGED_INV_MSN_RANGE;
 +              break;
 +      case NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
 +              flush_code = IB_WC_LOC_LEN_ERR;
 +              termhdr->layer_etype = (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER;
 +              termhdr->error_code = DDP_UNTAGGED_INV_TOO_LONG;
 +              break;
 +      case NES_AEQE_AEID_DDP_UBE_INVALID_DDP_VERSION:
 +              flush_code = IB_WC_GENERAL_ERR;
 +              if (is_tagged) {
 +                      termhdr->layer_etype = (LAYER_DDP << 4) | DDP_TAGGED_BUFFER;
 +                      termhdr->error_code = DDP_TAGGED_INV_DDP_VER;
 +              } else {
 +                      termhdr->layer_etype = (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER;
 +                      termhdr->error_code = DDP_UNTAGGED_INV_DDP_VER;
 +              }
 +              break;
 +      case NES_AEQE_AEID_DDP_UBE_INVALID_MO:
 +              flush_code = IB_WC_GENERAL_ERR;
 +              termhdr->layer_etype = (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER;
 +              termhdr->error_code = DDP_UNTAGGED_INV_MO;
 +              break;
 +      case NES_AEQE_AEID_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE:
 +              flush_code = IB_WC_REM_OP_ERR;
 +              termhdr->layer_etype = (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER;
 +              termhdr->error_code = DDP_UNTAGGED_INV_MSN_NO_BUF;
 +              break;
 +      case NES_AEQE_AEID_DDP_UBE_INVALID_QN:
 +              flush_code = IB_WC_GENERAL_ERR;
 +              termhdr->layer_etype = (LAYER_DDP << 4) | DDP_UNTAGGED_BUFFER;
 +              termhdr->error_code = DDP_UNTAGGED_INV_QN;
 +              break;
 +      case NES_AEQE_AEID_RDMAP_ROE_INVALID_RDMAP_VERSION:
 +              flush_code = IB_WC_GENERAL_ERR;
 +              termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_OP;
 +              termhdr->error_code = RDMAP_INV_RDMAP_VER;
 +              break;
 +      case NES_AEQE_AEID_RDMAP_ROE_UNEXPECTED_OPCODE:
 +              flush_code = IB_WC_LOC_QP_OP_ERR;
 +              termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_OP;
 +              termhdr->error_code = RDMAP_UNEXPECTED_OP;
 +              break;
 +      default:
 +              flush_code = IB_WC_FATAL_ERR;
 +              termhdr->layer_etype = (LAYER_RDMA << 4) | RDMAP_REMOTE_OP;
 +              termhdr->error_code = RDMAP_UNSPECIFIED;
 +              break;
 +      }
 +
 +      if (copy_len)
 +              memcpy(termhdr + 1, pkt, copy_len);
 +
 +      if ((flush_code) && ((NES_AEQE_INBOUND_RDMA & aeq_info) == 0)) {
 +              if (aeq_info & NES_AEQE_SQ)
 +                      nesqp->term_sq_flush_code = flush_code;
 +              else
 +                      nesqp->term_rq_flush_code = flush_code;
 +      }
 +
 +      return sizeof(struct nes_terminate_hdr) + copy_len;
 +}
 +
 +static void nes_terminate_connection(struct nes_device *nesdev, struct nes_qp *nesqp,
 +               struct nes_hw_aeqe *aeqe, enum ib_event_type eventtype)
 +{
 +      u64 context;
 +      unsigned long flags;
 +      u32 aeq_info;
 +      u16 async_event_id;
 +      u8 tcp_state;
 +      u8 iwarp_state;
 +      u32 termlen = 0;
 +      u32 mod_qp_flags = NES_CQP_QP_IWARP_STATE_TERMINATE |
 +                         NES_CQP_QP_TERM_DONT_SEND_FIN;
 +      struct nes_adapter *nesadapter = nesdev->nesadapter;
 +
 +      if (nesqp->term_flags & NES_TERM_SENT)
 +              return; /* Sanity check */
 +
 +      aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]);
 +      tcp_state = (aeq_info & NES_AEQE_TCP_STATE_MASK) >> NES_AEQE_TCP_STATE_SHIFT;
 +      iwarp_state = (aeq_info & NES_AEQE_IWARP_STATE_MASK) >> NES_AEQE_IWARP_STATE_SHIFT;
 +      async_event_id = (u16)aeq_info;
 +
 +      context = (unsigned long)nesadapter->qp_table[le32_to_cpu(
 +              aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]) - NES_FIRST_QPN];
 +      if (!context) {
 +              WARN_ON(!context);
 +              return;
 +      }
 +
 +      nesqp = (struct nes_qp *)(unsigned long)context;
 +      spin_lock_irqsave(&nesqp->lock, flags);
 +      nesqp->hw_iwarp_state = iwarp_state;
 +      nesqp->hw_tcp_state = tcp_state;
 +      nesqp->last_aeq = async_event_id;
 +      nesqp->terminate_eventtype = eventtype;
 +      spin_unlock_irqrestore(&nesqp->lock, flags);
 +
 +      if (nesadapter->send_term_ok)
 +              termlen = nes_bld_terminate_hdr(nesqp, async_event_id, aeq_info);
 +      else
 +              mod_qp_flags |= NES_CQP_QP_TERM_DONT_SEND_TERM_MSG;
 +
 +      nes_terminate_start_timer(nesqp);
 +      nesqp->term_flags |= NES_TERM_SENT;
 +      nes_hw_modify_qp(nesdev, nesqp, mod_qp_flags, termlen, 0);
 +}
 +
 +static void nes_terminate_send_fin(struct nes_device *nesdev,
 +                        struct nes_qp *nesqp, struct nes_hw_aeqe *aeqe)
 +{
 +      u32 aeq_info;
 +      u16 async_event_id;
 +      u8 tcp_state;
 +      u8 iwarp_state;
 +      unsigned long flags;
 +
 +      aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]);
 +      tcp_state = (aeq_info & NES_AEQE_TCP_STATE_MASK) >> NES_AEQE_TCP_STATE_SHIFT;
 +      iwarp_state = (aeq_info & NES_AEQE_IWARP_STATE_MASK) >> NES_AEQE_IWARP_STATE_SHIFT;
 +      async_event_id = (u16)aeq_info;
 +
 +      spin_lock_irqsave(&nesqp->lock, flags);
 +      nesqp->hw_iwarp_state = iwarp_state;
 +      nesqp->hw_tcp_state = tcp_state;
 +      nesqp->last_aeq = async_event_id;
 +      spin_unlock_irqrestore(&nesqp->lock, flags);
 +
 +      /* Send the fin only */
 +      nes_hw_modify_qp(nesdev, nesqp, NES_CQP_QP_IWARP_STATE_TERMINATE |
 +              NES_CQP_QP_TERM_DONT_SEND_TERM_MSG, 0, 0);
 +}
 +
 +/* Cleanup after a terminate sent or received */
 +static void nes_terminate_done(struct nes_qp *nesqp, int timeout_occurred)
 +{
 +      u32 next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR;
 +      unsigned long flags;
 +      struct nes_vnic *nesvnic = to_nesvnic(nesqp->ibqp.device);
 +      struct nes_device *nesdev = nesvnic->nesdev;
 +      u8 first_time = 0;
 +
 +      spin_lock_irqsave(&nesqp->lock, flags);
 +      if (nesqp->hte_added) {
 +              nesqp->hte_added = 0;
 +              next_iwarp_state |= NES_CQP_QP_DEL_HTE;
 +      }
 +
 +      first_time = (nesqp->term_flags & NES_TERM_DONE) == 0;
 +      nesqp->term_flags |= NES_TERM_DONE;
 +      spin_unlock_irqrestore(&nesqp->lock, flags);
 +
 +      /* Make sure we go through this only once */
 +      if (first_time) {
 +              if (timeout_occurred == 0)
 +                      del_timer(&nesqp->terminate_timer);
 +              else
 +                      next_iwarp_state |= NES_CQP_QP_RESET;
 +
 +              nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0, 0);
 +              nes_cm_disconn(nesqp);
 +      }
 +}
 +
 +static void nes_terminate_received(struct nes_device *nesdev,
 +                              struct nes_qp *nesqp, struct nes_hw_aeqe *aeqe)
 +{
 +      u32 aeq_info;
 +      u8 *pkt;
 +      u32 *mpa;
 +      u8 ddp_ctl;
 +      u8 rdma_ctl;
 +      u16 aeq_id = 0;
 +
 +      aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]);
 +      if (aeq_info & NES_AEQE_Q2_DATA_WRITTEN) {
 +              /* Terminate is not a performance path so the silicon */
 +              /* did not validate the frame - do it now */
 +              pkt = nesqp->hwqp.q2_vbase + BAD_FRAME_OFFSET;
 +              mpa = (u32 *)locate_mpa(pkt, aeq_info);
 +              ddp_ctl = (be32_to_cpu(mpa[0]) >> 8) & 0xff;
 +              rdma_ctl = be32_to_cpu(mpa[0]) & 0xff;
 +              if ((ddp_ctl & 0xc0) != 0x40)
 +                      aeq_id = NES_AEQE_AEID_DDP_LCE_LOCAL_CATASTROPHIC;
 +              else if ((ddp_ctl & 0x03) != 1)
 +                      aeq_id = NES_AEQE_AEID_DDP_UBE_INVALID_DDP_VERSION;
 +              else if (be32_to_cpu(mpa[2]) != 2)
 +                      aeq_id = NES_AEQE_AEID_DDP_UBE_INVALID_QN;
 +              else if (be32_to_cpu(mpa[3]) != 1)
 +                      aeq_id = NES_AEQE_AEID_DDP_INVALID_MSN_GAP_IN_MSN;
 +              else if (be32_to_cpu(mpa[4]) != 0)
 +                      aeq_id = NES_AEQE_AEID_DDP_UBE_INVALID_MO;
 +              else if ((rdma_ctl & 0xc0) != 0x40)
 +                      aeq_id = NES_AEQE_AEID_RDMAP_ROE_INVALID_RDMAP_VERSION;
 +
 +              if (aeq_id) {
 +                      /* Bad terminate recvd - send back a terminate */
 +                      aeq_info = (aeq_info & 0xffff0000) | aeq_id;
 +                      aeqe->aeqe_words[NES_AEQE_MISC_IDX] = cpu_to_le32(aeq_info);
 +                      nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_FATAL);
 +                      return;
 +              }
 +      }
 +
 +      nesqp->term_flags |= NES_TERM_RCVD;
 +      nesqp->terminate_eventtype = IB_EVENT_QP_FATAL;
 +      nes_terminate_start_timer(nesqp);
 +      nes_terminate_send_fin(nesdev, nesqp, aeqe);
 +}
 +
 +/* Timeout routine in case terminate fails to complete */
 +static void nes_terminate_timeout(unsigned long context)
 +{
 +      struct nes_qp *nesqp = (struct nes_qp *)(unsigned long)context;
 +
 +      nes_terminate_done(nesqp, 1);
 +}
 +
 +/* Set a timer in case hw cannot complete the terminate sequence */
 +static void nes_terminate_start_timer(struct nes_qp *nesqp)
 +{
 +      init_timer(&nesqp->terminate_timer);
 +      nesqp->terminate_timer.function = nes_terminate_timeout;
 +      nesqp->terminate_timer.expires = jiffies + HZ;
 +      nesqp->terminate_timer.data = (unsigned long)nesqp;
 +      add_timer(&nesqp->terminate_timer);
 +}
 +
  /**
   * nes_process_iwarp_aeqe
   */
@@@ -3323,27 -2910,28 +3323,27 @@@ static void nes_process_iwarp_aeqe(stru
                                   struct nes_hw_aeqe *aeqe)
  {
        u64 context;
 -      u64 aeqe_context = 0;
        unsigned long flags;
        struct nes_qp *nesqp;
 +      struct nes_hw_cq *hw_cq;
 +      struct nes_cq *nescq;
        int resource_allocated;
 -      /* struct iw_cm_id *cm_id; */
        struct nes_adapter *nesadapter = nesdev->nesadapter;
 -      struct ib_event ibevent;
 -      /* struct iw_cm_event cm_event; */
        u32 aeq_info;
        u32 next_iwarp_state = 0;
        u16 async_event_id;
        u8 tcp_state;
        u8 iwarp_state;
 +      int must_disconn = 1;
 +      int must_terminate = 0;
 +      struct ib_event ibevent;
  
        nes_debug(NES_DBG_AEQ, "\n");
        aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]);
 -      if ((NES_AEQE_INBOUND_RDMA&aeq_info) || (!(NES_AEQE_QP&aeq_info))) {
 +      if ((NES_AEQE_INBOUND_RDMA & aeq_info) || (!(NES_AEQE_QP & aeq_info))) {
                context  = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]);
                context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32;
        } else {
 -              aeqe_context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]);
 -              aeqe_context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32;
                context = (unsigned long)nesadapter->qp_table[le32_to_cpu(
                                                aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]) - NES_FIRST_QPN];
                BUG_ON(!context);
  
        switch (async_event_id) {
                case NES_AEQE_AEID_LLP_FIN_RECEIVED:
 -                      nesqp = *((struct nes_qp **)&context);
 +                      nesqp = (struct nes_qp *)(unsigned long)context;
 +
 +                      if (nesqp->term_flags)
 +                              return; /* Ignore it, wait for close complete */
 +
                        if (atomic_inc_return(&nesqp->close_timer_started) == 1) {
                                nesqp->cm_id->add_ref(nesqp->cm_id);
                                schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp,
                                                nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount),
                                                async_event_id, nesqp->last_aeq, tcp_state);
                        }
 +
                        if ((tcp_state != NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
                                        (nesqp->ibqp_state != IB_QPS_RTS)) {
                                /* FIN Received but tcp state or IB state moved on,
                                                should expect a close complete */
                                return;
                        }
 +
                case NES_AEQE_AEID_LLP_CLOSE_COMPLETE:
 +                      nesqp = (struct nes_qp *)(unsigned long)context;
 +                      if (nesqp->term_flags) {
 +                              nes_terminate_done(nesqp, 0);
 +                              return;
 +                      }
 +
                case NES_AEQE_AEID_LLP_CONNECTION_RESET:
 -              case NES_AEQE_AEID_TERMINATE_SENT:
 -              case NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE:
                case NES_AEQE_AEID_RESET_SENT:
 -                      nesqp = *((struct nes_qp **)&context);
 +                      nesqp = (struct nes_qp *)(unsigned long)context;
                        if (async_event_id == NES_AEQE_AEID_RESET_SENT) {
                                tcp_state = NES_AEQE_TCP_STATE_CLOSED;
                        }
                        if ((tcp_state == NES_AEQE_TCP_STATE_CLOSED) ||
                                        (tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT)) {
                                nesqp->hte_added = 0;
 -                              spin_unlock_irqrestore(&nesqp->lock, flags);
 -                              nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u to remove hte\n",
 -                                              nesqp->hwqp.qp_id);
 -                              nes_hw_modify_qp(nesdev, nesqp,
 -                                              NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_DEL_HTE, 0);
 -                              spin_lock_irqsave(&nesqp->lock, flags);
 +                              next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_DEL_HTE;
                        }
  
                        if ((nesqp->ibqp_state == IB_QPS_RTS) &&
                                                nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING;
                                                break;
                                        case NES_AEQE_IWARP_STATE_TERMINATE:
 -                                              next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE;
 -                                              nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_TERMINATE;
 -                                              if (async_event_id == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) {
 -                                                      next_iwarp_state |= 0x02000000;
 -                                                      nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
 -                                              }
 +                                              must_disconn = 0; /* terminate path takes care of disconn */
 +                                              if (nesqp->term_flags == 0)
 +                                                      must_terminate = 1;
                                                break;
 -                                      default:
 -                                              next_iwarp_state = 0;
 -                              }
 -                              spin_unlock_irqrestore(&nesqp->lock, flags);
 -                              if (next_iwarp_state) {
 -                                      nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X,"
 -                                                      " also added another reference\n",
 -                                                      nesqp->hwqp.qp_id, next_iwarp_state);
 -                                      nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0);
                                }
 -                              nes_cm_disconn(nesqp);
                        } else {
                                if (async_event_id ==  NES_AEQE_AEID_LLP_FIN_RECEIVED) {
                                        /* FIN Received but ib state not RTS,
                                                        close complete will be on its way */
 -                                      spin_unlock_irqrestore(&nesqp->lock, flags);
 -                                      return;
 -                              }
 -                              spin_unlock_irqrestore(&nesqp->lock, flags);
 -                              if (async_event_id == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) {
 -                                      next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000;
 -                                      nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
 -                                      nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X,"
 -                                                      " also added another reference\n",
 -                                                      nesqp->hwqp.qp_id, next_iwarp_state);
 -                                      nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0);
 +                                      must_disconn = 0;
                                }
 -                              nes_cm_disconn(nesqp);
                        }
 -                      break;
 -              case NES_AEQE_AEID_LLP_TERMINATE_RECEIVED:
 -                      nesqp = *((struct nes_qp **)&context);
 -                      spin_lock_irqsave(&nesqp->lock, flags);
 -                      nesqp->hw_iwarp_state = iwarp_state;
 -                      nesqp->hw_tcp_state = tcp_state;
 -                      nesqp->last_aeq = async_event_id;
                        spin_unlock_irqrestore(&nesqp->lock, flags);
 -                      nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TERMINATE_RECEIVED"
 -                                      " event on QP%u \n  Q2 Data:\n",
 -                                      nesqp->hwqp.qp_id);
 -                      if (nesqp->ibqp.event_handler) {
 -                              ibevent.device = nesqp->ibqp.device;
 -                              ibevent.element.qp = &nesqp->ibqp;
 -                              ibevent.event = IB_EVENT_QP_FATAL;
 -                              nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
 -                      }
 -                      if ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
 -                                      ((nesqp->ibqp_state == IB_QPS_RTS)&&
 -                                      (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
 +
 +                      if (must_terminate)
 +                              nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_FATAL);
 +                      else if (must_disconn) {
 +                              if (next_iwarp_state) {
 +                                      nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X\n",
 +                                                nesqp->hwqp.qp_id, next_iwarp_state);
 +                                      nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0, 0);
 +                              }
                                nes_cm_disconn(nesqp);
 -                      } else {
 -                              nesqp->in_disconnect = 0;
 -                              wake_up(&nesqp->kick_waitq);
                        }
                        break;
 -              case NES_AEQE_AEID_LLP_TOO_MANY_RETRIES:
 -                      nesqp = *((struct nes_qp **)&context);
 -                      spin_lock_irqsave(&nesqp->lock, flags);
 -                      nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_ERROR;
 -                      nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
 -                      nesqp->last_aeq = async_event_id;
 -                      if (nesqp->cm_id) {
 -                              nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TOO_MANY_RETRIES"
 -                                              " event on QP%u, remote IP = 0x%08X \n",
 -                                              nesqp->hwqp.qp_id,
 -                                              ntohl(nesqp->cm_id->remote_addr.sin_addr.s_addr));
 -                      } else {
 -                              nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TOO_MANY_RETRIES"
 -                                              " event on QP%u \n",
 -                                              nesqp->hwqp.qp_id);
 -                      }
 -                      spin_unlock_irqrestore(&nesqp->lock, flags);
 -                      next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_RESET;
 -                      nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0);
 -                      if (nesqp->ibqp.event_handler) {
 -                              ibevent.device = nesqp->ibqp.device;
 -                              ibevent.element.qp = &nesqp->ibqp;
 -                              ibevent.event = IB_EVENT_QP_FATAL;
 -                              nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
 -                      }
 +
 +              case NES_AEQE_AEID_TERMINATE_SENT:
 +                      nesqp = (struct nes_qp *)(unsigned long)context;
 +                      nes_terminate_send_fin(nesdev, nesqp, aeqe);
                        break;
 -              case NES_AEQE_AEID_AMP_BAD_STAG_INDEX:
 -                      if (NES_AEQE_INBOUND_RDMA&aeq_info) {
 -                              nesqp = nesadapter->qp_table[le32_to_cpu(
 -                                              aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN];
 -                      } else {
 -                              /* TODO: get the actual WQE and mask off wqe index */
 -                              context &= ~((u64)511);
 -                              nesqp = *((struct nes_qp **)&context);
 -                      }
 -                      spin_lock_irqsave(&nesqp->lock, flags);
 -                      nesqp->hw_iwarp_state = iwarp_state;
 -                      nesqp->hw_tcp_state = tcp_state;
 -                      nesqp->last_aeq = async_event_id;
 -                      spin_unlock_irqrestore(&nesqp->lock, flags);
 -                      nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_AMP_BAD_STAG_INDEX event on QP%u\n",
 -                                      nesqp->hwqp.qp_id);
 -                      if (nesqp->ibqp.event_handler) {
 -                              ibevent.device = nesqp->ibqp.device;
 -                              ibevent.element.qp = &nesqp->ibqp;
 -                              ibevent.event = IB_EVENT_QP_ACCESS_ERR;
 -                              nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
 -                      }
 +
 +              case NES_AEQE_AEID_LLP_TERMINATE_RECEIVED:
 +                      nesqp = (struct nes_qp *)(unsigned long)context;
 +                      nes_terminate_received(nesdev, nesqp, aeqe);
                        break;
 +
 +              case NES_AEQE_AEID_AMP_BAD_STAG_KEY:
 +              case NES_AEQE_AEID_AMP_BAD_STAG_INDEX:
                case NES_AEQE_AEID_AMP_UNALLOCATED_STAG:
 -                      nesqp = *((struct nes_qp **)&context);
 -                      spin_lock_irqsave(&nesqp->lock, flags);
 -                      nesqp->hw_iwarp_state = iwarp_state;
 -                      nesqp->hw_tcp_state = tcp_state;
 -                      nesqp->last_aeq = async_event_id;
 -                      spin_unlock_irqrestore(&nesqp->lock, flags);
 -                      nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_AMP_UNALLOCATED_STAG event on QP%u\n",
 -                                      nesqp->hwqp.qp_id);
 -                      if (nesqp->ibqp.event_handler) {
 -                              ibevent.device = nesqp->ibqp.device;
 -                              ibevent.element.qp = &nesqp->ibqp;
 -                              ibevent.event = IB_EVENT_QP_ACCESS_ERR;
 -                              nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
 -                      }
 -                      break;
 +              case NES_AEQE_AEID_AMP_INVALID_STAG:
 +              case NES_AEQE_AEID_AMP_RIGHTS_VIOLATION:
 +              case NES_AEQE_AEID_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS:
                case NES_AEQE_AEID_PRIV_OPERATION_DENIED:
 -                      nesqp = nesadapter->qp_table[le32_to_cpu(aeqe->aeqe_words
 -                                      [NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN];
 -                      spin_lock_irqsave(&nesqp->lock, flags);
 -                      nesqp->hw_iwarp_state = iwarp_state;
 -                      nesqp->hw_tcp_state = tcp_state;
 -                      nesqp->last_aeq = async_event_id;
 -                      spin_unlock_irqrestore(&nesqp->lock, flags);
 -                      nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_PRIV_OPERATION_DENIED event on QP%u,"
 -                                      " nesqp = %p, AE reported %p\n",
 -                                      nesqp->hwqp.qp_id, nesqp, *((struct nes_qp **)&context));
 -                      if (nesqp->ibqp.event_handler) {
 -                              ibevent.device = nesqp->ibqp.device;
 -                              ibevent.element.qp = &nesqp->ibqp;
 -                              ibevent.event = IB_EVENT_QP_ACCESS_ERR;
 -                              nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
 +              case NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
 +              case NES_AEQE_AEID_AMP_BOUNDS_VIOLATION:
 +              case NES_AEQE_AEID_AMP_TO_WRAP:
 +                      nesqp = (struct nes_qp *)(unsigned long)context;
 +                      nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_ACCESS_ERR);
 +                      break;
 +
 +              case NES_AEQE_AEID_LLP_SEGMENT_TOO_LARGE:
 +              case NES_AEQE_AEID_LLP_SEGMENT_TOO_SMALL:
 +              case NES_AEQE_AEID_DDP_UBE_INVALID_MO:
 +              case NES_AEQE_AEID_DDP_UBE_INVALID_QN:
 +                      nesqp = (struct nes_qp *)(unsigned long)context;
 +                      if (iwarp_opcode(nesqp, aeq_info) > IWARP_OPCODE_TERM) {
 +                              aeq_info &= 0xffff0000;
 +                              aeq_info |= NES_AEQE_AEID_RDMAP_ROE_UNEXPECTED_OPCODE;
 +                              aeqe->aeqe_words[NES_AEQE_MISC_IDX] = cpu_to_le32(aeq_info);
                        }
 +
 +              case NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE:
 +              case NES_AEQE_AEID_LLP_TOO_MANY_RETRIES:
 +              case NES_AEQE_AEID_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE:
 +              case NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR:
 +              case NES_AEQE_AEID_AMP_BAD_QP:
 +              case NES_AEQE_AEID_LLP_RECEIVED_MARKER_AND_LENGTH_FIELDS_DONT_MATCH:
 +              case NES_AEQE_AEID_DDP_LCE_LOCAL_CATASTROPHIC:
 +              case NES_AEQE_AEID_DDP_NO_L_BIT:
 +              case NES_AEQE_AEID_DDP_INVALID_MSN_GAP_IN_MSN:
 +              case NES_AEQE_AEID_DDP_INVALID_MSN_RANGE_IS_NOT_VALID:
 +              case NES_AEQE_AEID_DDP_UBE_INVALID_DDP_VERSION:
 +              case NES_AEQE_AEID_RDMAP_ROE_INVALID_RDMAP_VERSION:
 +              case NES_AEQE_AEID_RDMAP_ROE_UNEXPECTED_OPCODE:
 +              case NES_AEQE_AEID_AMP_BAD_PD:
 +              case NES_AEQE_AEID_AMP_FASTREG_SHARED:
 +              case NES_AEQE_AEID_AMP_FASTREG_VALID_STAG:
 +              case NES_AEQE_AEID_AMP_FASTREG_MW_STAG:
 +              case NES_AEQE_AEID_AMP_FASTREG_INVALID_RIGHTS:
 +              case NES_AEQE_AEID_AMP_FASTREG_PBL_TABLE_OVERFLOW:
 +              case NES_AEQE_AEID_AMP_FASTREG_INVALID_LENGTH:
 +              case NES_AEQE_AEID_AMP_INVALIDATE_SHARED:
 +              case NES_AEQE_AEID_AMP_INVALIDATE_MR_WITH_BOUND_WINDOWS:
 +              case NES_AEQE_AEID_AMP_MWBIND_VALID_STAG:
 +              case NES_AEQE_AEID_AMP_MWBIND_OF_MR_STAG:
 +              case NES_AEQE_AEID_AMP_MWBIND_TO_ZERO_BASED_STAG:
 +              case NES_AEQE_AEID_AMP_MWBIND_TO_MW_STAG:
 +              case NES_AEQE_AEID_AMP_MWBIND_INVALID_RIGHTS:
 +              case NES_AEQE_AEID_AMP_MWBIND_INVALID_BOUNDS:
 +              case NES_AEQE_AEID_AMP_MWBIND_TO_INVALID_PARENT:
 +              case NES_AEQE_AEID_AMP_MWBIND_BIND_DISABLED:
 +              case NES_AEQE_AEID_BAD_CLOSE:
 +              case NES_AEQE_AEID_RDMA_READ_WHILE_ORD_ZERO:
 +              case NES_AEQE_AEID_STAG_ZERO_INVALID:
 +              case NES_AEQE_AEID_ROE_INVALID_RDMA_READ_REQUEST:
 +              case NES_AEQE_AEID_ROE_INVALID_RDMA_WRITE_OR_READ_RESP:
 +                      nesqp = (struct nes_qp *)(unsigned long)context;
 +                      nes_terminate_connection(nesdev, nesqp, aeqe, IB_EVENT_QP_FATAL);
                        break;
 +
                case NES_AEQE_AEID_CQ_OPERATION_ERROR:
                        context <<= 1;
                        nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_CQ_OPERATION_ERROR event on CQ%u, %p\n",
                        if (resource_allocated) {
                                printk(KERN_ERR PFX "%s: Processing an NES_AEQE_AEID_CQ_OPERATION_ERROR event on CQ%u\n",
                                                __func__, le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]));
 +                              hw_cq = (struct nes_hw_cq *)(unsigned long)context;
 +                              if (hw_cq) {
 +                                      nescq = container_of(hw_cq, struct nes_cq, hw_cq);
 +                                      if (nescq->ibcq.event_handler) {
 +                                              ibevent.device = nescq->ibcq.device;
 +                                              ibevent.event = IB_EVENT_CQ_ERR;
 +                                              ibevent.element.cq = &nescq->ibcq;
 +                                              nescq->ibcq.event_handler(&ibevent, nescq->ibcq.cq_context);
 +                                      }
 +                              }
                        }
                        break;
 -              case NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
 -                      nesqp = nesadapter->qp_table[le32_to_cpu(
 -                                      aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN];
 -                      spin_lock_irqsave(&nesqp->lock, flags);
 -                      nesqp->hw_iwarp_state = iwarp_state;
 -                      nesqp->hw_tcp_state = tcp_state;
 -                      nesqp->last_aeq = async_event_id;
 -                      spin_unlock_irqrestore(&nesqp->lock, flags);
 -                      nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG"
 -                                      "_FOR_AVAILABLE_BUFFER event on QP%u\n",
 -                                      nesqp->hwqp.qp_id);
 -                      if (nesqp->ibqp.event_handler) {
 -                              ibevent.device = nesqp->ibqp.device;
 -                              ibevent.element.qp = &nesqp->ibqp;
 -                              ibevent.event = IB_EVENT_QP_ACCESS_ERR;
 -                              nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
 -                      }
 -                      /* tell cm to disconnect, cm will queue work to thread */
 -                      nes_cm_disconn(nesqp);
 -                      break;
 -              case NES_AEQE_AEID_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE:
 -                      nesqp = *((struct nes_qp **)&context);
 -                      spin_lock_irqsave(&nesqp->lock, flags);
 -                      nesqp->hw_iwarp_state = iwarp_state;
 -                      nesqp->hw_tcp_state = tcp_state;
 -                      nesqp->last_aeq = async_event_id;
 -                      spin_unlock_irqrestore(&nesqp->lock, flags);
 -                      nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_DDP_UBE_INVALID_MSN"
 -                                      "_NO_BUFFER_AVAILABLE event on QP%u\n",
 -                                      nesqp->hwqp.qp_id);
 -                      if (nesqp->ibqp.event_handler) {
 -                              ibevent.device = nesqp->ibqp.device;
 -                              ibevent.element.qp = &nesqp->ibqp;
 -                              ibevent.event = IB_EVENT_QP_FATAL;
 -                              nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
 -                      }
 -                      /* tell cm to disconnect, cm will queue work to thread */
 -                      nes_cm_disconn(nesqp);
 -                      break;
 -              case NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR:
 -                      nesqp = *((struct nes_qp **)&context);
 -                      spin_lock_irqsave(&nesqp->lock, flags);
 -                      nesqp->hw_iwarp_state = iwarp_state;
 -                      nesqp->hw_tcp_state = tcp_state;
 -                      nesqp->last_aeq = async_event_id;
 -                      spin_unlock_irqrestore(&nesqp->lock, flags);
 -                      nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR"
 -                                      " event on QP%u \n  Q2 Data:\n",
 -                                      nesqp->hwqp.qp_id);
 -                      if (nesqp->ibqp.event_handler) {
 -                              ibevent.device = nesqp->ibqp.device;
 -                              ibevent.element.qp = &nesqp->ibqp;
 -                              ibevent.event = IB_EVENT_QP_FATAL;
 -                              nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
 -                      }
 -                      /* tell cm to disconnect, cm will queue work to thread */
 -                      nes_cm_disconn(nesqp);
 -                      break;
 -                      /* TODO: additional AEs need to be here */
 -              case NES_AEQE_AEID_AMP_BOUNDS_VIOLATION:
 -                      nesqp = *((struct nes_qp **)&context);
 -                      spin_lock_irqsave(&nesqp->lock, flags);
 -                      nesqp->hw_iwarp_state = iwarp_state;
 -                      nesqp->hw_tcp_state = tcp_state;
 -                      nesqp->last_aeq = async_event_id;
 -                      spin_unlock_irqrestore(&nesqp->lock, flags);
 -                      if (nesqp->ibqp.event_handler) {
 -                              ibevent.device = nesqp->ibqp.device;
 -                              ibevent.element.qp = &nesqp->ibqp;
 -                              ibevent.event = IB_EVENT_QP_ACCESS_ERR;
 -                              nesqp->ibqp.event_handler(&ibevent,
 -                                              nesqp->ibqp.qp_context);
 -                      }
 -                      nes_cm_disconn(nesqp);
 -                      break;
 +
                default:
                        nes_debug(NES_DBG_AEQ, "Processing an iWARP related AE for QP, misc = 0x%04X\n",
                                        async_event_id);
  
  }
  
 -
  /**
   * nes_iwarp_ce_handler
   */
@@@ -3680,8 -3373,6 +3680,8 @@@ void flush_wqes(struct nes_device *nesd
  {
        struct nes_cqp_request *cqp_request;
        struct nes_hw_cqp_wqe *cqp_wqe;
 +      u32 sq_code = (NES_IWARP_CQE_MAJOR_FLUSH << 16) | NES_IWARP_CQE_MINOR_FLUSH;
 +      u32 rq_code = (NES_IWARP_CQE_MAJOR_FLUSH << 16) | NES_IWARP_CQE_MINOR_FLUSH;
        int ret;
  
        cqp_request = nes_get_cqp_request(nesdev);
        cqp_wqe = &cqp_request->cqp_wqe;
        nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
  
 +      /* If wqe in error was identified, set code to be put into cqe */
 +      if ((nesqp->term_sq_flush_code) && (which_wq & NES_CQP_FLUSH_SQ)) {
 +              which_wq |= NES_CQP_FLUSH_MAJ_MIN;
 +              sq_code = (CQE_MAJOR_DRV << 16) | nesqp->term_sq_flush_code;
 +              nesqp->term_sq_flush_code = 0;
 +      }
 +
 +      if ((nesqp->term_rq_flush_code) && (which_wq & NES_CQP_FLUSH_RQ)) {
 +              which_wq |= NES_CQP_FLUSH_MAJ_MIN;
 +              rq_code = (CQE_MAJOR_DRV << 16) | nesqp->term_rq_flush_code;
 +              nesqp->term_rq_flush_code = 0;
 +      }
 +
 +      if (which_wq & NES_CQP_FLUSH_MAJ_MIN) {
 +              cqp_wqe->wqe_words[NES_CQP_QP_WQE_FLUSH_SQ_CODE] = cpu_to_le32(sq_code);
 +              cqp_wqe->wqe_words[NES_CQP_QP_WQE_FLUSH_RQ_CODE] = cpu_to_le32(rq_code);
 +      }
 +
        cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] =
                        cpu_to_le32(NES_CQP_FLUSH_WQES | which_wq);
        cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesqp->hwqp.qp_id);
index 8f4b4fca2a1d9dbd26964771f6baa99614884455,986f07fb3ec42ddbf2987d6974f21adf764e36d6..30bdf427ee6d099b907f13ffe0d05dfa9d53c39a
@@@ -31,6 -31,7 +31,6 @@@
   */
  
  #include <rdma/ib_cm.h>
 -#include <rdma/ib_cache.h>
  #include <net/dst.h>
  #include <net/icmp.h>
  #include <linux/icmpv6.h>
@@@ -662,7 -663,6 +662,6 @@@ copied
        skb_reset_mac_header(skb);
        skb_pull(skb, IPOIB_ENCAP_LEN);
  
-       dev->last_rx = jiffies;
        ++dev->stats.rx_packets;
        dev->stats.rx_bytes += skb->len;
  
index e35f4a0ea9d5ffd457fef7becca2ed36685fb73b,c9dcb2064f20b632c8999daad7a4d65720ca85c3..8c91d9f37ada63687ff2423812a1a3b2e7185699
@@@ -36,6 -36,7 +36,6 @@@
  #include <linux/delay.h>
  #include <linux/dma-mapping.h>
  
 -#include <rdma/ib_cache.h>
  #include <linux/ip.h>
  #include <linux/tcp.h>
  
@@@ -276,7 -277,6 +276,6 @@@ static void ipoib_ib_handle_rx_wc(struc
        skb_reset_mac_header(skb);
        skb_pull(skb, IPOIB_ENCAP_LEN);
  
-       dev->last_rx = jiffies;
        ++dev->stats.rx_packets;
        dev->stats.rx_bytes += skb->len;
  
index c97ab82ec743b5edd1371dcdf3d3e64afc198dfd,8b3e76c1cf52a89f4466a7b41fbdd5ffb223d5b6..34e776c5f06b4391e1a7bf42ff1cffb72c8b9ce7
@@@ -172,6 -172,23 +172,23 @@@ static void link_report(struct net_devi
        }
  }
  
+ static void enable_tx_fifo_drain(struct adapter *adapter,
+                                struct port_info *pi)
+ {
+       t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + pi->mac.offset, 0,
+                        F_ENDROPPKT);
+       t3_write_reg(adapter, A_XGM_RX_CTRL + pi->mac.offset, 0);
+       t3_write_reg(adapter, A_XGM_TX_CTRL + pi->mac.offset, F_TXEN);
+       t3_write_reg(adapter, A_XGM_RX_CTRL + pi->mac.offset, F_RXEN);
+ }
+ static void disable_tx_fifo_drain(struct adapter *adapter,
+                                 struct port_info *pi)
+ {
+       t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + pi->mac.offset,
+                        F_ENDROPPKT, 0);
+ }
  void t3_os_link_fault(struct adapter *adap, int port_id, int state)
  {
        struct net_device *dev = adap->port[port_id];
  
                netif_carrier_on(dev);
  
+               disable_tx_fifo_drain(adap, pi);
                /* Clear local faults */
                t3_xgm_intr_disable(adap, pi->port_id);
                t3_read_reg(adap, A_XGM_INT_STATUS +
                t3_xgm_intr_enable(adap, pi->port_id);
  
                t3_mac_enable(mac, MAC_DIRECTION_TX);
-       } else
+       } else {
                netif_carrier_off(dev);
  
+               /* Flush TX FIFO */
+               enable_tx_fifo_drain(adap, pi);
+       }
        link_report(dev);
  }
  
@@@ -232,6 -254,8 +254,8 @@@ void t3_os_link_changed(struct adapter 
  
        if (link_stat != netif_carrier_ok(dev)) {
                if (link_stat) {
+                       disable_tx_fifo_drain(adapter, pi);
                        t3_mac_enable(mac, MAC_DIRECTION_RX);
  
                        /* Clear local faults */
                        t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
                        t3_mac_disable(mac, MAC_DIRECTION_RX);
                        t3_link_start(&pi->phy, mac, &pi->link_config);
+                       /* Flush TX FIFO */
+                       enable_tx_fifo_drain(adapter, pi);
                }
  
                link_report(dev);
@@@ -443,6 -470,7 +470,7 @@@ static int init_tp_parity(struct adapte
                memset(req, 0, sizeof(*req));
                req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
                OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i));
+               req->mtu_idx = NMTUS - 1;
                req->iff = i;
                t3_mgmt_tx(adap, skb);
                if (skb == adap->nofail_skb) {
@@@ -963,6 -991,75 +991,75 @@@ static int bind_qsets(struct adapter *a
  
  #define FW_FNAME "cxgb3/t3fw-%d.%d.%d.bin"
  #define TPSRAM_NAME "cxgb3/t3%c_psram-%d.%d.%d.bin"
+ #define AEL2005_OPT_EDC_NAME "cxgb3/ael2005_opt_edc.bin"
+ #define AEL2005_TWX_EDC_NAME "cxgb3/ael2005_twx_edc.bin"
+ #define AEL2020_TWX_EDC_NAME "cxgb3/ael2020_twx_edc.bin"
+ static inline const char *get_edc_fw_name(int edc_idx)
+ {
+       const char *fw_name = NULL;
+       switch (edc_idx) {
+       case EDC_OPT_AEL2005:
+               fw_name = AEL2005_OPT_EDC_NAME;
+               break;
+       case EDC_TWX_AEL2005:
+               fw_name = AEL2005_TWX_EDC_NAME;
+               break;
+       case EDC_TWX_AEL2020:
+               fw_name = AEL2020_TWX_EDC_NAME;
+               break;
+       }
+       return fw_name;
+ }
+ int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size)
+ {
+       struct adapter *adapter = phy->adapter;
+       const struct firmware *fw;
+       char buf[64];
+       u32 csum;
+       const __be32 *p;
+       u16 *cache = phy->phy_cache;
+       int i, ret;
+       snprintf(buf, sizeof(buf), get_edc_fw_name(edc_idx));
+       ret = request_firmware(&fw, buf, &adapter->pdev->dev);
+       if (ret < 0) {
+               dev_err(&adapter->pdev->dev,
+                       "could not upgrade firmware: unable to load %s\n",
+                       buf);
+               return ret;
+       }
+       /* check size, take checksum in account */
+       if (fw->size > size + 4) {
+               CH_ERR(adapter, "firmware image too large %u, expected %d\n",
+                      (unsigned int)fw->size, size + 4);
+               ret = -EINVAL;
+       }
+       /* compute checksum */
+       p = (const __be32 *)fw->data;
+       for (csum = 0, i = 0; i < fw->size / sizeof(csum); i++)
+               csum += ntohl(p[i]);
+       if (csum != 0xffffffff) {
+               CH_ERR(adapter, "corrupted firmware image, checksum %u\n",
+                      csum);
+               ret = -EINVAL;
+       }
+       for (i = 0; i < size / 4 ; i++) {
+               *cache++ = (be32_to_cpu(p[i]) & 0xffff0000) >> 16;
+               *cache++ = be32_to_cpu(p[i]) & 0xffff;
+       }
+       release_firmware(fw);
+       return ret;
+ }
  
  static int upgrade_fw(struct adapter *adap)
  {
@@@ -1286,7 -1383,6 +1383,7 @@@ static int cxgb_open(struct net_device 
        if (!other_ports)
                schedule_chk_task(adapter);
  
 +      cxgb3_event_notify(&adapter->tdev, OFFLOAD_PORT_UP, pi->port_id);
        return 0;
  }
  
@@@ -1319,7 -1415,6 +1416,7 @@@ static int cxgb_close(struct net_devic
        if (!adapter->open_device_map)
                cxgb_down(adapter);
  
 +      cxgb3_event_notify(&adapter->tdev, OFFLOAD_PORT_DOWN, pi->port_id);
        return 0;
  }
  
@@@ -2719,7 -2814,7 +2816,7 @@@ static int t3_adapter_error(struct adap
  
        if (is_offload(adapter) &&
            test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) {
 -              cxgb3_err_notify(&adapter->tdev, OFFLOAD_STATUS_DOWN, 0);
 +              cxgb3_event_notify(&adapter->tdev, OFFLOAD_STATUS_DOWN, 0);
                offload_close(&adapter->tdev);
        }
  
@@@ -2784,7 -2879,7 +2881,7 @@@ static void t3_resume_ports(struct adap
        }
  
        if (is_offload(adapter) && !ofld_disable)
 -              cxgb3_err_notify(&adapter->tdev, OFFLOAD_STATUS_UP, 0);
 +              cxgb3_event_notify(&adapter->tdev, OFFLOAD_STATUS_UP, 0);
  }
  
  /*
diff --combined drivers/net/gianfar.c
index a00ec639c38039ad56f17706a5441cabe2c3fc20,772104c5ed26ff643db248642ad9bed0208a4907..1e5289ffef6fdda0ce8fd75f92f77f057d860689
@@@ -297,7 -297,6 +297,6 @@@ static int gfar_probe(struct of_device 
        u32 tempval;
        struct net_device *dev = NULL;
        struct gfar_private *priv = NULL;
-       DECLARE_MAC_BUF(mac);
        int err = 0;
        int len_devname;
  
@@@ -491,7 -490,7 +490,7 @@@ static int gfar_remove(struct of_devic
  
        dev_set_drvdata(&ofdev->dev, NULL);
  
 -      unregister_netdev(dev);
 +      unregister_netdev(priv->ndev);
        iounmap(priv->regs);
        free_netdev(priv->ndev);
  
diff --combined drivers/net/tun.c
index 87214a257d2ae3431777e94e375e65bb33878828,589a44acdc76ec7c77949beed85c713f612f6ce7..3f5d28851aa20e4b175a05133faf27161f199f0c
@@@ -103,13 -103,10 +103,10 @@@ struct tun_struct 
        uid_t                   owner;
        gid_t                   group;
  
-       struct sk_buff_head     readq;
        struct net_device       *dev;
        struct fasync_struct    *fasync;
  
        struct tap_filter       txflt;
-       struct sock             *sk;
        struct socket           socket;
  
  #ifdef TUN_DEBUG
@@@ -130,10 -127,17 +127,10 @@@ static inline struct tun_sock *tun_sk(s
  static int tun_attach(struct tun_struct *tun, struct file *file)
  {
        struct tun_file *tfile = file->private_data;
 -      const struct cred *cred = current_cred();
        int err;
  
        ASSERT_RTNL();
  
 -      /* Check permissions */
 -      if (((tun->owner != -1 && cred->euid != tun->owner) ||
 -           (tun->group != -1 && !in_egroup_p(tun->group))) &&
 -              !capable(CAP_NET_ADMIN))
 -              return -EPERM;
 -
        netif_tx_lock_bh(tun->dev);
  
        err = -EINVAL;
        tfile->tun = tun;
        tun->tfile = tfile;
        dev_hold(tun->dev);
-       sock_hold(tun->sk);
+       sock_hold(tun->socket.sk);
        atomic_inc(&tfile->count);
  
  out:
@@@ -164,7 -168,7 +161,7 @@@ static void __tun_detach(struct tun_str
        netif_tx_unlock_bh(tun->dev);
  
        /* Drop read queue */
-       skb_queue_purge(&tun->readq);
+       skb_queue_purge(&tun->socket.sk->sk_receive_queue);
  
        /* Drop the extra count on the net device */
        dev_put(tun->dev);
@@@ -333,7 -337,7 +330,7 @@@ static void tun_free_netdev(struct net_
  {
        struct tun_struct *tun = netdev_priv(dev);
  
-       sock_put(tun->sk);
+       sock_put(tun->socket.sk);
  }
  
  /* Net device open. */
@@@ -351,7 -355,7 +348,7 @@@ static int tun_net_close(struct net_dev
  }
  
  /* Net device start xmit */
- static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
+ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
  {
        struct tun_struct *tun = netdev_priv(dev);
  
        if (!check_filter(&tun->txflt, skb))
                goto drop;
  
-       if (skb_queue_len(&tun->readq) >= dev->tx_queue_len) {
+       if (skb_queue_len(&tun->socket.sk->sk_receive_queue) >= dev->tx_queue_len) {
                if (!(tun->flags & TUN_ONE_QUEUE)) {
                        /* Normal queueing mode. */
                        /* Packet scheduler handles dropping of further packets. */
        }
  
        /* Enqueue packet */
-       skb_queue_tail(&tun->readq, skb);
+       skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);
        dev->trans_start = jiffies;
  
        /* Notify and wake up reader process */
        if (tun->flags & TUN_FASYNC)
                kill_fasync(&tun->fasync, SIGIO, POLL_IN);
        wake_up_interruptible(&tun->socket.wait);
-       return 0;
+       return NETDEV_TX_OK;
  
  drop:
        dev->stats.tx_dropped++;
        kfree_skb(skb);
-       return 0;
+       return NETDEV_TX_OK;
  }
  
  static void tun_net_mclist(struct net_device *dev)
@@@ -485,13 -489,13 +482,13 @@@ static unsigned int tun_chr_poll(struc
        if (!tun)
                return POLLERR;
  
-       sk = tun->sk;
+       sk = tun->socket.sk;
  
        DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
  
        poll_wait(file, &tun->socket.wait, wait);
  
-       if (!skb_queue_empty(&tun->readq))
+       if (!skb_queue_empty(&sk->sk_receive_queue))
                mask |= POLLIN | POLLRDNORM;
  
        if (sock_writeable(sk) ||
@@@ -512,7 -516,7 +509,7 @@@ static inline struct sk_buff *tun_alloc
                                            size_t prepad, size_t len,
                                            size_t linear, int noblock)
  {
-       struct sock *sk = tun->sk;
+       struct sock *sk = tun->socket.sk;
        struct sk_buff *skb;
        int err;
  
@@@ -634,6 -638,9 +631,9 @@@ static __inline__ ssize_t tun_get_user(
                case VIRTIO_NET_HDR_GSO_TCPV6:
                        skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
                        break;
+               case VIRTIO_NET_HDR_GSO_UDP:
+                       skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+                       break;
                default:
                        tun->dev->stats.rx_frame_errors++;
                        kfree_skb(skb);
@@@ -719,6 -726,8 +719,8 @@@ static __inline__ ssize_t tun_put_user(
                                gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
                        else if (sinfo->gso_type & SKB_GSO_TCPV6)
                                gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+                       else if (sinfo->gso_type & SKB_GSO_UDP)
+                               gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
                        else
                                BUG();
                        if (sinfo->gso_type & SKB_GSO_TCP_ECN)
@@@ -775,7 -784,7 +777,7 @@@ static ssize_t tun_chr_aio_read(struct 
                current->state = TASK_INTERRUPTIBLE;
  
                /* Read frames from the queue */
-               if (!(skb=skb_dequeue(&tun->readq))) {
+               if (!(skb=skb_dequeue(&tun->socket.sk->sk_receive_queue))) {
                        if (file->f_flags & O_NONBLOCK) {
                                ret = -EAGAIN;
                                break;
@@@ -812,8 -821,6 +814,6 @@@ static void tun_setup(struct net_devic
  {
        struct tun_struct *tun = netdev_priv(dev);
  
-       skb_queue_head_init(&tun->readq);
        tun->owner = -1;
        tun->group = -1;
  
@@@ -919,8 -926,6 +919,8 @@@ static int tun_set_iff(struct net *net
  
        dev = __dev_get_by_name(net, ifr->ifr_name);
        if (dev) {
 +              const struct cred *cred = current_cred();
 +
                if (ifr->ifr_flags & IFF_TUN_EXCL)
                        return -EBUSY;
                if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops)
                else
                        return -EINVAL;
  
-               err = security_tun_dev_attach(tun->sk);
 +              if (((tun->owner != -1 && cred->euid != tun->owner) ||
 +                   (tun->group != -1 && !in_egroup_p(tun->group))) &&
 +                  !capable(CAP_NET_ADMIN))
 +                      return -EPERM;
++              err = security_tun_dev_attach(tun->socket.sk);
 +              if (err < 0)
 +                      return err;
 +
                err = tun_attach(tun, file);
                if (err < 0)
                        return err;
  
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 +              err = security_tun_dev_create();
 +              if (err < 0)
 +                      return err;
  
                /* Set dev type */
                if (ifr->ifr_flags & IFF_TUN) {
                sk->sk_write_space = tun_sock_write_space;
                sk->sk_sndbuf = INT_MAX;
  
-               tun->sk = sk;
                container_of(sk, struct tun_sock, sk)->tun = tun;
  
 +              security_tun_dev_post_create(sk);
 +
                tun_net_init(dev);
  
                if (strchr(dev->name, '%')) {
                                goto err_free_sk;
                }
  
-               err = -EINVAL;
                err = register_netdevice(tun->dev);
                if (err < 0)
                        goto err_free_sk;
@@@ -1077,7 -1067,8 +1075,8 @@@ static int set_offload(struct net_devic
        old_features = dev->features;
        /* Unset features, set them as we chew on the arg. */
        features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST
-                                   |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6));
+                                   |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6
+                                   |NETIF_F_UFO));
  
        if (arg & TUN_F_CSUM) {
                features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
                                features |= NETIF_F_TSO6;
                        arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
                }
+               if (arg & TUN_F_UFO) {
+                       features |= NETIF_F_UFO;
+                       arg &= ~TUN_F_UFO;
+               }
        }
  
        /* This gives the user a way to test for new features in future by
@@@ -1247,7 -1243,7 +1251,7 @@@ static long tun_chr_ioctl(struct file *
                break;
  
        case TUNGETSNDBUF:
-               sndbuf = tun->sk->sk_sndbuf;
+               sndbuf = tun->socket.sk->sk_sndbuf;
                if (copy_to_user(argp, &sndbuf, sizeof(sndbuf)))
                        ret = -EFAULT;
                break;
                        break;
                }
  
-               tun->sk->sk_sndbuf = sndbuf;
+               tun->socket.sk->sk_sndbuf = sndbuf;
                break;
  
        default:
@@@ -1341,7 -1337,7 +1345,7 @@@ static int tun_chr_close(struct inode *
  
        tun = tfile->tun;
        if (tun)
-               sock_put(tun->sk);
+               sock_put(tun->socket.sk);
  
        put_net(tfile->net);
        kfree(tfile);
index 87dff11061b0cc4cc91c1076afa30bffd81115ee,271c4a82e84b6bedceb099c188670fa5cd23f4b1..9215fbbccc0816ca83ab5901c95247c48bd93909
@@@ -676,7 -676,6 +676,6 @@@ static void netiucv_unpack_skb(struct i
                 * we must use netif_rx_ni() instead of netif_rx()
                 */
                netif_rx_ni(skb);
-               dev->last_rx = jiffies;
                skb_pull(pskb, header->next);
                skb_put(pskb, NETIUCV_HDRLEN);
        }
@@@ -1376,14 -1375,14 +1375,14 @@@ static int netiucv_tx(struct sk_buff *s
        if (skb == NULL) {
                IUCV_DBF_TEXT(data, 2, "netiucv_tx: skb is NULL\n");
                privptr->stats.tx_dropped++;
-               return 0;
+               return NETDEV_TX_OK;
        }
        if (skb_headroom(skb) < NETIUCV_HDRLEN) {
                IUCV_DBF_TEXT(data, 2,
                        "netiucv_tx: skb_headroom < NETIUCV_HDRLEN\n");
                dev_kfree_skb(skb);
                privptr->stats.tx_dropped++;
-               return 0;
+               return NETDEV_TX_OK;
        }
  
        /**
                privptr->stats.tx_dropped++;
                privptr->stats.tx_errors++;
                privptr->stats.tx_carrier_errors++;
-               return 0;
+               return NETDEV_TX_OK;
        }
  
        if (netiucv_test_and_set_busy(dev)) {
@@@ -1839,10 -1838,9 +1838,10 @@@ static int netiucv_register_device(stru
                return -ENOMEM;
  
        ret = device_register(dev);
 -
 -      if (ret)
 +      if (ret) {
 +              put_device(dev);
                return ret;
 +      }
        ret = netiucv_add_files(dev);
        if (ret)
                goto out_unreg;
@@@ -2227,10 -2225,8 +2226,10 @@@ static int __init netiucv_init(void
        netiucv_dev->release = (void (*)(struct device *))kfree;
        netiucv_dev->driver = &netiucv_driver;
        rc = device_register(netiucv_dev);
 -      if (rc)
 +      if (rc) {
 +              put_device(netiucv_dev);
                goto out_driver;
 +      }
        netiucv_banner();
        return rc;
  
diff --combined include/linux/pci_ids.h
index c8fdcadce4379e81ee4f3fa706e79667151aabb9,85492546d33d1ec4c90379450756d13bef47d9b8..555a8262fbc2b8ce407e156327a5939b5ceba4c5
  #define PCI_DEVICE_ID_ATI_IXP600_IDE  0x438c
  #define PCI_DEVICE_ID_ATI_IXP700_SATA 0x4390
  #define PCI_DEVICE_ID_ATI_IXP700_IDE  0x439c
 +/* AMD SB Chipset */
 +#define PCI_DEVICE_ID_AMD_SB900_IDE    0x780c
 +#define PCI_DEVICE_ID_AMD_SB900_SATA_IDE 0x7800
  
  #define PCI_VENDOR_ID_VLSI            0x1004
  #define PCI_DEVICE_ID_VLSI_82C592     0x0005
  #define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450
  #define PCI_DEVICE_ID_AMD_8131_APIC   0x7451
  #define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458
 +#define PCI_DEVICE_ID_AMD_CS5535_IDE    0x208F
  #define PCI_DEVICE_ID_AMD_CS5536_ISA    0x2090
  #define PCI_DEVICE_ID_AMD_CS5536_FLASH  0x2091
  #define PCI_DEVICE_ID_AMD_CS5536_AUDIO  0x2093
  
  #define PCI_VENDOR_ID_SAMSUNG         0x144d
  
+ #define PCI_VENDOR_ID_GIGABYTE                0x1458
  #define PCI_VENDOR_ID_AMBIT           0x1468
  
  #define PCI_VENDOR_ID_MYRICOM         0x14c1
  #define PCI_DEVICE_ID_TIGON3_5787M    0x1693
  #define PCI_DEVICE_ID_TIGON3_5782     0x1696
  #define PCI_DEVICE_ID_TIGON3_5784     0x1698
- #define PCI_DEVICE_ID_TIGON3_5785     0x1699
  #define PCI_DEVICE_ID_TIGON3_5786     0x169a
  #define PCI_DEVICE_ID_TIGON3_5787     0x169b
  #define PCI_DEVICE_ID_TIGON3_5788     0x169c
diff --combined net/core/dev.c
index 278d489aad3bcecadcbbc38413ba4143c507159b,f843a0c5ecf91bc34f47895c042630a88d7986ed..84945470ab38cc073ff71eb8dac14ad653c9cad0
@@@ -191,7 -191,6 +191,6 @@@ static struct list_head ptype_all __rea
   * semaphore held.
   */
  DEFINE_RWLOCK(dev_base_lock);
  EXPORT_SYMBOL(dev_base_lock);
  
  #define NETDEV_HASHBITS       8
@@@ -248,6 -247,7 +247,7 @@@ static RAW_NOTIFIER_HEAD(netdev_chain)
   */
  
  DEFINE_PER_CPU(struct softnet_data, softnet_data);
+ EXPORT_PER_CPU_SYMBOL(softnet_data);
  
  #ifdef CONFIG_LOCKDEP
  /*
@@@ -269,10 -269,10 +269,10 @@@ static const unsigned short netdev_lock
         ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL,
         ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211,
         ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET,
-        ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY,
+        ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154,
         ARPHRD_VOID, ARPHRD_NONE};
  
- static const char *netdev_lock_name[] =
+ static const char *const netdev_lock_name[] =
        {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25",
         "_xmit_PRONET", "_xmit_CHAOS", "_xmit_IEEE802", "_xmit_ARCNET",
         "_xmit_APPLETLK", "_xmit_DLCI", "_xmit_ATM", "_xmit_METRICOM",
         "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL",
         "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211",
         "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET",
-        "_xmit_PHONET_PIPE", "_xmit_IEEE802154", "_xmit_IEEE802154_PHY",
+        "_xmit_PHONET_PIPE", "_xmit_IEEE802154",
         "_xmit_VOID", "_xmit_NONE"};
  
  static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)];
@@@ -381,6 -381,7 +381,7 @@@ void dev_add_pack(struct packet_type *p
        }
        spin_unlock_bh(&ptype_lock);
  }
+ EXPORT_SYMBOL(dev_add_pack);
  
  /**
   *    __dev_remove_pack        - remove packet handler
@@@ -418,6 -419,8 +419,8 @@@ void __dev_remove_pack(struct packet_ty
  out:
        spin_unlock_bh(&ptype_lock);
  }
+ EXPORT_SYMBOL(__dev_remove_pack);
  /**
   *    dev_remove_pack  - remove packet handler
   *    @pt: packet type declaration
@@@ -436,6 -439,7 +439,7 @@@ void dev_remove_pack(struct packet_typ
  
        synchronize_net();
  }
+ EXPORT_SYMBOL(dev_remove_pack);
  
  /******************************************************************************
  
@@@ -499,6 -503,7 +503,7 @@@ int netdev_boot_setup_check(struct net_
        }
        return 0;
  }
+ EXPORT_SYMBOL(netdev_boot_setup_check);
  
  
  /**
@@@ -591,6 -596,7 +596,7 @@@ struct net_device *__dev_get_by_name(st
        }
        return NULL;
  }
+ EXPORT_SYMBOL(__dev_get_by_name);
  
  /**
   *    dev_get_by_name         - find a device by its name
@@@ -615,6 -621,7 +621,7 @@@ struct net_device *dev_get_by_name(stru
        read_unlock(&dev_base_lock);
        return dev;
  }
+ EXPORT_SYMBOL(dev_get_by_name);
  
  /**
   *    __dev_get_by_index - find a device by its ifindex
@@@ -640,6 -647,7 +647,7 @@@ struct net_device *__dev_get_by_index(s
        }
        return NULL;
  }
+ EXPORT_SYMBOL(__dev_get_by_index);
  
  
  /**
@@@ -664,6 -672,7 +672,7 @@@ struct net_device *dev_get_by_index(str
        read_unlock(&dev_base_lock);
        return dev;
  }
+ EXPORT_SYMBOL(dev_get_by_index);
  
  /**
   *    dev_getbyhwaddr - find a device by its hardware address
@@@ -693,7 -702,6 +702,6 @@@ struct net_device *dev_getbyhwaddr(stru
  
        return NULL;
  }
  EXPORT_SYMBOL(dev_getbyhwaddr);
  
  struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type)
  
        return NULL;
  }
  EXPORT_SYMBOL(__dev_getfirstbyhwtype);
  
  struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type)
        rtnl_unlock();
        return dev;
  }
  EXPORT_SYMBOL(dev_getfirstbyhwtype);
  
  /**
   *    dev_put to indicate they have finished with it.
   */
  
- struct net_device * dev_get_by_flags(struct net *net, unsigned short if_flags, unsigned short mask)
+ struct net_device *dev_get_by_flags(struct net *net, unsigned short if_flags,
+                                   unsigned short mask)
  {
        struct net_device *dev, *ret;
  
        read_unlock(&dev_base_lock);
        return ret;
  }
+ EXPORT_SYMBOL(dev_get_by_flags);
  
  /**
   *    dev_valid_name - check if name is okay for network device
@@@ -777,6 -785,7 +785,7 @@@ int dev_valid_name(const char *name
        }
        return 1;
  }
+ EXPORT_SYMBOL(dev_valid_name);
  
  /**
   *    __dev_alloc_name - allocate a name for a device
@@@ -870,6 -879,7 +879,7 @@@ int dev_alloc_name(struct net_device *d
                strlcpy(dev->name, buf, IFNAMSIZ);
        return ret;
  }
+ EXPORT_SYMBOL(dev_alloc_name);
  
  
  /**
@@@ -906,8 -916,7 +916,7 @@@ int dev_change_name(struct net_device *
                err = dev_alloc_name(dev, newname);
                if (err < 0)
                        return err;
-       }
-       else if (__dev_get_by_name(net, newname))
+       } else if (__dev_get_by_name(net, newname))
                return -EEXIST;
        else
                strlcpy(dev->name, newname, IFNAMSIZ);
@@@ -970,7 -979,7 +979,7 @@@ int dev_set_alias(struct net_device *de
                return 0;
        }
  
-       dev->ifalias = krealloc(dev->ifalias, len+1, GFP_KERNEL);
+       dev->ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL);
        if (!dev->ifalias)
                return -ENOMEM;
  
@@@ -1006,6 -1015,7 +1015,7 @@@ void netdev_state_change(struct net_dev
                rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
        }
  }
+ EXPORT_SYMBOL(netdev_state_change);
  
  void netdev_bonding_change(struct net_device *dev)
  {
@@@ -1031,9 -1041,10 +1041,10 @@@ void dev_load(struct net *net, const ch
        dev = __dev_get_by_name(net, name);
        read_unlock(&dev_base_lock);
  
 -      if (!dev && capable(CAP_SYS_MODULE))
 +      if (!dev && capable(CAP_NET_ADMIN))
                request_module("%s", name);
  }
+ EXPORT_SYMBOL(dev_load);
  
  /**
   *    dev_open        - prepare an interface for use.
@@@ -1118,6 -1129,7 +1129,7 @@@ int dev_open(struct net_device *dev
  
        return ret;
  }
+ EXPORT_SYMBOL(dev_open);
  
  /**
   *    dev_close - shutdown an interface.
@@@ -1184,6 -1196,7 +1196,7 @@@ int dev_close(struct net_device *dev
  
        return 0;
  }
+ EXPORT_SYMBOL(dev_close);
  
  
  /**
@@@ -1279,6 -1292,7 +1292,7 @@@ rollback
        raw_notifier_chain_unregister(&netdev_chain, nb);
        goto unlock;
  }
+ EXPORT_SYMBOL(register_netdevice_notifier);
  
  /**
   *    unregister_netdevice_notifier - unregister a network notifier block
@@@ -1299,6 -1313,7 +1313,7 @@@ int unregister_netdevice_notifier(struc
        rtnl_unlock();
        return err;
  }
+ EXPORT_SYMBOL(unregister_netdevice_notifier);
  
  /**
   *    call_netdevice_notifiers - call all network notifier blocks
@@@ -1321,11 -1336,13 +1336,13 @@@ void net_enable_timestamp(void
  {
        atomic_inc(&netstamp_needed);
  }
+ EXPORT_SYMBOL(net_enable_timestamp);
  
  void net_disable_timestamp(void)
  {
        atomic_dec(&netstamp_needed);
  }
+ EXPORT_SYMBOL(net_disable_timestamp);
  
  static inline void net_timestamp(struct sk_buff *skb)
  {
@@@ -1359,7 -1376,7 +1376,7 @@@ static void dev_queue_xmit_nit(struct s
                if ((ptype->dev == dev || !ptype->dev) &&
                    (ptype->af_packet_priv == NULL ||
                     (struct sock *)ptype->af_packet_priv != skb->sk)) {
-                       struct sk_buff *skb2= skb_clone(skb, GFP_ATOMIC);
+                       struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
                        if (!skb2)
                                break;
  
@@@ -1527,6 -1544,7 +1544,7 @@@ out_set_summed
  out:
        return ret;
  }
+ EXPORT_SYMBOL(skb_checksum_help);
  
  /**
   *    skb_gso_segment - Perform segmentation on skb.
@@@ -1589,7 -1607,6 +1607,6 @@@ struct sk_buff *skb_gso_segment(struct 
  
        return segs;
  }
  EXPORT_SYMBOL(skb_gso_segment);
  
  /* Take action when hardware reception checksum errors are detected. */
@@@ -1704,7 -1721,7 +1721,7 @@@ int dev_hard_start_xmit(struct sk_buff 
                        skb_dst_drop(skb);
  
                rc = ops->ndo_start_xmit(skb, dev);
-               if (rc == 0)
+               if (rc == NETDEV_TX_OK)
                        txq_trans_update(txq);
                /*
                 * TODO: if skb_orphan() was called by
@@@ -1730,7 -1747,7 +1747,7 @@@ gso
                skb->next = nskb->next;
                nskb->next = NULL;
                rc = ops->ndo_start_xmit(nskb, dev);
-               if (unlikely(rc)) {
+               if (unlikely(rc != NETDEV_TX_OK)) {
                        nskb->next = skb->next;
                        skb->next = nskb;
                        return rc;
  
  out_kfree_skb:
        kfree_skb(skb);
-       return 0;
+       return NETDEV_TX_OK;
  }
  
  static u32 skb_tx_hashrnd;
@@@ -1755,7 -1772,7 +1772,7 @@@ u16 skb_tx_hash(const struct net_devic
  
        if (skb_rx_queue_recorded(skb)) {
                hash = skb_get_rx_queue(skb);
-               while (unlikely (hash >= dev->real_num_tx_queues))
+               while (unlikely(hash >= dev->real_num_tx_queues))
                        hash -= dev->real_num_tx_queues;
                return hash;
        }
@@@ -1786,6 -1803,40 +1803,40 @@@ static struct netdev_queue *dev_pick_tx
        return netdev_get_tx_queue(dev, queue_index);
  }
  
+ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
+                                struct net_device *dev,
+                                struct netdev_queue *txq)
+ {
+       spinlock_t *root_lock = qdisc_lock(q);
+       int rc;
+       spin_lock(root_lock);
+       if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
+               kfree_skb(skb);
+               rc = NET_XMIT_DROP;
+       } else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) &&
+                  !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) {
+               /*
+                * This is a work-conserving queue; there are no old skbs
+                * waiting to be sent out; and the qdisc is not running -
+                * xmit the skb directly.
+                */
+               __qdisc_update_bstats(q, skb->len);
+               if (sch_direct_xmit(skb, q, dev, txq, root_lock))
+                       __qdisc_run(q);
+               else
+                       clear_bit(__QDISC_STATE_RUNNING, &q->state);
+               rc = NET_XMIT_SUCCESS;
+       } else {
+               rc = qdisc_enqueue_root(skb, q);
+               qdisc_run(q);
+       }
+       spin_unlock(root_lock);
+       return rc;
+ }
  /**
   *    dev_queue_xmit - transmit a buffer
   *    @skb: buffer to transmit
        q = rcu_dereference(txq->qdisc);
  
  #ifdef CONFIG_NET_CLS_ACT
-       skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS);
+       skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_EGRESS);
  #endif
        if (q->enqueue) {
-               spinlock_t *root_lock = qdisc_lock(q);
-               spin_lock(root_lock);
-               if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
-                       kfree_skb(skb);
-                       rc = NET_XMIT_DROP;
-               } else {
-                       rc = qdisc_enqueue_root(skb, q);
-                       qdisc_run(q);
-               }
-               spin_unlock(root_lock);
+               rc = __dev_xmit_skb(skb, q, dev, txq);
                goto out;
        }
  
                        HARD_TX_LOCK(dev, txq, cpu);
  
                        if (!netif_tx_queue_stopped(txq)) {
-                               rc = 0;
+                               rc = NET_XMIT_SUCCESS;
                                if (!dev_hard_start_xmit(skb, dev, txq)) {
                                        HARD_TX_UNLOCK(dev, txq);
                                        goto out;
@@@ -1924,6 -1963,7 +1963,7 @@@ out
        rcu_read_unlock_bh();
        return rc;
  }
+ EXPORT_SYMBOL(dev_queue_xmit);
  
  
  /*=======================================================================
@@@ -1990,6 -2030,7 +2030,7 @@@ enqueue
        kfree_skb(skb);
        return NET_RX_DROP;
  }
+ EXPORT_SYMBOL(netif_rx);
  
  int netif_rx_ni(struct sk_buff *skb)
  {
  
        return err;
  }
  EXPORT_SYMBOL(netif_rx_ni);
  
  static void net_tx_action(struct softirq_action *h)
@@@ -2076,7 -2116,7 +2116,7 @@@ static inline int deliver_skb(struct sk
  /* This hook is defined here for ATM LANE */
  int (*br_fdb_test_addr_hook)(struct net_device *dev,
                             unsigned char *addr) __read_mostly;
- EXPORT_SYMBOL(br_fdb_test_addr_hook);
+ EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook);
  #endif
  
  /*
   */
  struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
                                        struct sk_buff *skb) __read_mostly;
- EXPORT_SYMBOL(br_handle_frame_hook);
+ EXPORT_SYMBOL_GPL(br_handle_frame_hook);
  
  static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
                                            struct packet_type **pt_prev, int *ret,
@@@ -2336,6 -2376,7 +2376,7 @@@ out
        rcu_read_unlock();
        return ret;
  }
+ EXPORT_SYMBOL(netif_receive_skb);
  
  /* Network device is going away, flush any packets still pending  */
  static void flush_backlog(void *arg)
@@@ -2852,7 -2893,7 +2893,7 @@@ softnet_break
        goto out;
  }
  
- static gifconf_func_t * gifconf_list [NPROTO];
+ static gifconf_func_t *gifconf_list[NPROTO];
  
  /**
   *    register_gifconf        -       register a SIOCGIF handler
   *    that is passed must not be freed or reused until it has been replaced
   *    by another handler.
   */
- int register_gifconf(unsigned int family, gifconf_func_t * gifconf)
+ int register_gifconf(unsigned int family, gifconf_func_t *gifconf)
  {
        if (family >= NPROTO)
                return -EINVAL;
        gifconf_list[family] = gifconf;
        return 0;
  }
+ EXPORT_SYMBOL(register_gifconf);
  
  
  /*
@@@ -3080,7 -3122,7 +3122,7 @@@ static int softnet_seq_show(struct seq_
        seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
                   s->total, s->dropped, s->time_squeeze, 0,
                   0, 0, 0, 0, /* was fastroute */
-                  s->cpu_collision );
+                  s->cpu_collision);
        return 0;
  }
  
@@@ -3316,6 -3358,7 +3358,7 @@@ int netdev_set_master(struct net_devic
        rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE);
        return 0;
  }
+ EXPORT_SYMBOL(netdev_set_master);
  
  static void dev_change_rx_flags(struct net_device *dev, int flags)
  {
@@@ -3394,6 -3437,7 +3437,7 @@@ int dev_set_promiscuity(struct net_devi
                dev_set_rx_mode(dev);
        return err;
  }
+ EXPORT_SYMBOL(dev_set_promiscuity);
  
  /**
   *    dev_set_allmulti        - update allmulti count on a device
@@@ -3437,6 -3481,7 +3481,7 @@@ int dev_set_allmulti(struct net_device 
        }
        return 0;
  }
+ EXPORT_SYMBOL(dev_set_allmulti);
  
  /*
   *    Upload unicast and multicast address lists to device and
@@@ -3927,6 -3972,7 +3972,7 @@@ int __dev_addr_sync(struct dev_addr_lis
        }
        return err;
  }
+ EXPORT_SYMBOL_GPL(__dev_addr_sync);
  
  void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
                       struct dev_addr_list **from, int *from_count)
                da = next;
        }
  }
+ EXPORT_SYMBOL_GPL(__dev_addr_unsync);
  
  /**
   *    dev_unicast_sync - Synchronize device's unicast list to another device
@@@ -4064,6 -4111,7 +4111,7 @@@ unsigned dev_get_flags(const struct net
  
        return flags;
  }
+ EXPORT_SYMBOL(dev_get_flags);
  
  /**
   *    dev_change_flags - change device settings
@@@ -4114,12 -4162,13 +4162,13 @@@ int dev_change_flags(struct net_device 
        }
  
        if (dev->flags & IFF_UP &&
-           ((old_flags ^ dev->flags) &(IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
+           ((old_flags ^ dev->flags) & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
                                          IFF_VOLATILE)))
                call_netdevice_notifiers(NETDEV_CHANGE, dev);
  
        if ((flags ^ dev->gflags) & IFF_PROMISC) {
-               int inc = (flags & IFF_PROMISC) ? +1 : -1;
+               int inc = (flags & IFF_PROMISC) ? 1 : -1;
                dev->gflags ^= IFF_PROMISC;
                dev_set_promiscuity(dev, inc);
        }
           IFF_ALLMULTI is requested not asking us and not reporting.
         */
        if ((flags ^ dev->gflags) & IFF_ALLMULTI) {
-               int inc = (flags & IFF_ALLMULTI) ? +1 : -1;
+               int inc = (flags & IFF_ALLMULTI) ? 1 : -1;
                dev->gflags ^= IFF_ALLMULTI;
                dev_set_allmulti(dev, inc);
        }
  
        return ret;
  }
+ EXPORT_SYMBOL(dev_change_flags);
  
  /**
   *    dev_set_mtu - Change maximum transfer unit
@@@ -4174,6 -4225,7 +4225,7 @@@ int dev_set_mtu(struct net_device *dev
                call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
        return err;
  }
+ EXPORT_SYMBOL(dev_set_mtu);
  
  /**
   *    dev_set_mac_address - Change Media Access Control Address
@@@ -4198,6 -4250,7 +4250,7 @@@ int dev_set_mac_address(struct net_devi
                call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
        return err;
  }
+ EXPORT_SYMBOL(dev_set_mac_address);
  
  /*
   *    Perform the SIOCxIFxxx calls, inside read_lock(dev_base_lock)
@@@ -4211,56 -4264,56 +4264,56 @@@ static int dev_ifsioc_locked(struct ne
                return -ENODEV;
  
        switch (cmd) {
-               case SIOCGIFFLAGS:      /* Get interface flags */
-                       ifr->ifr_flags = (short) dev_get_flags(dev);
-                       return 0;
+       case SIOCGIFFLAGS:      /* Get interface flags */
+               ifr->ifr_flags = (short) dev_get_flags(dev);
+               return 0;
  
-               case SIOCGIFMETRIC:     /* Get the metric on the interface
-                                          (currently unused) */
-                       ifr->ifr_metric = 0;
-                       return 0;
+       case SIOCGIFMETRIC:     /* Get the metric on the interface
+                                  (currently unused) */
+               ifr->ifr_metric = 0;
+               return 0;
  
-               case SIOCGIFMTU:        /* Get the MTU of a device */
-                       ifr->ifr_mtu = dev->mtu;
-                       return 0;
+       case SIOCGIFMTU:        /* Get the MTU of a device */
+               ifr->ifr_mtu = dev->mtu;
+               return 0;
  
-               case SIOCGIFHWADDR:
-                       if (!dev->addr_len)
-                               memset(ifr->ifr_hwaddr.sa_data, 0, sizeof ifr->ifr_hwaddr.sa_data);
-                       else
-                               memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
-                                      min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
-                       ifr->ifr_hwaddr.sa_family = dev->type;
-                       return 0;
+       case SIOCGIFHWADDR:
+               if (!dev->addr_len)
+                       memset(ifr->ifr_hwaddr.sa_data, 0, sizeof ifr->ifr_hwaddr.sa_data);
+               else
+                       memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
+                              min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
+               ifr->ifr_hwaddr.sa_family = dev->type;
+               return 0;
  
-               case SIOCGIFSLAVE:
-                       err = -EINVAL;
-                       break;
+       case SIOCGIFSLAVE:
+               err = -EINVAL;
+               break;
  
-               case SIOCGIFMAP:
-                       ifr->ifr_map.mem_start = dev->mem_start;
-                       ifr->ifr_map.mem_end   = dev->mem_end;
-                       ifr->ifr_map.base_addr = dev->base_addr;
-                       ifr->ifr_map.irq       = dev->irq;
-                       ifr->ifr_map.dma       = dev->dma;
-                       ifr->ifr_map.port      = dev->if_port;
-                       return 0;
+       case SIOCGIFMAP:
+               ifr->ifr_map.mem_start = dev->mem_start;
+               ifr->ifr_map.mem_end   = dev->mem_end;
+               ifr->ifr_map.base_addr = dev->base_addr;
+               ifr->ifr_map.irq       = dev->irq;
+               ifr->ifr_map.dma       = dev->dma;
+               ifr->ifr_map.port      = dev->if_port;
+               return 0;
  
-               case SIOCGIFINDEX:
-                       ifr->ifr_ifindex = dev->ifindex;
-                       return 0;
+       case SIOCGIFINDEX:
+               ifr->ifr_ifindex = dev->ifindex;
+               return 0;
  
-               case SIOCGIFTXQLEN:
-                       ifr->ifr_qlen = dev->tx_queue_len;
-                       return 0;
+       case SIOCGIFTXQLEN:
+               ifr->ifr_qlen = dev->tx_queue_len;
+               return 0;
  
-               default:
-                       /* dev_ioctl() should ensure this case
-                        * is never reached
-                        */
-                       WARN_ON(1);
-                       err = -EINVAL;
-                       break;
+       default:
+               /* dev_ioctl() should ensure this case
+                * is never reached
+                */
+               WARN_ON(1);
+               err = -EINVAL;
+               break;
  
        }
        return err;
@@@ -4281,92 -4334,91 +4334,91 @@@ static int dev_ifsioc(struct net *net, 
        ops = dev->netdev_ops;
  
        switch (cmd) {
-               case SIOCSIFFLAGS:      /* Set interface flags */
-                       return dev_change_flags(dev, ifr->ifr_flags);
-               case SIOCSIFMETRIC:     /* Set the metric on the interface
-                                          (currently unused) */
-                       return -EOPNOTSUPP;
+       case SIOCSIFFLAGS:      /* Set interface flags */
+               return dev_change_flags(dev, ifr->ifr_flags);
  
-               case SIOCSIFMTU:        /* Set the MTU of a device */
-                       return dev_set_mtu(dev, ifr->ifr_mtu);
+       case SIOCSIFMETRIC:     /* Set the metric on the interface
+                                  (currently unused) */
+               return -EOPNOTSUPP;
  
-               case SIOCSIFHWADDR:
-                       return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
+       case SIOCSIFMTU:        /* Set the MTU of a device */
+               return dev_set_mtu(dev, ifr->ifr_mtu);
  
-               case SIOCSIFHWBROADCAST:
-                       if (ifr->ifr_hwaddr.sa_family != dev->type)
-                               return -EINVAL;
-                       memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
-                              min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
-                       call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
-                       return 0;
+       case SIOCSIFHWADDR:
+               return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
  
-               case SIOCSIFMAP:
-                       if (ops->ndo_set_config) {
-                               if (!netif_device_present(dev))
-                                       return -ENODEV;
-                               return ops->ndo_set_config(dev, &ifr->ifr_map);
-                       }
-                       return -EOPNOTSUPP;
-               case SIOCADDMULTI:
-                       if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
-                           ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
-                               return -EINVAL;
-                       if (!netif_device_present(dev))
-                               return -ENODEV;
-                       return dev_mc_add(dev, ifr->ifr_hwaddr.sa_data,
-                                         dev->addr_len, 1);
+       case SIOCSIFHWBROADCAST:
+               if (ifr->ifr_hwaddr.sa_family != dev->type)
+                       return -EINVAL;
+               memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
+                      min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
+               call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+               return 0;
  
-               case SIOCDELMULTI:
-                       if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
-                           ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
-                               return -EINVAL;
+       case SIOCSIFMAP:
+               if (ops->ndo_set_config) {
                        if (!netif_device_present(dev))
                                return -ENODEV;
-                       return dev_mc_delete(dev, ifr->ifr_hwaddr.sa_data,
-                                            dev->addr_len, 1);
+                       return ops->ndo_set_config(dev, &ifr->ifr_map);
+               }
+               return -EOPNOTSUPP;
  
-               case SIOCSIFTXQLEN:
-                       if (ifr->ifr_qlen < 0)
-                               return -EINVAL;
-                       dev->tx_queue_len = ifr->ifr_qlen;
-                       return 0;
+       case SIOCADDMULTI:
+               if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
+                   ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
+                       return -EINVAL;
+               if (!netif_device_present(dev))
+                       return -ENODEV;
+               return dev_mc_add(dev, ifr->ifr_hwaddr.sa_data,
+                                 dev->addr_len, 1);
+       case SIOCDELMULTI:
+               if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
+                   ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
+                       return -EINVAL;
+               if (!netif_device_present(dev))
+                       return -ENODEV;
+               return dev_mc_delete(dev, ifr->ifr_hwaddr.sa_data,
+                                    dev->addr_len, 1);
  
-               case SIOCSIFNAME:
-                       ifr->ifr_newname[IFNAMSIZ-1] = '\0';
-                       return dev_change_name(dev, ifr->ifr_newname);
+       case SIOCSIFTXQLEN:
+               if (ifr->ifr_qlen < 0)
+                       return -EINVAL;
+               dev->tx_queue_len = ifr->ifr_qlen;
+               return 0;
  
-               /*
-                *      Unknown or private ioctl
-                */
+       case SIOCSIFNAME:
+               ifr->ifr_newname[IFNAMSIZ-1] = '\0';
+               return dev_change_name(dev, ifr->ifr_newname);
  
-               default:
-                       if ((cmd >= SIOCDEVPRIVATE &&
-                           cmd <= SIOCDEVPRIVATE + 15) ||
-                           cmd == SIOCBONDENSLAVE ||
-                           cmd == SIOCBONDRELEASE ||
-                           cmd == SIOCBONDSETHWADDR ||
-                           cmd == SIOCBONDSLAVEINFOQUERY ||
-                           cmd == SIOCBONDINFOQUERY ||
-                           cmd == SIOCBONDCHANGEACTIVE ||
-                           cmd == SIOCGMIIPHY ||
-                           cmd == SIOCGMIIREG ||
-                           cmd == SIOCSMIIREG ||
-                           cmd == SIOCBRADDIF ||
-                           cmd == SIOCBRDELIF ||
-                           cmd == SIOCSHWTSTAMP ||
-                           cmd == SIOCWANDEV) {
-                               err = -EOPNOTSUPP;
-                               if (ops->ndo_do_ioctl) {
-                                       if (netif_device_present(dev))
-                                               err = ops->ndo_do_ioctl(dev, ifr, cmd);
-                                       else
-                                               err = -ENODEV;
-                               }
-                       } else
-                               err = -EINVAL;
+       /*
+        *      Unknown or private ioctl
+        */
+       default:
+               if ((cmd >= SIOCDEVPRIVATE &&
+                   cmd <= SIOCDEVPRIVATE + 15) ||
+                   cmd == SIOCBONDENSLAVE ||
+                   cmd == SIOCBONDRELEASE ||
+                   cmd == SIOCBONDSETHWADDR ||
+                   cmd == SIOCBONDSLAVEINFOQUERY ||
+                   cmd == SIOCBONDINFOQUERY ||
+                   cmd == SIOCBONDCHANGEACTIVE ||
+                   cmd == SIOCGMIIPHY ||
+                   cmd == SIOCGMIIREG ||
+                   cmd == SIOCSMIIREG ||
+                   cmd == SIOCBRADDIF ||
+                   cmd == SIOCBRDELIF ||
+                   cmd == SIOCSHWTSTAMP ||
+                   cmd == SIOCWANDEV) {
+                       err = -EOPNOTSUPP;
+                       if (ops->ndo_do_ioctl) {
+                               if (netif_device_present(dev))
+                                       err = ops->ndo_do_ioctl(dev, ifr, cmd);
+                               else
+                                       err = -ENODEV;
+                       }
+               } else
+                       err = -EINVAL;
  
        }
        return err;
@@@ -4423,135 -4475,135 +4475,135 @@@ int dev_ioctl(struct net *net, unsigne
         */
  
        switch (cmd) {
-               /*
-                *      These ioctl calls:
-                *      - can be done by all.
-                *      - atomic and do not require locking.
-                *      - return a value
-                */
-               case SIOCGIFFLAGS:
-               case SIOCGIFMETRIC:
-               case SIOCGIFMTU:
-               case SIOCGIFHWADDR:
-               case SIOCGIFSLAVE:
-               case SIOCGIFMAP:
-               case SIOCGIFINDEX:
-               case SIOCGIFTXQLEN:
-                       dev_load(net, ifr.ifr_name);
-                       read_lock(&dev_base_lock);
-                       ret = dev_ifsioc_locked(net, &ifr, cmd);
-                       read_unlock(&dev_base_lock);
-                       if (!ret) {
-                               if (colon)
-                                       *colon = ':';
-                               if (copy_to_user(arg, &ifr,
-                                                sizeof(struct ifreq)))
-                                       ret = -EFAULT;
-                       }
-                       return ret;
+       /*
+        *      These ioctl calls:
+        *      - can be done by all.
+        *      - atomic and do not require locking.
+        *      - return a value
+        */
+       case SIOCGIFFLAGS:
+       case SIOCGIFMETRIC:
+       case SIOCGIFMTU:
+       case SIOCGIFHWADDR:
+       case SIOCGIFSLAVE:
+       case SIOCGIFMAP:
+       case SIOCGIFINDEX:
+       case SIOCGIFTXQLEN:
+               dev_load(net, ifr.ifr_name);
+               read_lock(&dev_base_lock);
+               ret = dev_ifsioc_locked(net, &ifr, cmd);
+               read_unlock(&dev_base_lock);
+               if (!ret) {
+                       if (colon)
+                               *colon = ':';
+                       if (copy_to_user(arg, &ifr,
+                                        sizeof(struct ifreq)))
+                               ret = -EFAULT;
+               }
+               return ret;
  
-               case SIOCETHTOOL:
-                       dev_load(net, ifr.ifr_name);
-                       rtnl_lock();
-                       ret = dev_ethtool(net, &ifr);
-                       rtnl_unlock();
-                       if (!ret) {
-                               if (colon)
-                                       *colon = ':';
-                               if (copy_to_user(arg, &ifr,
-                                                sizeof(struct ifreq)))
-                                       ret = -EFAULT;
-                       }
-                       return ret;
+       case SIOCETHTOOL:
+               dev_load(net, ifr.ifr_name);
+               rtnl_lock();
+               ret = dev_ethtool(net, &ifr);
+               rtnl_unlock();
+               if (!ret) {
+                       if (colon)
+                               *colon = ':';
+                       if (copy_to_user(arg, &ifr,
+                                        sizeof(struct ifreq)))
+                               ret = -EFAULT;
+               }
+               return ret;
  
-               /*
-                *      These ioctl calls:
-                *      - require superuser power.
-                *      - require strict serialization.
-                *      - return a value
-                */
-               case SIOCGMIIPHY:
-               case SIOCGMIIREG:
-               case SIOCSIFNAME:
-                       if (!capable(CAP_NET_ADMIN))
-                               return -EPERM;
-                       dev_load(net, ifr.ifr_name);
-                       rtnl_lock();
-                       ret = dev_ifsioc(net, &ifr, cmd);
-                       rtnl_unlock();
-                       if (!ret) {
-                               if (colon)
-                                       *colon = ':';
-                               if (copy_to_user(arg, &ifr,
-                                                sizeof(struct ifreq)))
-                                       ret = -EFAULT;
-                       }
-                       return ret;
+       /*
+        *      These ioctl calls:
+        *      - require superuser power.
+        *      - require strict serialization.
+        *      - return a value
+        */
+       case SIOCGMIIPHY:
+       case SIOCGMIIREG:
+       case SIOCSIFNAME:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+               dev_load(net, ifr.ifr_name);
+               rtnl_lock();
+               ret = dev_ifsioc(net, &ifr, cmd);
+               rtnl_unlock();
+               if (!ret) {
+                       if (colon)
+                               *colon = ':';
+                       if (copy_to_user(arg, &ifr,
+                                        sizeof(struct ifreq)))
+                               ret = -EFAULT;
+               }
+               return ret;
  
-               /*
-                *      These ioctl calls:
-                *      - require superuser power.
-                *      - require strict serialization.
-                *      - do not return a value
-                */
-               case SIOCSIFFLAGS:
-               case SIOCSIFMETRIC:
-               case SIOCSIFMTU:
-               case SIOCSIFMAP:
-               case SIOCSIFHWADDR:
-               case SIOCSIFSLAVE:
-               case SIOCADDMULTI:
-               case SIOCDELMULTI:
-               case SIOCSIFHWBROADCAST:
-               case SIOCSIFTXQLEN:
-               case SIOCSMIIREG:
-               case SIOCBONDENSLAVE:
-               case SIOCBONDRELEASE:
-               case SIOCBONDSETHWADDR:
-               case SIOCBONDCHANGEACTIVE:
-               case SIOCBRADDIF:
-               case SIOCBRDELIF:
-               case SIOCSHWTSTAMP:
-                       if (!capable(CAP_NET_ADMIN))
-                               return -EPERM;
-                       /* fall through */
-               case SIOCBONDSLAVEINFOQUERY:
-               case SIOCBONDINFOQUERY:
+       /*
+        *      These ioctl calls:
+        *      - require superuser power.
+        *      - require strict serialization.
+        *      - do not return a value
+        */
+       case SIOCSIFFLAGS:
+       case SIOCSIFMETRIC:
+       case SIOCSIFMTU:
+       case SIOCSIFMAP:
+       case SIOCSIFHWADDR:
+       case SIOCSIFSLAVE:
+       case SIOCADDMULTI:
+       case SIOCDELMULTI:
+       case SIOCSIFHWBROADCAST:
+       case SIOCSIFTXQLEN:
+       case SIOCSMIIREG:
+       case SIOCBONDENSLAVE:
+       case SIOCBONDRELEASE:
+       case SIOCBONDSETHWADDR:
+       case SIOCBONDCHANGEACTIVE:
+       case SIOCBRADDIF:
+       case SIOCBRDELIF:
+       case SIOCSHWTSTAMP:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+               /* fall through */
+       case SIOCBONDSLAVEINFOQUERY:
+       case SIOCBONDINFOQUERY:
+               dev_load(net, ifr.ifr_name);
+               rtnl_lock();
+               ret = dev_ifsioc(net, &ifr, cmd);
+               rtnl_unlock();
+               return ret;
+       case SIOCGIFMEM:
+               /* Get the per device memory space. We can add this but
+                * currently do not support it */
+       case SIOCSIFMEM:
+               /* Set the per device memory buffer space.
+                * Not applicable in our case */
+       case SIOCSIFLINK:
+               return -EINVAL;
+       /*
+        *      Unknown or private ioctl.
+        */
+       default:
+               if (cmd == SIOCWANDEV ||
+                   (cmd >= SIOCDEVPRIVATE &&
+                    cmd <= SIOCDEVPRIVATE + 15)) {
                        dev_load(net, ifr.ifr_name);
                        rtnl_lock();
                        ret = dev_ifsioc(net, &ifr, cmd);
                        rtnl_unlock();
+                       if (!ret && copy_to_user(arg, &ifr,
+                                                sizeof(struct ifreq)))
+                               ret = -EFAULT;
                        return ret;
-               case SIOCGIFMEM:
-                       /* Get the per device memory space. We can add this but
-                        * currently do not support it */
-               case SIOCSIFMEM:
-                       /* Set the per device memory buffer space.
-                        * Not applicable in our case */
-               case SIOCSIFLINK:
-                       return -EINVAL;
-               /*
-                *      Unknown or private ioctl.
-                */
-               default:
-                       if (cmd == SIOCWANDEV ||
-                           (cmd >= SIOCDEVPRIVATE &&
-                            cmd <= SIOCDEVPRIVATE + 15)) {
-                               dev_load(net, ifr.ifr_name);
-                               rtnl_lock();
-                               ret = dev_ifsioc(net, &ifr, cmd);
-                               rtnl_unlock();
-                               if (!ret && copy_to_user(arg, &ifr,
-                                                        sizeof(struct ifreq)))
-                                       ret = -EFAULT;
-                               return ret;
-                       }
-                       /* Take care of Wireless Extensions */
-                       if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
-                               return wext_handle_ioctl(net, &ifr, cmd, arg);
-                       return -EINVAL;
+               }
+               /* Take care of Wireless Extensions */
+               if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
+                       return wext_handle_ioctl(net, &ifr, cmd, arg);
+               return -EINVAL;
        }
  }
  
@@@ -4816,6 -4868,7 +4868,7 @@@ err_uninit
                dev->netdev_ops->ndo_uninit(dev);
        goto out;
  }
+ EXPORT_SYMBOL(register_netdevice);
  
  /**
   *    init_dummy_netdev       - init a dummy network device for NAPI
@@@ -5168,6 -5221,7 +5221,7 @@@ void free_netdev(struct net_device *dev
        /* will free via device release */
        put_device(&dev->dev);
  }
+ EXPORT_SYMBOL(free_netdev);
  
  /**
   *    synchronize_net -  Synchronize with packet receive processing
@@@ -5180,6 -5234,7 +5234,7 @@@ void synchronize_net(void
        might_sleep();
        synchronize_rcu();
  }
+ EXPORT_SYMBOL(synchronize_net);
  
  /**
   *    unregister_netdevice - remove device from the kernel
@@@ -5200,6 -5255,7 +5255,7 @@@ void unregister_netdevice(struct net_de
        /* Finish processing unregister after unlock */
        net_set_todo(dev);
  }
+ EXPORT_SYMBOL(unregister_netdevice);
  
  /**
   *    unregister_netdev - remove device from the kernel
@@@ -5218,7 -5274,6 +5274,6 @@@ void unregister_netdev(struct net_devic
        unregister_netdevice(dev);
        rtnl_unlock();
  }
  EXPORT_SYMBOL(unregister_netdev);
  
  /**
@@@ -5347,6 -5402,7 +5402,7 @@@ int dev_change_net_namespace(struct net
  out:
        return err;
  }
+ EXPORT_SYMBOL_GPL(dev_change_net_namespace);
  
  static int dev_cpu_callback(struct notifier_block *nfb,
                            unsigned long action,
@@@ -5407,7 -5463,7 +5463,7 @@@ unsigned long netdev_increment_features
                                        unsigned long mask)
  {
        /* If device needs checksumming, downgrade to it. */
-         if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM))
+       if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM))
                all ^= NETIF_F_NO_CSUM | (one & NETIF_F_ALL_CSUM);
        else if (mask & NETIF_F_ALL_CSUM) {
                /* If one device supports v4/v6 checksumming, set for all. */
@@@ -5633,41 -5689,3 +5689,3 @@@ static int __init initialize_hashrnd(vo
  
  late_initcall_sync(initialize_hashrnd);
  
- EXPORT_SYMBOL(__dev_get_by_index);
- EXPORT_SYMBOL(__dev_get_by_name);
- EXPORT_SYMBOL(__dev_remove_pack);
- EXPORT_SYMBOL(dev_valid_name);
- EXPORT_SYMBOL(dev_add_pack);
- EXPORT_SYMBOL(dev_alloc_name);
- EXPORT_SYMBOL(dev_close);
- EXPORT_SYMBOL(dev_get_by_flags);
- EXPORT_SYMBOL(dev_get_by_index);
- EXPORT_SYMBOL(dev_get_by_name);
- EXPORT_SYMBOL(dev_open);
- EXPORT_SYMBOL(dev_queue_xmit);
- EXPORT_SYMBOL(dev_remove_pack);
- EXPORT_SYMBOL(dev_set_allmulti);
- EXPORT_SYMBOL(dev_set_promiscuity);
- EXPORT_SYMBOL(dev_change_flags);
- EXPORT_SYMBOL(dev_set_mtu);
- EXPORT_SYMBOL(dev_set_mac_address);
- EXPORT_SYMBOL(free_netdev);
- EXPORT_SYMBOL(netdev_boot_setup_check);
- EXPORT_SYMBOL(netdev_set_master);
- EXPORT_SYMBOL(netdev_state_change);
- EXPORT_SYMBOL(netif_receive_skb);
- EXPORT_SYMBOL(netif_rx);
- EXPORT_SYMBOL(register_gifconf);
- EXPORT_SYMBOL(register_netdevice);
- EXPORT_SYMBOL(register_netdevice_notifier);
- EXPORT_SYMBOL(skb_checksum_help);
- EXPORT_SYMBOL(synchronize_net);
- EXPORT_SYMBOL(unregister_netdevice);
- EXPORT_SYMBOL(unregister_netdevice_notifier);
- EXPORT_SYMBOL(net_enable_timestamp);
- EXPORT_SYMBOL(net_disable_timestamp);
- EXPORT_SYMBOL(dev_get_flags);
- EXPORT_SYMBOL(dev_load);
- EXPORT_PER_CPU_SYMBOL(softnet_data);
diff --combined net/ipv4/ip_output.c
index 7ffcd96fe591921bd139a1de925991b97f9a74f0,afae0cbabbf9a87b40bc3ceb32a197e51408a914..9fe5d7b81580fe8b8768b03e4fff05f9059d14c6
@@@ -813,8 -813,6 +813,8 @@@ int ip_append_data(struct sock *sk
                        inet->cork.addr = ipc->addr;
                }
                rt = *rtp;
 +              if (unlikely(!rt))
 +                      return -EFAULT;
                /*
                 * We steal reference to this route, caller should not release it
                 */
@@@ -1304,7 -1302,7 +1304,7 @@@ int ip_push_pending_frames(struct sock 
        err = ip_local_out(skb);
        if (err) {
                if (err > 0)
-                       err = inet->recverr ? net_xmit_errno(err) : 0;
+                       err = net_xmit_errno(err);
                if (err)
                        goto error;
        }
diff --combined net/sched/sch_api.c
index fdb694e9f75938bafad249723c9318b2e4750c3f,3af106140f3577c2ec5119b7102fafae1d54926a..692d9a41cd23e714f77eda461323962e11c3a7b8
@@@ -207,7 -207,7 +207,7 @@@ static struct Qdisc *qdisc_match_from_r
  static void qdisc_list_add(struct Qdisc *q)
  {
        if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS))
-               list_add_tail(&q->list, &qdisc_root_sleeping(q)->list);
+               list_add_tail(&q->list, &qdisc_dev(q)->qdisc->list);
  }
  
  void qdisc_list_del(struct Qdisc *q)
@@@ -219,17 -219,11 +219,11 @@@ EXPORT_SYMBOL(qdisc_list_del)
  
  struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
  {
-       unsigned int i;
        struct Qdisc *q;
  
-       for (i = 0; i < dev->num_tx_queues; i++) {
-               struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
-               struct Qdisc *txq_root = txq->qdisc_sleeping;
-               q = qdisc_match_from_root(txq_root, handle);
-               if (q)
-                       goto out;
-       }
+       q = qdisc_match_from_root(dev->qdisc, handle);
+       if (q)
+               goto out;
  
        q = qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle);
  out:
@@@ -616,32 -610,6 +610,6 @@@ static u32 qdisc_alloc_handle(struct ne
        return i>0 ? autohandle : 0;
  }
  
- /* Attach toplevel qdisc to device queue. */
- static struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
-                                    struct Qdisc *qdisc)
- {
-       struct Qdisc *oqdisc = dev_queue->qdisc_sleeping;
-       spinlock_t *root_lock;
-       root_lock = qdisc_lock(oqdisc);
-       spin_lock_bh(root_lock);
-       /* Prune old scheduler */
-       if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1)
-               qdisc_reset(oqdisc);
-       /* ... and graft new one */
-       if (qdisc == NULL)
-               qdisc = &noop_qdisc;
-       dev_queue->qdisc_sleeping = qdisc;
-       rcu_assign_pointer(dev_queue->qdisc, &noop_qdisc);
-       spin_unlock_bh(root_lock);
-       return oqdisc;
- }
  void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
  {
        const struct Qdisc_class_ops *cops;
@@@ -710,6 -678,11 +678,11 @@@ static int qdisc_graft(struct net_devic
                if (dev->flags & IFF_UP)
                        dev_deactivate(dev);
  
+               if (new && new->ops->attach) {
+                       new->ops->attach(new);
+                       num_q = 0;
+               }
                for (i = 0; i < num_q; i++) {
                        struct netdev_queue *dev_queue = &dev->rx_queue;
  
                        if (new && i > 0)
                                atomic_inc(&new->refcnt);
  
-                       notify_and_destroy(skb, n, classid, old, new);
+                       qdisc_destroy(old);
                }
  
+               notify_and_destroy(skb, n, classid, dev->qdisc, new);
+               if (new && !new->ops->attach)
+                       atomic_inc(&new->refcnt);
+               dev->qdisc = new ? : &noop_qdisc;
                if (dev->flags & IFF_UP)
                        dev_activate(dev);
        } else {
                const struct Qdisc_class_ops *cops = parent->ops->cl_ops;
  
-               err = -EINVAL;
-               if (cops) {
+               err = -EOPNOTSUPP;
+               if (cops && cops->graft) {
                        unsigned long cl = cops->get(parent, classid);
                        if (cl) {
                                err = cops->graft(parent, cl, new, &old);
                                cops->put(parent, cl);
-                       }
+                       } else
+                               err = -ENOENT;
                }
                if (!err)
                        notify_and_destroy(skb, n, classid, old, new);
@@@ -755,7 -733,8 +733,8 @@@ static struct lock_class_key qdisc_rx_l
  
  static struct Qdisc *
  qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
-            u32 parent, u32 handle, struct nlattr **tca, int *errp)
+            struct Qdisc *p, u32 parent, u32 handle,
+            struct nlattr **tca, int *errp)
  {
        int err;
        struct nlattr *kind = tca[TCA_KIND];
                if (tca[TCA_RATE]) {
                        spinlock_t *root_lock;
  
+                       err = -EOPNOTSUPP;
+                       if (sch->flags & TCQ_F_MQROOT)
+                               goto err_out4;
                        if ((sch->parent != TC_H_ROOT) &&
-                           !(sch->flags & TCQ_F_INGRESS))
+                           !(sch->flags & TCQ_F_INGRESS) &&
+                           (!p || !(p->flags & TCQ_F_MQROOT)))
                                root_lock = qdisc_root_sleeping_lock(sch);
                        else
                                root_lock = qdisc_lock(sch);
  
                        err = gen_new_estimator(&sch->bstats, &sch->rate_est,
                                                root_lock, tca[TCA_RATE]);
-                       if (err) {
-                               /*
-                                * Any broken qdiscs that would require
-                                * a ops->reset() here? The qdisc was never
-                                * in action so it shouldn't be necessary.
-                                */
-                               if (ops->destroy)
-                                       ops->destroy(sch);
-                               goto err_out3;
-                       }
+                       if (err)
+                               goto err_out4;
                }
  
                qdisc_list_add(sch);
@@@ -865,6 -841,15 +841,15 @@@ err_out2
  err_out:
        *errp = err;
        return NULL;
+ err_out4:
+       /*
+        * Any broken qdiscs that would require a ops->reset() here?
+        * The qdisc was never in action so it shouldn't be necessary.
+        */
+       if (ops->destroy)
+               ops->destroy(sch);
+       goto err_out3;
  }
  
  static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
        qdisc_put_stab(sch->stab);
        sch->stab = stab;
  
-       if (tca[TCA_RATE])
+       if (tca[TCA_RATE]) {
                /* NB: ignores errors from replace_estimator
                   because change can't be undone. */
+               if (sch->flags & TCQ_F_MQROOT)
+                       goto out;
                gen_replace_estimator(&sch->bstats, &sch->rate_est,
                                            qdisc_root_sleeping_lock(sch),
                                            tca[TCA_RATE]);
+       }
+ out:
        return 0;
  }
  
@@@ -974,9 -962,7 +962,7 @@@ static int tc_get_qdisc(struct sk_buff 
                                q = dev->rx_queue.qdisc_sleeping;
                        }
                } else {
-                       struct netdev_queue *dev_queue;
-                       dev_queue = netdev_get_tx_queue(dev, 0);
-                       q = dev_queue->qdisc_sleeping;
+                       q = dev->qdisc;
                }
                if (!q)
                        return -ENOENT;
@@@ -1044,9 -1030,7 +1030,7 @@@ replay
                                q = dev->rx_queue.qdisc_sleeping;
                        }
                } else {
-                       struct netdev_queue *dev_queue;
-                       dev_queue = netdev_get_tx_queue(dev, 0);
-                       q = dev_queue->qdisc_sleeping;
+                       q = dev->qdisc;
                }
  
                /* It may be default qdisc, ignore it */
@@@ -1123,13 -1107,19 +1107,19 @@@ create_n_graft
        if (!(n->nlmsg_flags&NLM_F_CREATE))
                return -ENOENT;
        if (clid == TC_H_INGRESS)
-               q = qdisc_create(dev, &dev->rx_queue,
+               q = qdisc_create(dev, &dev->rx_queue, p,
                                 tcm->tcm_parent, tcm->tcm_parent,
                                 tca, &err);
-       else
-               q = qdisc_create(dev, netdev_get_tx_queue(dev, 0),
+       else {
+               unsigned int ntx = 0;
+               if (p && p->ops->cl_ops && p->ops->cl_ops->select_queue)
+                       ntx = p->ops->cl_ops->select_queue(p, tcm);
+               q = qdisc_create(dev, netdev_get_tx_queue(dev, ntx), p,
                                 tcm->tcm_parent, tcm->tcm_handle,
                                 tca, &err);
+       }
        if (q == NULL) {
                if (err == -EAGAIN)
                        goto replay;
@@@ -1291,8 -1281,7 +1281,7 @@@ static int tc_dump_qdisc(struct sk_buf
                        s_q_idx = 0;
                q_idx = 0;
  
-               dev_queue = netdev_get_tx_queue(dev, 0);
-               if (tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb, &q_idx, s_q_idx) < 0)
+               if (tc_dump_qdisc_root(dev->qdisc, skb, cb, &q_idx, s_q_idx) < 0)
                        goto done;
  
                dev_queue = &dev->rx_queue;
@@@ -1323,7 -1312,6 +1312,6 @@@ done
  static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
  {
        struct net *net = sock_net(skb->sk);
-       struct netdev_queue *dev_queue;
        struct tcmsg *tcm = NLMSG_DATA(n);
        struct nlattr *tca[TCA_MAX + 1];
        struct net_device *dev;
  
        /* Step 1. Determine qdisc handle X:0 */
  
-       dev_queue = netdev_get_tx_queue(dev, 0);
        if (pid != TC_H_ROOT) {
                u32 qid1 = TC_H_MAJ(pid);
  
                } else if (qid1) {
                        qid = qid1;
                } else if (qid == 0)
-                       qid = dev_queue->qdisc_sleeping->handle;
+                       qid = dev->qdisc->handle;
  
                /* Now qid is genuine qdisc handle consistent
                   both with parent and child.
                        pid = TC_H_MAKE(qid, pid);
        } else {
                if (qid == 0)
-                       qid = dev_queue->qdisc_sleeping->handle;
+                       qid = dev->qdisc->handle;
        }
  
        /* OK. Locate qdisc */
                                goto out;
                        break;
                case RTM_DELTCLASS:
-                       err = cops->delete(q, cl);
+                       err = -EOPNOTSUPP;
+                       if (cops->delete)
+                               err = cops->delete(q, cl);
                        if (err == 0)
                                tclass_notify(skb, n, q, cl, RTM_DELTCLASS);
                        goto out;
        }
  
        new_cl = cl;
-       err = cops->change(q, clid, pid, tca, &new_cl);
+       err = -EOPNOTSUPP;
+       if (cops->change)
+               err = cops->change(q, clid, pid, tca, &new_cl);
        if (err == 0)
                tclass_notify(skb, n, q, new_cl, RTM_NEWTCLASS);
  
@@@ -1456,8 -1447,6 +1447,8 @@@ static int tc_fill_tclass(struct sk_buf
        nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
        tcm = NLMSG_DATA(nlh);
        tcm->tcm_family = AF_UNSPEC;
 +      tcm->tcm__pad1 = 0;
 +      tcm->tcm__pad2 = 0;
        tcm->tcm_ifindex = qdisc_dev(q)->ifindex;
        tcm->tcm_parent = q->handle;
        tcm->tcm_handle = q->handle;
@@@ -1586,8 -1575,7 +1577,7 @@@ static int tc_dump_tclass(struct sk_buf
        s_t = cb->args[0];
        t = 0;
  
-       dev_queue = netdev_get_tx_queue(dev, 0);
-       if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0)
+       if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t) < 0)
                goto done;
  
        dev_queue = &dev->rx_queue;
@@@ -1707,6 -1695,7 +1697,7 @@@ static int __init pktsched_init(void
  {
        register_qdisc(&pfifo_qdisc_ops);
        register_qdisc(&bfifo_qdisc_ops);
+       register_qdisc(&mq_qdisc_ops);
        proc_net_fops_create(&init_net, "psched", 0, &psched_fops);
  
        rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);