]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
authorDavid S. Miller <davem@davemloft.net>
Mon, 15 Jun 2009 10:02:23 +0000 (03:02 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 15 Jun 2009 10:02:23 +0000 (03:02 -0700)
Conflicts:
Documentation/feature-removal-schedule.txt
drivers/scsi/fcoe/fcoe.c
net/core/drop_monitor.c
net/core/net-traces.c

51 files changed:
1  2 
Documentation/feature-removal-schedule.txt
Documentation/networking/can.txt
MAINTAINERS
arch/arm/kernel/signal.c
arch/arm/mach-pxa/tosa.c
drivers/isdn/mISDN/dsp_core.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/arm/ixp4xx_eth.c
drivers/net/b44.h
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/e100.c
drivers/net/e1000e/e1000.h
drivers/net/igbvf/igbvf.h
drivers/net/mlx4/en_netdev.c
drivers/net/mlx4/eq.c
drivers/net/mlx4/mr.c
drivers/net/qlge/qlge_main.c
drivers/net/qlge/qlge_mpi.c
drivers/net/r8169.c
drivers/net/tokenring/3c359.c
drivers/net/tokenring/lanstreamer.c
drivers/net/tokenring/olympic.c
drivers/net/usb/usbnet.c
drivers/net/virtio_net.c
drivers/net/wan/ixp4xx_hss.c
drivers/net/wireless/Kconfig
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rt2x00/rt2x00lib.h
drivers/net/wireless/wavelan_cs.c
drivers/of/Kconfig
drivers/scsi/fcoe/fcoe.c
drivers/scsi/fcoe/libfcoe.c
include/linux/Kbuild
include/linux/if_ether.h
include/linux/net_dropmon.h
include/linux/pci_ids.h
include/linux/sched.h
include/trace/events/napi.h
net/core/dev.c
net/core/drop_monitor.c
net/core/net-traces.c
net/core/netpoll.c
net/core/skbuff.c
net/ipv6/addrconf.c
net/netfilter/Kconfig
net/sched/cls_cgroup.c
security/selinux/hooks.c

index edb2f0b076168deee52986ffdba744e05d7fabf4,ec9ef5d0d7b3b3af5d12c595edd7ddb048be6f2b..7129846a27851a9e61d817e396802edc7e2eac3e
@@@ -438,9 -438,12 +438,19 @@@ Why:     Superseded by tdfxfb. I2C/DDC supp
  Who:  Jean Delvare <khali@linux-fr.org>
        Krzysztof Helt <krzysztof.h1@wp.pl>
  
 +---------------------------
 +
 +What: CONFIG_RFKILL_INPUT
 +When: 2.6.33
 +Why:  Should be implemented in userspace, policy daemon.
 +Who:  Johannes Berg <johannes@sipsolutions.net>
++
+ ----------------------------
+ What: CONFIG_X86_OLD_MCE
+ When: 2.6.32
+ Why:  Remove the old legacy 32bit machine check code. This has been
+       superseded by the newer machine check code from the 64bit port,
+       but the old version has been kept around for easier testing. Note this
+       doesn't impact the old P5 and WinChip machine check handlers.
+ Who:  Andi Kleen <andi@firstfloor.org>
index 6cd6627c3293ded2cf0d97ea1f3be4886182d223,463d9e029ef3a4a702a85410119827333e0ee7bc..cd79735013f94728c15359f292f5fad4b1d0f838
@@@ -36,15 -36,10 +36,15 @@@ This file contain
      6.2 local loopback of sent frames
      6.3 CAN controller hardware filters
      6.4 The virtual CAN driver (vcan)
 -    6.5 currently supported CAN hardware
 -    6.6 todo
 +    6.5 The CAN network device driver interface
 +      6.5.1 Netlink interface to set/get devices properties
 +      6.5.2 Setting the CAN bit-timing
 +      6.5.3 Starting and stopping the CAN network device
 +    6.6 supported CAN hardware
  
 -  7 Credits
 +  7 Socket CAN resources
 +
 +  8 Credits
  
  ============================================================================
  
@@@ -239,8 -234,6 +239,8 @@@ solution for a couple of reasons
    the user application using the common CAN filter mechanisms. Inside
    this filter definition the (interested) type of errors may be
    selected. The reception of error frames is disabled by default.
 +  The format of the CAN error frame is briefly decribed in the Linux
 +  header file "include/linux/can/error.h".
  
  4. How to use Socket CAN
  ------------------------
              return 1;
      }
  
-     /* paraniod check ... */
+     /* paranoid check ... */
      if (nbytes < sizeof(struct can_frame)) {
              fprintf(stderr, "read: incomplete CAN frame\n");
              return 1;
    removal of vcan network devices can be managed with the ip(8) tool:
  
    - Create a virtual CAN network interface:
 -       ip link add type vcan
 +       ip link add type vcan
  
    - Create a virtual CAN network interface with a specific name 'vcan42':
 -       ip link add dev vcan42 type vcan
 +       ip link add dev vcan42 type vcan
  
    - Remove a (virtual CAN) network interface 'vcan42':
 -       ip link del vcan42
 -
 -  The tool 'vcan' from the SocketCAN SVN repository on BerliOS is obsolete.
 -
 -  Virtual CAN network device creation in older Kernels:
 -  In Linux Kernel versions < 2.6.24 the vcan driver creates 4 vcan
 -  netdevices at module load time by default. This value can be changed
 -  with the module parameter 'numdev'. E.g. 'modprobe vcan numdev=8'
 -
 -  6.5 currently supported CAN hardware
 +       $ ip link del vcan42
 +
 +  6.5 The CAN network device driver interface
 +
 +  The CAN network device driver interface provides a generic interface
 +  to setup, configure and monitor CAN network devices. The user can then
 +  configure the CAN device, like setting the bit-timing parameters, via
 +  the netlink interface using the program "ip" from the "IPROUTE2"
 +  utility suite. The following chapter describes briefly how to use it.
 +  Furthermore, the interface uses a common data structure and exports a
 +  set of common functions, which all real CAN network device drivers
 +  should use. Please have a look to the SJA1000 or MSCAN driver to
 +  understand how to use them. The name of the module is can-dev.ko.
 +
 +  6.5.1 Netlink interface to set/get devices properties
 +
 +  The CAN device must be configured via netlink interface. The supported
 +  netlink message types are defined and briefly described in
 +  "include/linux/can/netlink.h". CAN link support for the program "ip"
 +  of the IPROUTE2 utility suite is avaiable and it can be used as shown
 +  below:
 +
 +  - Setting CAN device properties:
 +
 +    $ ip link set can0 type can help
 +    Usage: ip link set DEVICE type can
 +      [ bitrate BITRATE [ sample-point SAMPLE-POINT] ] |
 +      [ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1
 +        phase-seg2 PHASE-SEG2 [ sjw SJW ] ]
 +
 +      [ loopback { on | off } ]
 +      [ listen-only { on | off } ]
 +      [ triple-sampling { on | off } ]
 +
 +      [ restart-ms TIME-MS ]
 +      [ restart ]
 +
 +      Where: BITRATE       := { 1..1000000 }
 +             SAMPLE-POINT  := { 0.000..0.999 }
 +             TQ            := { NUMBER }
 +             PROP-SEG      := { 1..8 }
 +             PHASE-SEG1    := { 1..8 }
 +             PHASE-SEG2    := { 1..8 }
 +             SJW           := { 1..4 }
 +             RESTART-MS    := { 0 | NUMBER }
 +
 +  - Display CAN device details and statistics:
 +
 +    $ ip -details -statistics link show can0
 +    2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP qlen 10
 +      link/can
 +      can <TRIPLE-SAMPLING> state ERROR-ACTIVE restart-ms 100
 +      bitrate 125000 sample_point 0.875
 +      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
 +      sja1000: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
 +      clock 8000000
 +      re-started bus-errors arbit-lost error-warn error-pass bus-off
 +      41         17457      0          41         42         41
 +      RX: bytes  packets  errors  dropped overrun mcast
 +      140859     17608    17457   0       0       0
 +      TX: bytes  packets  errors  dropped carrier collsns
 +      861        112      0       41      0       0
 +
 +  More info to the above output:
 +
 +    "<TRIPLE-SAMPLING>"
 +      Shows the list of selected CAN controller modes: LOOPBACK,
 +      LISTEN-ONLY, or TRIPLE-SAMPLING.
 +
 +    "state ERROR-ACTIVE"
 +      The current state of the CAN controller: "ERROR-ACTIVE",
 +      "ERROR-WARNING", "ERROR-PASSIVE", "BUS-OFF" or "STOPPED"
 +
 +    "restart-ms 100"
 +      Automatic restart delay time. If set to a non-zero value, a
 +      restart of the CAN controller will be triggered automatically
 +      in case of a bus-off condition after the specified delay time
 +      in milliseconds. By default it's off.
 +
 +    "bitrate 125000 sample_point 0.875"
 +      Shows the real bit-rate in bits/sec and the sample-point in the
 +      range 0.000..0.999. If the calculation of bit-timing parameters
 +      is enabled in the kernel (CONFIG_CAN_CALC_BITTIMING=y), the
 +      bit-timing can be defined by setting the "bitrate" argument.
 +      Optionally the "sample-point" can be specified. By default it's
 +      0.000 assuming CIA-recommended sample-points.
 +
 +    "tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1"
 +      Shows the time quanta in ns, propagation segment, phase buffer
 +      segment 1 and 2 and the synchronisation jump width in units of
 +      tq. They allow to define the CAN bit-timing in a hardware
 +      independent format as proposed by the Bosch CAN 2.0 spec (see
 +      chapter 8 of http://www.semiconductors.bosch.de/pdf/can2spec.pdf).
 +
 +    "sja1000: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
 +     clock 8000000"
 +      Shows the bit-timing constants of the CAN controller, here the
 +      "sja1000". The minimum and maximum values of the time segment 1
 +      and 2, the synchronisation jump width in units of tq, the
 +      bitrate pre-scaler and the CAN system clock frequency in Hz.
 +      These constants could be used for user-defined (non-standard)
 +      bit-timing calculation algorithms in user-space.
 +
 +    "re-started bus-errors arbit-lost error-warn error-pass bus-off"
 +      Shows the number of restarts, bus and arbitration lost errors,
 +      and the state changes to the error-warning, error-passive and
 +      bus-off state. RX overrun errors are listed in the "overrun"
 +      field of the standard network statistics.
 +
 +  6.5.2 Setting the CAN bit-timing
 +
 +  The CAN bit-timing parameters can always be defined in a hardware
 +  independent format as proposed in the Bosch CAN 2.0 specification
 +  specifying the arguments "tq", "prop_seg", "phase_seg1", "phase_seg2"
 +  and "sjw":
 +
 +    $ ip link set canX type can tq 125 prop-seg 6 \
 +                              phase-seg1 7 phase-seg2 2 sjw 1
 +
 +  If the kernel option CONFIG_CAN_CALC_BITTIMING is enabled, CIA
 +  recommended CAN bit-timing parameters will be calculated if the bit-
 +  rate is specified with the argument "bitrate":
 +
 +    $ ip link set canX type can bitrate 125000
 +
 +  Note that this works fine for the most common CAN controllers with
 +  standard bit-rates but may *fail* for exotic bit-rates or CAN system
 +  clock frequencies. Disabling CONFIG_CAN_CALC_BITTIMING saves some
 +  space and allows user-space tools to solely determine and set the
 +  bit-timing parameters. The CAN controller specific bit-timing
 +  constants can be used for that purpose. They are listed by the
 +  following command:
 +
 +    $ ip -details link show can0
 +    ...
 +      sja1000: clock 8000000 tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
 +
 +  6.5.3 Starting and stopping the CAN network device
 +
 +  A CAN network device is started or stopped as usual with the command
 +  "ifconfig canX up/down" or "ip link set canX up/down". Be aware that
 +  you *must* define proper bit-timing parameters for real CAN devices
 +  before you can start it to avoid error-prone default settings:
 +
 +    $ ip link set canX up type can bitrate 125000
 +
 +  A device may enter the "bus-off" state if too much errors occurred on
 +  the CAN bus. Then no more messages are received or sent. An automatic
 +  bus-off recovery can be enabled by setting the "restart-ms" to a
 +  non-zero value, e.g.:
 +
 +    $ ip link set canX type can restart-ms 100
 +
 +  Alternatively, the application may realize the "bus-off" condition
 +  by monitoring CAN error frames and do a restart when appropriate with
 +  the command:
 +
 +    $ ip link set canX type can restart
 +
 +  Note that a restart will also create a CAN error frame (see also
 +  chapter 3.4).
  
 -  On the project website http://developer.berlios.de/projects/socketcan
 -  there are different drivers available:
 +  6.6 Supported CAN hardware
  
 -    vcan:    Virtual CAN interface driver (if no real hardware is available)
 -    sja1000: Philips SJA1000 CAN controller (recommended)
 -    i82527:  Intel i82527 CAN controller
 -    mscan:   Motorola/Freescale CAN controller (e.g. inside SOC MPC5200)
 -    ccan:    CCAN controller core (e.g. inside SOC h7202)
 -    slcan:   For a bunch of CAN adaptors that are attached via a
 -             serial line ASCII protocol (for serial / USB adaptors)
 +  Please check the "Kconfig" file in "drivers/net/can" to get an actual
 +  list of the support CAN hardware. On the Socket CAN project website
 +  (see chapter 7) there might be further drivers available, also for
 +  older kernel versions.
  
 -  Additionally the different CAN adaptors (ISA/PCI/PCMCIA/USB/Parport)
 -  from PEAK Systemtechnik support the CAN netdevice driver model
 -  since Linux driver v6.0: http://www.peak-system.com/linux/index.htm
 +7. Socket CAN resources
 +-----------------------
  
 -  Please check the Mailing Lists on the berlios OSS project website.
 +  You can find further resources for Socket CAN like user space tools,
 +  support for old kernel versions, more drivers, mailing lists, etc.
 +  at the BerliOS OSS project website for Socket CAN:
  
 -  6.6 todo
 +    http://developer.berlios.de/projects/socketcan
  
 -  The configuration interface for CAN network drivers is still an open
 -  issue that has not been finalized in the socketcan project. Also the
 -  idea of having a library module (candev.ko) that holds functions
 -  that are needed by all CAN netdevices is not ready to ship.
 -  Your contribution is welcome.
 +  If you have questions, bug fixes, etc., don't hesitate to post them to
 +  the Socketcan-Users mailing list. But please search the archives first.
  
 -7. Credits
 +8. Credits
  ----------
  
 -  Oliver Hartkopp (PF_CAN core, filters, drivers, bcm)
 +  Oliver Hartkopp (PF_CAN core, filters, drivers, bcm, SJA1000 driver)
    Urs Thuermann (PF_CAN core, kernel integration, socket interfaces, raw, vcan)
    Jan Kizka (RT-SocketCAN core, Socket-API reconciliation)
 -  Wolfgang Grandegger (RT-SocketCAN core & drivers, Raw Socket-API reviews)
 +  Wolfgang Grandegger (RT-SocketCAN core & drivers, Raw Socket-API reviews,
 +                       CAN device driver interface, MSCAN driver)
    Robert Schwebel (design reviews, PTXdist integration)
    Marc Kleine-Budde (design reviews, Kernel 2.6 cleanups, drivers)
    Benedikt Spranger (reviews)
    Thomas Gleixner (LKML reviews, coding style, posting hints)
 -  Andrey Volkov (kernel subtree structure, ioctls, mscan driver)
 +  Andrey Volkov (kernel subtree structure, ioctls, MSCAN driver)
    Matthias Brukner (first SJA1000 CAN netdevice implementation Q2/2003)
    Klaus Hitschler (PEAK driver integration)
    Uwe Koppe (CAN netdevices with PF_PACKET approach)
    Michael Schulze (driver layer loopback requirement, RT CAN drivers review)
 +  Pavel Pisa (Bit-timing calculation)
 +  Sascha Hauer (SJA1000 platform driver)
 +  Sebastian Haas (SJA1000 EMS PCI driver)
 +  Markus Plessing (SJA1000 EMS PCI driver)
 +  Per Dalen (SJA1000 Kvaser PCI driver)
 +  Sam Ravnborg (reviews, coding style, kbuild help)
diff --combined MAINTAINERS
index 61c190a15b5df058d5aa1e7e6954aa8414fb0ad7,a1fe87ad483222f643657c0422f6797a4feb24d4..2cb7566904b128a80bd507359f22031b800ff9b7
@@@ -71,7 -71,7 +71,7 @@@ P: Perso
  M: Mail patches to
  L: Mailing list that is relevant to this area
  W: Web-page with status/info
- T: SCM tree type and location.  Type is one of: git, hg, quilt.
+ T: SCM tree type and location.  Type is one of: git, hg, quilt, stgit.
  S: Status, one of the following:
  
        Supported:      Someone is actually paid to look after this.
@@@ -159,7 -159,8 +159,8 @@@ F: drivers/net/r8169.
  8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
  L:    linux-serial@vger.kernel.org
  W:    http://serial.sourceforge.net
- S:    Orphan
+ M:    alan@lxorguk.ukuu.org.uk
+ S:    Odd Fixes
  F:    drivers/serial/8250*
  F:    include/linux/serial_8250.h
  
@@@ -434,7 -435,7 +435,7 @@@ F: arch/alpha
  
  AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
  P:    Thomas Dahlmann
- M:    thomas.dahlmann@amd.com
+ M:    dahlmann.thomas@arcor.de
  L:    linux-geode@lists.infradead.org (moderated for non-subscribers)
  S:    Supported
  F:    drivers/usb/gadget/amd5536udc.*
@@@ -624,6 -625,7 +625,7 @@@ M: paulius.zaleckas@teltonika.l
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
  T:    git git://gitorious.org/linux-gemini/mainline.git
  S:    Maintained
+ F:    arch/arm/mach-gemini/
  
  ARM/EBSA110 MACHINE SUPPORT
  P:    Russell King
@@@ -650,6 -652,7 +652,7 @@@ P: Paulius Zalecka
  M:    paulius.zaleckas@teltonika.lt
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
  S:    Maintained
+ F:    arch/arm/mm/*-fa*
  
  ARM/FOOTBRIDGE ARCHITECTURE
  P:    Russell King
@@@ -678,6 -681,13 +681,13 @@@ M:       sakoman@gmail.co
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
  S:    Maintained
  
+ ARM/H4700 (HP IPAQ HX4700) MACHINE SUPPORT
+ P:    Philipp Zabel
+ M:    philipp.zabel@gmail.com
+ S:    Maintained
+ F:    arch/arm/mach-pxa/hx4700.c
+ F:    arch/arm/mach-pxa/include/mach/hx4700.h
  ARM/HP JORNADA 7XX MACHINE SUPPORT
  P:    Kristoffer Ericson
  M:    kristoffer.ericson@gmail.com
@@@ -937,12 -947,6 +947,12 @@@ P:       Luis R. Rodrigue
  M:    lrodriguez@atheros.com
  P:    Jouni Malinen
  M:    jmalinen@atheros.com
 +P:    Sujith Manoharan
 +M:    Sujith.Manoharan@atheros.com
 +P:    Vasanthakumar Thiagarajan
 +M:    vasanth@atheros.com
 +P:    Senthil Balasubramanian
 +M:    senthilkumar@atheros.com
  L:    linux-wireless@vger.kernel.org
  L:    ath9k-devel@lists.ath9k.org
  S:    Supported
@@@ -1138,17 -1142,17 +1148,17 @@@ F:   fs/bfs
  F:    include/linux/bfs_fs.h
  
  BLACKFIN ARCHITECTURE
- P:    Bryan Wu
- M:    cooloney@kernel.org
+ P:    Mike Frysinger
+ M:    vapier@gentoo.org
  L:    uclinux-dist-devel@blackfin.uclinux.org
  W:    http://blackfin.uclinux.org
  S:    Supported
  F:    arch/blackfin/
  
  BLACKFIN EMAC DRIVER
- P:    Bryan Wu
- M:    cooloney@kernel.org
- L:    uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+ P:    Michael Hennerich
+ M:    michael.hennerich@analog.com
+ L:    uclinux-dist-devel@blackfin.uclinux.org
  W:    http://blackfin.uclinux.org
  S:    Supported
  F:    drivers/net/bfin_mac.*
  BLACKFIN RTC DRIVER
  P:    Mike Frysinger
  M:    vapier.adi@gmail.com
- L:    uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+ L:    uclinux-dist-devel@blackfin.uclinux.org
  W:    http://blackfin.uclinux.org
  S:    Supported
  F:    drivers/rtc/rtc-bfin.c
  BLACKFIN SERIAL DRIVER
  P:    Sonic Zhang
  M:    sonic.zhang@analog.com
- L:    uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+ L:    uclinux-dist-devel@blackfin.uclinux.org
  W:    http://blackfin.uclinux.org
  S:    Supported
  F:    drivers/serial/bfin_5xx.c
  BLACKFIN WATCHDOG DRIVER
  P:    Mike Frysinger
  M:    vapier.adi@gmail.com
- L:    uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+ L:    uclinux-dist-devel@blackfin.uclinux.org
  W:    http://blackfin.uclinux.org
  S:    Supported
  F:    drivers/watchdog/bfin_wdt.c
  BLACKFIN I2C TWI DRIVER
  P:    Sonic Zhang
  M:    sonic.zhang@analog.com
- L:    uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+ L:    uclinux-dist-devel@blackfin.uclinux.org
  W:    http://blackfin.uclinux.org/
  S:    Supported
  F:    drivers/i2c/busses/i2c-bfin-twi.c
@@@ -1335,13 -1339,6 +1345,13 @@@ F:    drivers/net/can
  F:    include/linux/can/
  F:    include/linux/can.h
  
 +CAN NETWORK DRIVERS
 +P:    Wolfgang Grandegger
 +M:    wg@grandegger.com
 +L:    socketcan-core@lists.berlios.de (subscribers-only)
 +W:    http://developer.berlios.de/projects/socketcan/
 +S:    Maintained
 +
  CELL BROADBAND ENGINE ARCHITECTURE
  P:    Arnd Bergmann
  M:    arnd@arndb.de
@@@ -1444,6 -1441,14 +1454,14 @@@ P:    Russell Kin
  M:    linux@arm.linux.org.uk
  F:    include/linux/clk.h
  
+ CISCO FCOE HBA DRIVER
+ P:    Abhijeet Joglekar
+ M:    abjoglek@cisco.com
+ P:    Joe Eykholt
+ M:    jeykholt@cisco.com
+ L:    linux-scsi@vger.kernel.org
+ S:    Supported
  CODA FILE SYSTEM
  P:    Jan Harkes
  M:    jaharkes@cs.cmu.edu
@@@ -1804,10 -1809,10 +1822,10 @@@ F:   drivers/char/epca
  F:    drivers/char/digi*
  
  DIRECTORY NOTIFICATION (DNOTIFY)
- P:    Stephen Rothwell
- M:    sfr@canb.auug.org.au
+ P:    Eric Paris
+ M:    eparis@parisplace.org
  L:    linux-kernel@vger.kernel.org
- S:    Supported
+ S:    Maintained
  F:    Documentation/filesystems/dnotify.txt
  F:    fs/notify/dnotify/
  F:    include/linux/dnotify.h
@@@ -1981,10 -1986,20 +1999,20 @@@ F:   Documentation/edac.tx
  F:    drivers/edac/edac_*
  F:    include/linux/edac.h
  
+ EDAC-AMD64
+ P:    Doug Thompson
+ M:    dougthompson@xmission.com
+ P:    Borislav Petkov
+ M:    borislav.petkov@amd.com
+ L:    bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
+ W:    bluesmoke.sourceforge.net
+ S:    Supported
+ F:    drivers/edac/amd64_edac*
  EDAC-E752X
  P:    Mark Gross
- P:    Doug Thompson
  M:    mark.gross@intel.com
+ P:    Doug Thompson
  M:    dougthompson@xmission.com
  L:    bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
  W:    bluesmoke.sourceforge.net
@@@ -2097,6 -2112,15 +2125,15 @@@ W:    http://sourceforge.net/projects/lpfc
  S:    Supported
  F:    drivers/scsi/lpfc/
  
+ ENE CB710 FLASH CARD READER DRIVER
+ P:    MichaÅ‚ MirosÅ‚aw
+ M:    mirq-linux@rere.qmqm.pl
+ L:    linux-kernel@vger.kernel.org
+ S:    Maintained
+ F:    drivers/misc/cb710/
+ F:    drivers/mmc/host/cb710-mmc.*
+ F:    include/linux/cb710.h
  EPSON 1355 FRAMEBUFFER DRIVER
  P:    Christopher Hoover
  M:    ch@murgatroid.com
@@@ -2261,7 -2285,7 +2298,7 @@@ P:      Li Yan
  M:    leoli@freescale.com
  P:    Zhang Wei
  M:    zw@zh-kernel.org
- L:    linuxppc-embedded@ozlabs.org
+ L:    linuxppc-dev@ozlabs.org
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  F:    drivers/dma/fsldma.*
@@@ -2343,7 -2367,7 +2380,7 @@@ F:      fs/freevxfs
  
  FREEZER
  P:    Pavel Machek
- M:    pavel@suse.cz
+ M:    pavel@ucw.cz
  P:    Rafael J. Wysocki
  M:    rjw@sisk.pl
  L:    linux-pm@lists.linux-foundation.org
@@@ -2819,18 -2843,6 +2856,18 @@@ L:    linux1394-devel@lists.sourceforge.ne
  S:    Maintained
  F:    drivers/ieee1394/raw1394*
  
 +IEEE 802.15.4 SUBSYSTEM
 +P:    Dmitry Eremin-Solenikov
 +M:    dbaryshkov@gmail.com
 +P:    Sergey Lapin
 +M:    slapin@ossfans.org
 +L:    linux-zigbee-devel@lists.sourceforge.net
 +W:    http://apps.sourceforge.net/trac/linux-zigbee
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/lumag/lowpan.git
 +S:    Maintained
 +F:    net/ieee802154/
 +F:    drivers/ieee801254/
 +
  INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
  P:    Mimi Zohar
  M:    zohar@us.ibm.com
@@@ -2862,6 -2874,8 +2899,8 @@@ P:      John McCutcha
  M:    john@johnmccutchan.com
  P:    Robert Love
  M:    rlove@rlove.org
+ P:    Eric Paris
+ M:    eparis@parisplace.org
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
  F:    Documentation/filesystems/inotify.txt
@@@ -3122,7 -3136,6 +3161,7 @@@ M:      samuel@sortiz.or
  L:    irda-users@lists.sourceforge.net (subscribers-only)
  W:    http://irda.sourceforge.net/
  S:    Maintained
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git
  F:    Documentation/networking/irda.txt
  F:    drivers/net/irda/
  F:    include/net/irda/
@@@ -3366,6 -3379,16 +3405,16 @@@ F:    drivers/serial/kgdboc.
  F:    include/linux/kgdb.h
  F:    kernel/kgdb.c
  
+ KMEMLEAK
+ P:    Catalin Marinas
+ M:    catalin.marinas@arm.com
+ L:    linux-kernel@vger.kernel.org
+ S:    Maintained
+ F:    Documentation/kmemleak.txt
+ F:    include/linux/kmemleak.h
+ F:    mm/kmemleak.c
+ F:    mm/kmemleak-test.c
  KMEMTRACE
  P:    Eduard - Gabriel Munteanu
  M:    eduard.munteanu@linux360.ro
@@@ -4152,6 -4175,69 +4201,69 @@@ S:    Maintaine
  F:    drivers/video/riva/
  F:    drivers/video/nvidia/
  
+ OMAP SUPPORT
+ P:    Tony Lindgren <tony@atomide.com>
+ M:    tony@atomide.com
+ L:    linux-omap@vger.kernel.org
+ W:    http://www.muru.com/linux/omap/
+ W:    http://linux.omap.com/
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
+ S:    Maintained
+ F:    arch/arm/*omap*
+ OMAP CLOCK FRAMEWORK SUPPORT
+ P:    Paul Walmsley
+ M:    paul@pwsan.com
+ L:    linux-omap@vger.kernel.org
+ S:    Maintained
+ F:    arch/arm/*omap*/*clock*
+ OMAP POWER MANAGEMENT SUPPORT
+ P:    Kevin Hilman
+ M:    khilman@deeprootsystems.com
+ L:    linux-omap@vger.kernel.org
+ S:    Maintained
+ F:    arch/arm/*omap*/*pm*
+ OMAP AUDIO SUPPORT
+ P:    Jarkko Nikula
+ M:    jhnikula@gmail.com
+ L:    alsa-devel@alsa-project.org (subscribers-only)
+ L:    linux-omap@vger.kernel.org
+ S:    Maintained
+ F:    sound/soc/omap/
+ OMAP FRAMEBUFFER SUPPORT
+ P:    Imre Deak
+ M:    imre.deak@nokia.com
+ L:    linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+ L:    linux-omap@vger.kernel.org
+ S:    Maintained
+ F:    drivers/video/omap/
+ OMAP MMC SUPPORT
+ P:    Jarkko Lavinen
+ M:    jarkko.lavinen@nokia.com
+ L:    linux-kernel@vger.kernel.org
+ L:    linux-omap@vger.kernel.org
+ S:    Maintained
+ F:    drivers/mmc/host/*omap*
+ OMAP RANDOM NUMBER GENERATOR SUPPORT
+ P:    Deepak Saxena
+ M:    dsaxena@plexity.net
+ S:    Maintained
+ F:    drivers/char/hw_random/omap-rng.c
+ OMAP USB SUPPORT
+ P:    Felipe Balbi
+ M:    felipe.balbi@nokia.com
+ P:    David Brownell
+ M:    dbrownell@users.sourceforge.net
+ L:    linux-usb@vger.kernel.org
+ L:    linux-omap@vger.kernel.org
+ S:    Maintained
  OMFS FILESYSTEM
  P:    Bob Copeland
  M:    me@bobcopeland.com
@@@ -4408,6 -4494,16 +4520,16 @@@ S:    Maintaine
  F:    include/linux/delayacct.h
  F:    kernel/delayacct.c
  
+ PERFORMANCE COUNTER SUBSYSTEM
+ P:    Peter Zijlstra
+ M:    a.p.zijlstra@chello.nl
+ P:    Paul Mackerras
+ M:    paulus@samba.org
+ P:    Ingo Molnar
+ M:    mingo@elte.hu
+ L:    linux-kernel@vger.kernel.org
+ S:    Supported
  PERSONALITY HANDLING
  P:    Christoph Hellwig
  M:    hch@infradead.org
@@@ -4525,8 -4621,8 +4647,8 @@@ S:      Maintaine
  F:    drivers/ata/sata_promise.*
  
  PS3 NETWORK SUPPORT
 -P:    Masakazu Mokuno
 -M:    mokuno@sm.sony.co.jp
 +P:    Geoff Levand
 +M:    geoffrey.levand@am.sony.com
  L:    netdev@vger.kernel.org
  L:    cbe-oss-dev@ozlabs.org
  S:    Supported
@@@ -4580,7 -4676,7 +4702,7 @@@ F:      drivers/media/video/pvrusb2
  
  PXA2xx/PXA3xx SUPPORT
  P:    Eric Miao
- M:    eric.miao@marvell.com
+ M:    eric.y.miao@gmail.com
  P:    Russell King
  M:    linux@arm.linux.org.uk
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
@@@ -4590,23 -4686,24 +4712,24 @@@ F:   drivers/pcmcia/pxa2xx
  F:    drivers/spi/pxa2xx*
  F:    drivers/usb/gadget/pxa2*
  F:    include/sound/pxa2xx-lib.h
- F:    sound/soc/pxa/pxa2xx*
+ F:    sound/arm/pxa*
+ F:    sound/soc/pxa
  
  PXA168 SUPPORT
  P:    Eric Miao
- M:    eric.miao@marvell.com
+ M:    eric.y.miao@gmail.com
  P:    Jason Chagas
  M:    jason.chagas@marvell.com
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
- S:    Supported
+ S:    Maintained
  
  PXA910 SUPPORT
  P:    Eric Miao
- M:    eric.miao@marvell.com
+ M:    eric.y.miao@gmail.com
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
- S:    Supported
+ S:    Maintained
  
  PXA MMCI DRIVER
  S:    Orphan
@@@ -4726,7 -4823,7 +4849,7 @@@ F:      drivers/net/r6040.
  RDS - RELIABLE DATAGRAM SOCKETS
  P:    Andy Grover
  M:    andy.grover@oracle.com
 -L:    rds-devel@oss.oracle.com
 +L:    rds-devel@oss.oracle.com (moderated for non-subscribers)
  S:    Supported
  F:    net/rds/
  
@@@ -4766,9 -4863,9 +4889,9 @@@ S:      Supporte
  F:    fs/reiserfs/
  
  RFKILL
 -P:    Ivo van Doorn
 -M:    IvDoorn@gmail.com
 -L:    netdev@vger.kernel.org
 +P:    Johannes Berg
 +M:    johannes@sipsolutions.net
 +L:    linux-wireless@vger.kernel.org
  S:    Maintained
  F     Documentation/rfkill.txt
  F:    net/rfkill/
@@@ -5127,7 -5224,6 +5250,6 @@@ P:      Vincent Sander
  M:    support@simtec.co.uk
  W:    http://www.simtec.co.uk/products/EB110ATX/
  S:    Supported
- F:    arch/arm/mach-ebsa110/
  
  SIMTEC EB2410ITX (BAST)
  P:    Ben Dooks
@@@ -5318,11 -5414,12 +5440,12 @@@ P:   Liam Girdwoo
  M:    lrg@slimlogic.co.uk
  P:    Mark Brown
  M:    broonie@opensource.wolfsonmicro.com
- T:    git git://opensource.wolfsonmicro.com/linux-2.6-asoc
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git
  L:    alsa-devel@alsa-project.org (subscribers-only)
  W:    http://alsa-project.org/main/index.php/ASoC
  S:    Supported
  F:    sound/soc/
+ F:    include/sound/soc*
  
  SPARC + UltraSPARC (sparc/sparc64)
  P:    David S. Miller
@@@ -5540,20 -5637,6 +5663,6 @@@ F:     drivers/misc/tifm
  F:    drivers/mmc/host/tifm_sd.c
  F:    include/linux/tifm.h
  
- TI OMAP MMC INTERFACE DRIVER
- P:    Carlos Aguiar, Anderson Briglia and Syed Khasim
- M:    linux-omap@vger.kernel.org
- W:    http://linux.omap.com
- W:    http://www.muru.com/linux/omap/
- S:    Maintained
- F:    drivers/mmc/host/omap.c
- TI OMAP RANDOM NUMBER GENERATOR SUPPORT
- P:    Deepak Saxena
- M:    dsaxena@plexity.net
- S:    Maintained
- F:    drivers/char/hw_random/omap-rng.c
  TIPC NETWORK LAYER
  P:    Per Liden
  M:    per.liden@ericsson.com
@@@ -5612,6 -5695,14 +5721,14 @@@ M:    ian@mnementh.co.u
  S:    Maintained
  F:    drivers/mmc/host/tmio_mmc.*
  
+ TMPFS (SHMEM FILESYSTEM)
+ P:    Hugh Dickins
+ M:    hugh.dickins@tiscali.co.uk
+ L:    linux-mm@kvack.org
+ S:    Maintained
+ F:    include/linux/shmem_fs.h
+ F:    mm/shmem.c
  TPM DEVICE DRIVER
  P:    Debora Velarde
  M:    debora@linux.vnet.ibm.com
@@@ -5637,6 -5728,7 +5754,7 @@@ P:      Alan Co
  M:    alan@lxorguk.ukuu.org.uk
  L:    linux-kernel@vger.kernel.org
  S:    Maintained
+ T:    stgit http://zeniv.linux.org.uk/~alan/ttydev/
  
  TULIP NETWORK DRIVERS
  P:    Grant Grundler
diff --combined arch/arm/kernel/signal.c
index 614c9f642878e4665b9f192c230a95e62b0e7106,442b87476f97105963df1862efcf089bc542f7d0..93bb4247b7ed019e92a6b64806c86af2fe338c7f
@@@ -426,9 -426,13 +426,13 @@@ setup_return(struct pt_regs *regs, stru
                 */
                thumb = handler & 1;
  
-               if (thumb)
+               if (thumb) {
                        cpsr |= PSR_T_BIT;
-               else
+ #if __LINUX_ARM_ARCH__ >= 7
+                       /* clear the If-Then Thumb-2 execution state */
+                       cpsr &= ~PSR_IT_MASK;
+ #endif
+               } else
                        cpsr &= ~PSR_T_BIT;
        }
  #endif
@@@ -532,7 -536,7 +536,7 @@@ setup_rt_frame(int usig, struct k_sigac
        return err;
  }
  
 -static inline void restart_syscall(struct pt_regs *regs)
 +static inline void setup_syscall_restart(struct pt_regs *regs)
  {
        regs->ARM_r0 = regs->ARM_ORIG_r0;
        regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
@@@ -567,7 -571,7 +571,7 @@@ handle_signal(unsigned long sig, struc
                        }
                        /* fallthrough */
                case -ERESTARTNOINTR:
 -                      restart_syscall(regs);
 +                      setup_syscall_restart(regs);
                }
        }
  
@@@ -691,7 -695,7 +695,7 @@@ static int do_signal(sigset_t *oldset, 
                if (regs->ARM_r0 == -ERESTARTNOHAND ||
                    regs->ARM_r0 == -ERESTARTSYS ||
                    regs->ARM_r0 == -ERESTARTNOINTR) {
 -                      restart_syscall(regs);
 +                      setup_syscall_restart(regs);
                }
        }
        single_step_set(current);
diff --combined arch/arm/mach-pxa/tosa.c
index 58ce807fe440d453465d2d51e0a32b37bc511a00,168267a5dfb3e3f80775599990c5d54bba81acc3..117ad5920e53aefb56ce25e683002498b0fecfc0
@@@ -31,6 -31,7 +31,6 @@@
  #include <linux/input.h>
  #include <linux/gpio.h>
  #include <linux/pda_power.h>
 -#include <linux/rfkill.h>
  #include <linux/spi/spi.h>
  
  #include <asm/setup.h>
@@@ -39,7 -40,7 +39,7 @@@
  #include <mach/pxa25x.h>
  #include <mach/reset.h>
  #include <mach/irda.h>
- #include <mach/i2c.h>
+ #include <plat/i2c.h>
  #include <mach/mmc.h>
  #include <mach/udc.h>
  #include <mach/tosa_bt.h>
@@@ -896,7 -897,7 +896,7 @@@ static void __init tosa_init(void
        gpio_set_wake(MFP_PIN_GPIO1, 1);
        /* We can't pass to gpio-keys since it will drop the Reset altfunc */
  
-       init_gpio_reset(TOSA_GPIO_ON_RESET, 0);
+       init_gpio_reset(TOSA_GPIO_ON_RESET, 0, 0);
  
        pm_power_off = tosa_poweroff;
        arm_pm_restart = tosa_restart;
index c12cd2f942549623426b55456afe047acbf95bfe,47dbfe298b43ab4002e591a4da7702daa982e6dc..77ee2867c8b4dd8cb768e394f9cd7de5762b1321
@@@ -203,13 -203,13 +203,13 @@@ dsp_rx_off_member(struct dsp *dsp
        else if (dsp->dtmf.software)
                rx_off = 0;
        /* echo in software */
 -      else if (dsp->echo && dsp->pcm_slot_tx < 0)
 +      else if (dsp->echo.software)
                rx_off = 0;
        /* bridge in software */
 -      else if (dsp->conf) {
 -              if (dsp->conf->software)
 -                      rx_off = 0;
 -      }
 +      else if (dsp->conf && dsp->conf->software)
 +              rx_off = 0;
 +      /* data is not required by user space and not required
 +       * for echo dtmf detection, soft-echo, soft-bridging */
  
        if (rx_off == dsp->rx_is_off)
                return;
@@@ -280,7 -280,7 +280,7 @@@ dsp_fill_empty(struct dsp *dsp
  static int
  dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
  {
 -      struct          sk_buff *nskb;
 +      struct sk_buff  *nskb;
        int ret = 0;
        int cont;
        u8 *data;
                                        "to %d\n", *((int *)data));
                        dsp->dtmf.treshold = (*(int *)data) * 10000;
                }
 +              dsp->dtmf.enable = 1;
                /* init goertzel */
                dsp_dtmf_goertzel_init(dsp);
  
                /* check dtmf hardware */
                dsp_dtmf_hardware(dsp);
 +              dsp_rx_off(dsp);
                break;
        case DTMF_TONE_STOP: /* turn off DTMF */
                if (dsp_debug & DEBUG_DSP_CORE)
                        printk(KERN_DEBUG "%s: stop dtmf\n", __func__);
 +              dsp->dtmf.enable = 0;
                dsp->dtmf.hardware = 0;
                dsp->dtmf.software = 0;
                break;
@@@ -417,7 -414,7 +417,7 @@@ tone_off
                dsp_rx_off(dsp);
                break;
        case DSP_ECHO_ON: /* enable echo */
 -              dsp->echo = 1; /* soft echo */
 +              dsp->echo.software = 1; /* soft echo */
                if (dsp_debug & DEBUG_DSP_CORE)
                        printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__);
                dsp_cmx_hardware(dsp->conf, dsp);
                        dsp_cmx_debug(dsp);
                break;
        case DSP_ECHO_OFF: /* disable echo */
 -              dsp->echo = 0;
 +              dsp->echo.software = 0;
 +              dsp->echo.hardware = 0;
                if (dsp_debug & DEBUG_DSP_CORE)
                        printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__);
                dsp_cmx_hardware(dsp->conf, dsp);
                        break;
                }
                dsp->cmx_delay = (*((int *)data)) << 3;
-                       /* miliseconds to samples */
+                       /* milliseconds to samples */
                if (dsp->cmx_delay >= (CMX_BUFF_HALF>>1))
                        /* clip to half of maximum usable buffer
                        (half of half buffer) */
                        dsp->pipeline.inuse = 1;
                        dsp_cmx_hardware(dsp->conf, dsp);
                        ret = dsp_pipeline_build(&dsp->pipeline,
 -                              len > 0 ? (char *)data : NULL);
 +                              len > 0 ? data : NULL);
                        dsp_cmx_hardware(dsp->conf, dsp);
                        dsp_rx_off(dsp);
                }
@@@ -661,10 -657,11 +661,10 @@@ get_features(struct mISDNchannel *ch
  static int
  dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
  {
 -      struct dsp                      *dsp = container_of(ch, struct dsp, ch);
 +      struct dsp              *dsp = container_of(ch, struct dsp, ch);
        struct mISDNhead        *hh;
        int                     ret = 0;
 -      u8                      *digits;
 -      int                     cont;
 +      u8                      *digits = NULL;
        u_long                  flags;
  
        hh = mISDN_HEAD_P(skb);
                        break;
                }
  
 +              spin_lock_irqsave(&dsp_lock, flags);
 +
                /* decrypt if enabled */
                if (dsp->bf_enable)
                        dsp_bf_decrypt(dsp, skb->data, skb->len);
                /* pipeline */
                if (dsp->pipeline.inuse)
                        dsp_pipeline_process_rx(&dsp->pipeline, skb->data,
 -                              skb->len);
 +                              skb->len, hh->id);
                /* change volume if requested */
                if (dsp->rx_volume)
                        dsp_change_volume(skb, dsp->rx_volume);
 -
                /* check if dtmf soft decoding is turned on */
                if (dsp->dtmf.software) {
                        digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
 -                              skb->len, (dsp_options&DSP_OPT_ULAW)?1:0);
 +                              skb->len, (dsp_options&DSP_OPT_ULAW) ? 1 : 0);
 +              }
 +              /* we need to process receive data if software */
 +              if (dsp->conf && dsp->conf->software) {
 +                      /* process data from card at cmx */
 +                      dsp_cmx_receive(dsp, skb);
 +              }
 +
 +              spin_unlock_irqrestore(&dsp_lock, flags);
 +
 +              /* send dtmf result, if any */
 +              if (digits) {
                        while (*digits) {
 +                              int k;
                                struct sk_buff *nskb;
                                if (dsp_debug & DEBUG_DSP_DTMF)
                                        printk(KERN_DEBUG "%s: digit"
                                            "(%c) to layer %s\n",
                                            __func__, *digits, dsp->name);
 -                              cont = DTMF_TONE_VAL | *digits;
 +                              k = *digits | DTMF_TONE_VAL;
                                nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
 -                                  MISDN_ID_ANY, sizeof(int), &cont,
 -                                  GFP_ATOMIC);
 +                                      MISDN_ID_ANY, sizeof(int), &k,
 +                                      GFP_ATOMIC);
                                if (nskb) {
                                        if (dsp->up) {
                                                if (dsp->up->send(
                                                    dsp->up, nskb))
 -                                              dev_kfree_skb(nskb);
 +                                                      dev_kfree_skb(nskb);
                                        } else
                                                dev_kfree_skb(nskb);
                                }
                                digits++;
                        }
                }
 -              /* we need to process receive data if software */
 -              spin_lock_irqsave(&dsp_lock, flags);
 -              if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) {
 -                      /* process data from card at cmx */
 -                      dsp_cmx_receive(dsp, skb);
 -              }
 -              spin_unlock_irqrestore(&dsp_lock, flags);
 -
                if (dsp->rx_disabled) {
                        /* if receive is not allowed */
                        break;
                                        if (dsp->up) {
                                                if (dsp->up->send(
                                                    dsp->up, nskb))
 -                                              dev_kfree_skb(nskb);
 +                                                      dev_kfree_skb(nskb);
                                        } else
                                                dev_kfree_skb(nskb);
                                }
@@@ -954,7 -946,7 +954,7 @@@ dsp_ctrl(struct mISDNchannel *ch, u_in
        int             err = 0;
  
        if (debug & DEBUG_DSP_CTRL)
 -      printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
 +              printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
  
        switch (cmd) {
        case OPEN_CHANNEL:
@@@ -1177,9 -1169,9 +1177,9 @@@ static int dsp_init(void
  
        /* init conversion tables */
        dsp_audio_generate_law_tables();
 -      dsp_silence = (dsp_options&DSP_OPT_ULAW)?0xff:0x2a;
 -      dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW)?dsp_audio_ulaw_to_s32:
 -              dsp_audio_alaw_to_s32;
 +      dsp_silence = (dsp_options&DSP_OPT_ULAW) ? 0xff : 0x2a;
 +      dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW) ?
 +              dsp_audio_ulaw_to_s32 : dsp_audio_alaw_to_s32;
        dsp_audio_generate_s2law_table();
        dsp_audio_generate_seven();
        dsp_audio_generate_mix_table();
diff --combined drivers/net/Kconfig
index 3f739cfd92fa9d1cd117786d7d8d21c2527cc8ce,3111b6c7cbc3225e039de507559cdb334cbb2c30..01f282cd0989d7123b0cb1b74477cded1571919d
@@@ -1,3 -1,4 +1,3 @@@
 -
  #
  # Network device configuration
  #
@@@ -25,6 -26,15 +25,6 @@@ menuconfig NETDEVICE
  # that for each of the symbols.
  if NETDEVICES
  
 -config COMPAT_NET_DEV_OPS
 -       default y
 -       bool "Enable older network device API compatibility"
 -       ---help---
 -          This option enables kernel compatibility with older network devices
 -          that do not use net_device_ops interface.
 -
 -        If unsure, say Y.
 -
  config IFB
        tristate "Intermediate Functional Block support"
        depends on NET_CLS_ACT
@@@ -516,16 -526,15 +516,16 @@@ config STNI
  config SH_ETH
        tristate "Renesas SuperH Ethernet support"
        depends on SUPERH && \
 -              (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7763 || \
 -               CPU_SUBTYPE_SH7619)
 +              (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
 +               CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
 +               CPU_SUBTYPE_SH7724)
        select CRC32
        select MII
        select MDIO_BITBANG
        select PHYLIB
        help
          Renesas SuperH Ethernet device driver.
 -        This driver support SH7710, SH7712, SH7763 and SH7619.
 +        This driver support SH7710, SH7712, SH7763, SH7619, and SH7724.
  
  config SUNLANCE
        tristate "Sun LANCE support"
@@@ -918,16 -927,6 +918,16 @@@ config NET_NET
          To compile this driver as a module, choose M here. The module
          will be called netx-eth.
  
 +config TI_DAVINCI_EMAC
 +      tristate "TI DaVinci EMAC Support"
 +      depends on ARM && ARCH_DAVINCI
 +      select PHYLIB
 +      help
 +        This driver supports TI's DaVinci Ethernet .
 +
 +        To compile this driver as a module, choose M here: the module
 +        will be called davinci_emac_driver.  This is recommended.
 +
  config DM9000
        tristate "DM9000 support"
        depends on ARM || BLACKFIN || MIPS
@@@ -1001,7 -1000,7 +1001,7 @@@ config SMC911
  
  config SMSC911X
        tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
 -      depends on ARM || SUPERH
 +      depends on ARM || SUPERH || BLACKFIN
        select CRC32
        select MII
        select PHYLIB
@@@ -1723,11 -1722,6 +1723,11 @@@ config TLA
  
          Please email feedback to <torben.mathiasen@compaq.com>.
  
 +config KS8842
 +      tristate "Micrel KSZ8842"
 +      help
 +        This platform driver is for Micrel KSZ8842 chip.
 +
  config VIA_RHINE
        tristate "VIA Rhine support"
        depends on NET_PCI && PCI
@@@ -1864,8 -1858,8 +1864,8 @@@ config 68360_ENE
          the Motorola 68360 processor.
  
  config FEC
 -      bool "FEC ethernet controller (of ColdFire CPUs)"
 -      depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27
 +      bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
 +      depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35
        help
          Say Y here if you want to use the built-in 10/100 Fast ethernet
          controller on some Motorola ColdFire and Freescale i.MX processors.
@@@ -1886,7 -1880,7 +1886,7 @@@ config FEC_MPC52x
        ---help---
          This option enables support for the MPC5200's on-chip
          Fast Ethernet Controller
-         If compiled as module, it will be called 'fec_mpc52xx.ko'.
+         If compiled as module, it will be called fec_mpc52xx.
  
  config FEC_MPC52xx_MDIO
        bool "MPC52xx FEC MDIO bus driver"
          (Motorola? industry standard).
          If your board uses an external PHY connected to FEC, enable this.
          If not sure, enable.
-         If compiled as module, it will be called 'fec_mpc52xx_phy.ko'.
+         If compiled as module, it will be called fec_mpc52xx_phy.
  
  config NE_H8300
        tristate "NE2000 compatible support for H8/300"
@@@ -2270,6 -2264,17 +2270,17 @@@ config BNX
          To compile this driver as a module, choose M here: the module
          will be called bnx2.  This is recommended.
  
+ config CNIC
+       tristate "Broadcom CNIC support"
+       depends on BNX2
+       depends on UIO
+       help
+         This driver supports offload features of Broadcom NetXtremeII
+         gigabit Ethernet cards.
+         To compile this driver as a module, choose M here: the module
+         will be called cnic.  This is recommended.
  config SPIDER_NET
        tristate "Spider Gigabit Ethernet driver"
        depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB)
@@@ -2357,7 -2362,7 +2368,7 @@@ config UGETH_TX_ON_DEMAN
  
  config MV643XX_ETH
        tristate "Marvell Discovery (643XX) and Orion ethernet support"
 -      depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION
 +      depends on MV64X60 || PPC32 || PLAT_ORION
        select INET_LRO
        select PHYLIB
        help
          Some boards that use the Discovery chipset are the Momenco
          Ocelot C and Jaguar ATX and Pegasos II.
  
 +config XILINX_LL_TEMAC
 +      tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
 +      select PHYLIB
 +      depends on PPC_DCR_NATIVE
 +      help
 +        This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
 +        core used in Xilinx Spartan and Virtex FPGAs
 +
  config QLA3XXX
        tristate "QLogic QLA3XXX Network Driver Support"
        depends on PCI
@@@ -2449,14 -2446,10 +2460,14 @@@ menuconfig NETDEV_1000
  
  if NETDEV_10000
  
 +config MDIO
 +      tristate
 +
  config CHELSIO_T1
          tristate "Chelsio 10Gb Ethernet support"
          depends on PCI
        select CRC32
 +      select MDIO
          help
            This driver supports Chelsio gigabit and 10-gigabit
            Ethernet cards. More information about adapter features and
@@@ -2489,7 -2482,6 +2500,7 @@@ config CHELSIO_T
        tristate "Chelsio Communications T3 10Gb Ethernet support"
        depends on CHELSIO_T3_DEPENDS
        select FW_LOADER
 +      select MDIO
        help
          This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
          adapters.
@@@ -2525,7 -2517,6 +2536,7 @@@ config ENI
  config IXGBE
        tristate "Intel(R) 10GbE PCI Express adapters support"
        depends on PCI && INET
 +      select MDIO
        ---help---
          This driver supports Intel(R) 10GbE PCI Express family of
          adapters.  For more information on how to identify your adapter, go
@@@ -2688,7 -2679,6 +2699,7 @@@ config TEHUT
  config BNX2X
        tristate "Broadcom NetXtremeII 10Gb support"
        depends on PCI
 +      select FW_LOADER
        select ZLIB_INFLATE
        select LIBCRC32C
        help
@@@ -2725,8 -2715,6 +2736,8 @@@ source "drivers/net/wan/Kconfig
  
  source "drivers/atm/Kconfig"
  
 +source "drivers/ieee802154/Kconfig"
 +
  source "drivers/s390/net/Kconfig"
  
  config XEN_NETDEV_FRONTEND
diff --combined drivers/net/Makefile
index 1c378dd5933e665214863ee0d97b6657e21c2f84,db30ebd7b262336bb3949da5db58e7173d4bfa64..d366fb2b40e99e2065408160243c12da9cc95c33
@@@ -2,8 -2,6 +2,8 @@@
  # Makefile for the Linux network (ethercard) device drivers.
  #
  
 +obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
 +
  obj-$(CONFIG_E1000) += e1000/
  obj-$(CONFIG_E1000E) += e1000e/
  obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
@@@ -75,6 -73,7 +75,7 @@@ obj-$(CONFIG_STNIC) += stnic.o 8390.
  obj-$(CONFIG_FEALNX) += fealnx.o
  obj-$(CONFIG_TIGON3) += tg3.o
  obj-$(CONFIG_BNX2) += bnx2.o
+ obj-$(CONFIG_CNIC) += cnic.o
  obj-$(CONFIG_BNX2X) += bnx2x.o
  bnx2x-objs := bnx2x_main.o bnx2x_link.o
  spidernet-y += spider_net.o spider_net_ethtool.o
@@@ -86,7 -85,6 +87,7 @@@ obj-$(CONFIG_TC35815) += tc35815.
  obj-$(CONFIG_SKGE) += skge.o
  obj-$(CONFIG_SKY2) += sky2.o
  obj-$(CONFIG_SKFP) += skfp/
 +obj-$(CONFIG_KS8842)  += ks8842.o
  obj-$(CONFIG_VIA_RHINE) += via-rhine.o
  obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
  obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
@@@ -98,7 -96,6 +99,7 @@@ obj-$(CONFIG_SH_ETH) += sh_eth.
  #
  
  obj-$(CONFIG_MII) += mii.o
 +obj-$(CONFIG_MDIO) += mdio.o
  obj-$(CONFIG_PHYLIB) += phy/
  
  obj-$(CONFIG_SUNDANCE) += sundance.o
@@@ -138,8 -135,6 +139,8 @@@ obj-$(CONFIG_AX88796) += ax88796.
  
  obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
  obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
 +ll_temac-objs := ll_temac_main.o ll_temac_mdio.o
 +obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
  obj-$(CONFIG_QLA3XXX) += qla3xxx.o
  obj-$(CONFIG_QLGE) += qlge/
  
index 1fcf8388b1c89c2f5574de818f8a338dbe9a5549,b6d188115caff792889899236972a5926ace1de8..6f42ad728915b2683ee9ee66a9e11562c890453e
@@@ -456,7 -456,8 +456,8 @@@ static inline void queue_put_desc(unsig
        debug_desc(phys, desc);
        BUG_ON(phys & 0x1F);
        qmgr_put_entry(queue, phys);
-       BUG_ON(qmgr_stat_overflow(queue));
+       /* Don't check for queue overflow here, we've allocated sufficient
+          length and queues >= 32 don't support this check anyway. */
  }
  
  
@@@ -512,8 -513,8 +513,8 @@@ static int eth_poll(struct napi_struct 
  #endif
                        napi_complete(napi);
                        qmgr_enable_irq(rxq);
-                       if (!qmgr_stat_empty(rxq) &&
-                           napi_reschedule(napi)) {
+                       if (!qmgr_stat_below_low_watermark(rxq) &&
+                           napi_reschedule(napi)) { /* not empty again */
  #if DEBUG_RX
                                printk(KERN_DEBUG "%s: eth_poll"
                                       " napi_reschedule successed\n",
                dma_unmap_single(&dev->dev, desc->data - NET_IP_ALIGN,
                                 RX_BUFF_SIZE, DMA_FROM_DEVICE);
  #else
 -              dma_sync_single(&dev->dev, desc->data - NET_IP_ALIGN,
 -                              RX_BUFF_SIZE, DMA_FROM_DEVICE);
 +              dma_sync_single_for_cpu(&dev->dev, desc->data - NET_IP_ALIGN,
 +                                      RX_BUFF_SIZE, DMA_FROM_DEVICE);
                memcpy_swab32((u32 *)skb->data, (u32 *)port->rx_buff_tab[n],
                              ALIGN(NET_IP_ALIGN + desc->pkt_len, 4) / 4);
  #endif
@@@ -630,9 -631,9 +631,9 @@@ static void eth_txdone_irq(void *unused
                        port->tx_buff_tab[n_desc] = NULL;
                }
  
-               start = qmgr_stat_empty(port->plat->txreadyq);
+               start = qmgr_stat_below_low_watermark(port->plat->txreadyq);
                queue_put_desc(port->plat->txreadyq, phys, desc);
-               if (start) {
+               if (start) { /* TX-ready queue was empty */
  #if DEBUG_TX
                        printk(KERN_DEBUG "%s: eth_txdone_irq xmit ready\n",
                               port->netdev->name);
@@@ -708,13 -709,14 +709,14 @@@ static int eth_xmit(struct sk_buff *skb
        queue_put_desc(TX_QUEUE(port->id), tx_desc_phys(port, n), desc);
        dev->trans_start = jiffies;
  
-       if (qmgr_stat_empty(txreadyq)) {
+       if (qmgr_stat_below_low_watermark(txreadyq)) { /* empty */
  #if DEBUG_TX
                printk(KERN_DEBUG "%s: eth_xmit queue full\n", dev->name);
  #endif
                netif_stop_queue(dev);
                /* we could miss TX ready interrupt */
-               if (!qmgr_stat_empty(txreadyq)) {
+               /* really empty in fact */
+               if (!qmgr_stat_below_low_watermark(txreadyq)) {
  #if DEBUG_TX
                        printk(KERN_DEBUG "%s: eth_xmit ready again\n",
                               dev->name);
@@@ -814,29 -816,29 +816,29 @@@ static int request_queues(struct port *
        int err;
  
        err = qmgr_request_queue(RXFREE_QUEUE(port->id), RX_DESCS, 0, 0,
-                           "%s:RX-free", port->netdev->name);
+                                "%s:RX-free", port->netdev->name);
        if (err)
                return err;
  
        err = qmgr_request_queue(port->plat->rxq, RX_DESCS, 0, 0,
-                           "%s:RX", port->netdev->name);
+                                "%s:RX", port->netdev->name);
        if (err)
                goto rel_rxfree;
  
        err = qmgr_request_queue(TX_QUEUE(port->id), TX_DESCS, 0, 0,
-                           "%s:TX", port->netdev->name);
+                                "%s:TX", port->netdev->name);
        if (err)
                goto rel_rx;
  
        err = qmgr_request_queue(port->plat->txreadyq, TX_DESCS, 0, 0,
-                           "%s:TX-ready", port->netdev->name);
+                                "%s:TX-ready", port->netdev->name);
        if (err)
                goto rel_tx;
  
        /* TX-done queue handles skbs sent out by the NPEs */
        if (!ports_open) {
                err = qmgr_request_queue(TXDONE_QUEUE, TXDONE_QUEUE_LEN, 0, 0,
-                                   "%s:TX-done", DRV_NAME);
+                                        "%s:TX-done", DRV_NAME);
                if (err)
                        goto rel_txready;
        }
@@@ -1149,7 -1151,7 +1151,7 @@@ static int __devinit eth_init_one(struc
        struct net_device *dev;
        struct eth_plat_info *plat = pdev->dev.platform_data;
        u32 regs_phys;
 -      char phy_id[BUS_ID_SIZE];
 +      char phy_id[MII_BUS_ID_SIZE + 3];
        int err;
  
        if (!(dev = alloc_etherdev(sizeof(struct port))))
        __raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
        udelay(50);
  
 -      snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy);
 +      snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy);
        port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
                                   PHY_INTERFACE_MODE_MII);
        if ((err = IS_ERR(port->phydev)))
diff --combined drivers/net/b44.h
index 0443f6801f60517373d5b93cc87ba489db8887f4,d24158e7f3097261633d22a342cbdb249e415d01..e1905a49279ff584a1328eadc371284814eeacac
@@@ -97,7 -97,7 +97,7 @@@
  #define B44_DMARX_STAT        0x021CUL /* DMA RX Current Active Desc. + Status */
  #define  DMARX_STAT_CDMASK    0x00000fff /* Current Descriptor Mask */
  #define  DMARX_STAT_SMASK     0x0000f000 /* State Mask */
- #define  DMARX_STAT_SDISABLED 0x00000000 /* State Disbaled */
+ #define  DMARX_STAT_SDISABLED 0x00000000 /* State Disabled */
  #define  DMARX_STAT_SACTIVE   0x00001000 /* State Active */
  #define  DMARX_STAT_SIDLE     0x00002000 /* State Idle Wait */
  #define  DMARX_STAT_SSTOPPED  0x00003000 /* State Stopped */
@@@ -384,6 -384,7 +384,6 @@@ struct b44 
  
        struct timer_list       timer;
  
 -      struct net_device_stats stats;
        struct b44_hw_stats     hw_stats;
  
        struct ssb_device       *sdev;
diff --combined drivers/net/bnx2.c
index f99e17e0a319248e1ea7e1be4bfa627939167c99,3f5fcb0156a180a49977f200b7a16fe5e19f6a38..7e3738112c4e64297c00b0c74a7658d9df4a00c8
  #include <linux/cache.h>
  #include <linux/firmware.h>
  #include <linux/log2.h>
 +#include <linux/list.h>
  
+ #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
+ #define BCM_CNIC 1
+ #include "cnic_if.h"
+ #endif
  #include "bnx2.h"
  #include "bnx2_fw.h"
  
@@@ -316,6 -319,158 +320,158 @@@ bnx2_ctx_wr(struct bnx2 *bp, u32 cid_ad
        spin_unlock_bh(&bp->indirect_lock);
  }
  
+ #ifdef BCM_CNIC
+ static int
+ bnx2_drv_ctl(struct net_device *dev, struct drv_ctl_info *info)
+ {
+       struct bnx2 *bp = netdev_priv(dev);
+       struct drv_ctl_io *io = &info->data.io;
+       switch (info->cmd) {
+       case DRV_CTL_IO_WR_CMD:
+               bnx2_reg_wr_ind(bp, io->offset, io->data);
+               break;
+       case DRV_CTL_IO_RD_CMD:
+               io->data = bnx2_reg_rd_ind(bp, io->offset);
+               break;
+       case DRV_CTL_CTX_WR_CMD:
+               bnx2_ctx_wr(bp, io->cid_addr, io->offset, io->data);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+ }
+ static void bnx2_setup_cnic_irq_info(struct bnx2 *bp)
+ {
+       struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+       int sb_id;
+       if (bp->flags & BNX2_FLAG_USING_MSIX) {
+               cp->drv_state |= CNIC_DRV_STATE_USING_MSIX;
+               bnapi->cnic_present = 0;
+               sb_id = bp->irq_nvecs;
+               cp->irq_arr[0].irq_flags |= CNIC_IRQ_FL_MSIX;
+       } else {
+               cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX;
+               bnapi->cnic_tag = bnapi->last_status_idx;
+               bnapi->cnic_present = 1;
+               sb_id = 0;
+               cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX;
+       }
+       cp->irq_arr[0].vector = bp->irq_tbl[sb_id].vector;
+       cp->irq_arr[0].status_blk = (void *)
+               ((unsigned long) bnapi->status_blk.msi +
+               (BNX2_SBLK_MSIX_ALIGN_SIZE * sb_id));
+       cp->irq_arr[0].status_blk_num = sb_id;
+       cp->num_irq = 1;
+ }
+ static int bnx2_register_cnic(struct net_device *dev, struct cnic_ops *ops,
+                             void *data)
+ {
+       struct bnx2 *bp = netdev_priv(dev);
+       struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+       if (ops == NULL)
+               return -EINVAL;
+       if (cp->drv_state & CNIC_DRV_STATE_REGD)
+               return -EBUSY;
+       bp->cnic_data = data;
+       rcu_assign_pointer(bp->cnic_ops, ops);
+       cp->num_irq = 0;
+       cp->drv_state = CNIC_DRV_STATE_REGD;
+       bnx2_setup_cnic_irq_info(bp);
+       return 0;
+ }
+ static int bnx2_unregister_cnic(struct net_device *dev)
+ {
+       struct bnx2 *bp = netdev_priv(dev);
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+       struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+       cp->drv_state = 0;
+       bnapi->cnic_present = 0;
+       rcu_assign_pointer(bp->cnic_ops, NULL);
+       synchronize_rcu();
+       return 0;
+ }
+ struct cnic_eth_dev *bnx2_cnic_probe(struct net_device *dev)
+ {
+       struct bnx2 *bp = netdev_priv(dev);
+       struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+       cp->drv_owner = THIS_MODULE;
+       cp->chip_id = bp->chip_id;
+       cp->pdev = bp->pdev;
+       cp->io_base = bp->regview;
+       cp->drv_ctl = bnx2_drv_ctl;
+       cp->drv_register_cnic = bnx2_register_cnic;
+       cp->drv_unregister_cnic = bnx2_unregister_cnic;
+       return cp;
+ }
+ EXPORT_SYMBOL(bnx2_cnic_probe);
+ static void
+ bnx2_cnic_stop(struct bnx2 *bp)
+ {
+       struct cnic_ops *c_ops;
+       struct cnic_ctl_info info;
+       rcu_read_lock();
+       c_ops = rcu_dereference(bp->cnic_ops);
+       if (c_ops) {
+               info.cmd = CNIC_CTL_STOP_CMD;
+               c_ops->cnic_ctl(bp->cnic_data, &info);
+       }
+       rcu_read_unlock();
+ }
+ static void
+ bnx2_cnic_start(struct bnx2 *bp)
+ {
+       struct cnic_ops *c_ops;
+       struct cnic_ctl_info info;
+       rcu_read_lock();
+       c_ops = rcu_dereference(bp->cnic_ops);
+       if (c_ops) {
+               if (!(bp->flags & BNX2_FLAG_USING_MSIX)) {
+                       struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+                       bnapi->cnic_tag = bnapi->last_status_idx;
+               }
+               info.cmd = CNIC_CTL_START_CMD;
+               c_ops->cnic_ctl(bp->cnic_data, &info);
+       }
+       rcu_read_unlock();
+ }
+ #else
+ static void
+ bnx2_cnic_stop(struct bnx2 *bp)
+ {
+ }
+ static void
+ bnx2_cnic_start(struct bnx2 *bp)
+ {
+ }
+ #endif
  static int
  bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
  {
@@@ -489,6 -644,7 +645,7 @@@ bnx2_napi_enable(struct bnx2 *bp
  static void
  bnx2_netif_stop(struct bnx2 *bp)
  {
+       bnx2_cnic_stop(bp);
        bnx2_disable_int_sync(bp);
        if (netif_running(bp->dev)) {
                bnx2_napi_disable(bp);
@@@ -505,6 -661,7 +662,7 @@@ bnx2_netif_start(struct bnx2 *bp
                        netif_tx_wake_all_queues(bp->dev);
                        bnx2_napi_enable(bp);
                        bnx2_enable_int(bp);
+                       bnx2_cnic_start(bp);
                }
        }
  }
@@@ -546,7 -703,8 +704,7 @@@ bnx2_free_rx_mem(struct bnx2 *bp
                                                    rxr->rx_desc_mapping[j]);
                        rxr->rx_desc_ring[j] = NULL;
                }
 -              if (rxr->rx_buf_ring)
 -                      vfree(rxr->rx_buf_ring);
 +              vfree(rxr->rx_buf_ring);
                rxr->rx_buf_ring = NULL;
  
                for (j = 0; j < bp->rx_max_pg_ring; j++) {
                                                    rxr->rx_pg_desc_mapping[j]);
                        rxr->rx_pg_desc_ring[j] = NULL;
                }
 -              if (rxr->rx_pg_ring)
 -                      vfree(rxr->rx_pg_ring);
 +              vfree(rxr->rx_pg_ring);
                rxr->rx_pg_ring = NULL;
        }
  }
@@@ -2629,15 -2788,14 +2787,15 @@@ bnx2_tx_int(struct bnx2 *bp, struct bnx
                tx_buf = &txr->tx_buf_ring[sw_ring_cons];
                skb = tx_buf->skb;
  
 +              /* prefetch skb_end_pointer() to speedup skb_shinfo(skb) */
 +              prefetch(&skb->end);
 +
                /* partial BD completions possible with TSO packets */
 -              if (skb_is_gso(skb)) {
 +              if (tx_buf->is_gso) {
                        u16 last_idx, last_ring_idx;
  
 -                      last_idx = sw_cons +
 -                              skb_shinfo(skb)->nr_frags + 1;
 -                      last_ring_idx = sw_ring_cons +
 -                              skb_shinfo(skb)->nr_frags + 1;
 +                      last_idx = sw_cons + tx_buf->nr_frags + 1;
 +                      last_ring_idx = sw_ring_cons + tx_buf->nr_frags + 1;
                        if (unlikely(last_ring_idx >= MAX_TX_DESC_CNT)) {
                                last_idx++;
                        }
                skb_dma_unmap(&bp->pdev->dev, skb, DMA_TO_DEVICE);
  
                tx_buf->skb = NULL;
 -              last = skb_shinfo(skb)->nr_frags;
 +              last = tx_buf->nr_frags;
  
                for (i = 0; i < last; i++) {
                        sw_cons = NEXT_TX_BD(sw_cons);
                if (tx_pkt == budget)
                        break;
  
 -              hw_cons = bnx2_get_hw_tx_cons(bnapi);
 +              if (hw_cons == sw_cons)
 +                      hw_cons = bnx2_get_hw_tx_cons(bnapi);
        }
  
        txr->hw_tx_cons = hw_cons;
@@@ -3165,6 -3322,11 +3323,11 @@@ bnx2_has_work(struct bnx2_napi *bnapi
        if (bnx2_has_fast_work(bnapi))
                return 1;
  
+ #ifdef BCM_CNIC
+       if (bnapi->cnic_present && (bnapi->cnic_tag != sblk->status_idx))
+               return 1;
+ #endif
        if ((sblk->status_attn_bits & STATUS_ATTN_EVENTS) !=
            (sblk->status_attn_bits_ack & STATUS_ATTN_EVENTS))
                return 1;
@@@ -3194,6 -3356,23 +3357,23 @@@ bnx2_chk_missed_msi(struct bnx2 *bp
        bp->idle_chk_status_idx = bnapi->last_status_idx;
  }
  
+ #ifdef BCM_CNIC
+ static void bnx2_poll_cnic(struct bnx2 *bp, struct bnx2_napi *bnapi)
+ {
+       struct cnic_ops *c_ops;
+       if (!bnapi->cnic_present)
+               return;
+       rcu_read_lock();
+       c_ops = rcu_dereference(bp->cnic_ops);
+       if (c_ops)
+               bnapi->cnic_tag = c_ops->cnic_handler(bp->cnic_data,
+                                                     bnapi->status_blk.msi);
+       rcu_read_unlock();
+ }
+ #endif
  static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi)
  {
        struct status_block *sblk = bnapi->status_blk.msi;
@@@ -3268,6 -3447,10 +3448,10 @@@ static int bnx2_poll(struct napi_struc
  
                work_done = bnx2_poll_work(bp, bnapi, work_done, budget);
  
+ #ifdef BCM_CNIC
+               bnx2_poll_cnic(bp, bnapi);
+ #endif
                /* bnapi->last_status_idx is used below to tell the hw how
                 * much work has been processed, so we must read it before
                 * checking for more work.
@@@ -3309,7 -3492,7 +3493,7 @@@ bnx2_set_rx_mode(struct net_device *dev
  {
        struct bnx2 *bp = netdev_priv(dev);
        u32 rx_mode, sort_mode;
 -      struct dev_addr_list *uc_ptr;
 +      struct netdev_hw_addr *ha;
        int i;
  
        if (!netif_running(dev))
                sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN;
        }
  
 -      uc_ptr = NULL;
        if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) {
                rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
                sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
                             BNX2_RPM_SORT_USER0_PROM_VLAN;
        } else if (!(dev->flags & IFF_PROMISC)) {
 -              uc_ptr = dev->uc_list;
 -
                /* Add all entries into to the match filter list */
 -              for (i = 0; i < dev->uc_count; i++) {
 -                      bnx2_set_mac_addr(bp, uc_ptr->da_addr,
 +              i = 0;
 +              list_for_each_entry(ha, &dev->uc_list, list) {
 +                      bnx2_set_mac_addr(bp, ha->addr,
                                          i + BNX2_START_UNICAST_ADDRESS_INDEX);
                        sort_mode |= (1 <<
                                      (i + BNX2_START_UNICAST_ADDRESS_INDEX));
 -                      uc_ptr = uc_ptr->next;
 +                      i++;
                }
  
        }
@@@ -4631,8 -4816,11 +4815,11 @@@ bnx2_init_chip(struct bnx2 *bp
        val = REG_RD(bp, BNX2_MQ_CONFIG);
        val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE;
        val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
-       if (CHIP_ID(bp) == CHIP_ID_5709_A0 || CHIP_ID(bp) == CHIP_ID_5709_A1)
-               val |= BNX2_MQ_CONFIG_HALT_DIS;
+       if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+               val |= BNX2_MQ_CONFIG_BIN_MQ_MODE;
+               if (CHIP_REV(bp) == CHIP_REV_Ax)
+                       val |= BNX2_MQ_CONFIG_HALT_DIS;
+       }
  
        REG_WR(bp, BNX2_MQ_CONFIG, val);
  
@@@ -5485,7 -5673,7 +5672,7 @@@ bnx2_run_loopback(struct bnx2 *bp, int 
                dev_kfree_skb(skb);
                return -EIO;
        }
 -      map = skb_shinfo(skb)->dma_maps[0];
 +      map = skb_shinfo(skb)->dma_head;
  
        REG_WR(bp, BNX2_HC_COMMAND,
               bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
@@@ -6165,7 -6353,7 +6352,7 @@@ bnx2_start_xmit(struct sk_buff *skb, st
        }
  
        sp = skb_shinfo(skb);
 -      mapping = sp->dma_maps[0];
 +      mapping = sp->dma_head;
  
        tx_buf = &txr->tx_buf_ring[ring_prod];
        tx_buf->skb = skb;
        txbd->tx_bd_vlan_tag_flags = vlan_tag_flags | TX_BD_FLAGS_START;
  
        last_frag = skb_shinfo(skb)->nr_frags;
 +      tx_buf->nr_frags = last_frag;
 +      tx_buf->is_gso = skb_is_gso(skb);
  
        for (i = 0; i < last_frag; i++) {
                skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
                txbd = &txr->tx_desc_ring[ring_prod];
  
                len = frag->size;
 -              mapping = sp->dma_maps[i + 1];
 +              mapping = sp->dma_maps[i];
  
                txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
                txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
        mmiowb();
  
        txr->tx_prod = prod;
 -      dev->trans_start = jiffies;
  
        if (unlikely(bnx2_tx_avail(bp, txr) <= MAX_SKB_FRAGS)) {
                netif_tx_stop_queue(txq);
@@@ -7471,7 -7658,7 +7658,7 @@@ bnx2_init_board(struct pci_dev *pdev, s
        INIT_WORK(&bp->reset_task, bnx2_reset_task);
  
        dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0);
-       mem_len = MB_GET_CID_ADDR(TX_TSS_CID + TX_MAX_TSS_RINGS);
+       mem_len = MB_GET_CID_ADDR(TX_TSS_CID + TX_MAX_TSS_RINGS + 1);
        dev->mem_end = dev->mem_start + mem_len;
        dev->irq = pdev->irq;
  
diff --combined drivers/net/bnx2.h
index 026ed1c846983179c9831bda7afe542ad52b8865,a1ff739bc9b5e5709f6e3093bf516ace7d148515..f1edfaa9e56acd87afd0cb41aa20cd23248f7880
@@@ -361,6 -361,9 +361,9 @@@ struct l2_fhdr 
  #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE      (1<<28)
  
  #define BNX2_L2CTX_HOST_BDIDX                         0x00000004
+ #define BNX2_L2CTX_STATUSB_NUM_SHIFT                   16
+ #define BNX2_L2CTX_STATUSB_NUM(sb_id)                  \
+       (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_STATUSB_NUM_SHIFT) : 0)
  #define BNX2_L2CTX_HOST_BSEQ                          0x00000008
  #define BNX2_L2CTX_NX_BSEQ                            0x0000000c
  #define BNX2_L2CTX_NX_BDHADDR_HI                      0x00000010
  #define BNX2_RXP_FTQ_CTL_CUR_DEPTH                     (0x3ffL<<22)
  
  #define BNX2_RXP_SCRATCH                              0x000e0000
+ #define BNX2_RXP_SCRATCH_RXP_FLOOD                     0x000e0024
  #define BNX2_RXP_SCRATCH_RSS_TBL_SZ                    0x000e0038
  #define BNX2_RXP_SCRATCH_RSS_TBL                       0x000e003c
  #define BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES           128
@@@ -6552,8 -6556,6 +6556,8 @@@ struct sw_pg 
  
  struct sw_tx_bd {
        struct sk_buff          *skb;
 +      unsigned short          is_gso;
 +      unsigned short          nr_frags;
  };
  
  #define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT)
@@@ -6680,6 -6682,11 +6684,11 @@@ struct bnx2_napi 
        u32                     last_status_idx;
        u32                     int_num;
  
+ #ifdef BCM_CNIC
+       u32                     cnic_tag;
+       int                     cnic_present;
+ #endif
        struct bnx2_rx_ring_info        rx_ring;
        struct bnx2_tx_ring_info        tx_ring;
  };
@@@ -6729,6 -6736,11 +6738,11 @@@ struct bnx2 
        int             tx_ring_size;
        u32             tx_wake_thresh;
  
+ #ifdef BCM_CNIC
+       struct cnic_ops         *cnic_ops;
+       void                    *cnic_data;
+ #endif
        /* End of fields used in the performance code paths. */
  
        unsigned int            current_interval;
  
        u32                     idle_chk_status_idx;
  
+ #ifdef BCM_CNIC
+       struct cnic_eth_dev     cnic_eth_dev;
+ #endif
        const struct firmware   *mips_firmware;
        const struct firmware   *rv2p_firmware;
  };
diff --combined drivers/net/e100.c
index e52a2018e91e3e59db5088cd8a91f70045893a86,af5364f4955065421f50a30180ba378915dcc50a..f7929e89eb036128d715523e26a78f957c3ce071
   *    FIXES:
   * 2005/12/02 - Michael O'Donnell <Michael.ODonnell at stratus dot com>
   *    - Stratus87247: protect MDI control register manipulations
 + * 2009/06/01 - Andreas Mohr <andi at lisas dot de>
 + *      - add clean lowlevel I/O emulation for cards with MII-lacking PHYs
   */
  
  #include <linux/module.h>
@@@ -374,7 -372,6 +374,7 @@@ enum eeprom_op 
  
  enum eeprom_offsets {
        eeprom_cnfg_mdix  = 0x03,
 +      eeprom_phy_iface  = 0x06,
        eeprom_id         = 0x0A,
        eeprom_config_asf = 0x0D,
        eeprom_smbus_addr = 0x90,
@@@ -384,18 -381,6 +384,18 @@@ enum eeprom_cnfg_mdix 
        eeprom_mdix_enabled = 0x0080,
  };
  
 +enum eeprom_phy_iface {
 +      NoSuchPhy = 0,
 +      I82553AB,
 +      I82553C,
 +      I82503,
 +      DP83840,
 +      S80C240,
 +      S80C24,
 +      I82555,
 +      DP83840A = 10,
 +};
 +
  enum eeprom_id {
        eeprom_id_wol = 0x0020,
  };
@@@ -560,7 -545,6 +560,7 @@@ struct nic 
        u32 msg_enable                          ____cacheline_aligned;
        struct net_device *netdev;
        struct pci_dev *pdev;
 +      u16 (*mdio_ctrl)(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data);
  
        struct rx *rxs                          ____cacheline_aligned;
        struct rx *rx_to_use;
@@@ -915,21 -899,7 +915,21 @@@ err_unlock
        return err;
  }
  
 -static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
 +static int mdio_read(struct net_device *netdev, int addr, int reg)
 +{
 +      struct nic *nic = netdev_priv(netdev);
 +      return nic->mdio_ctrl(nic, addr, mdi_read, reg, 0);
 +}
 +
 +static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
 +{
 +      struct nic *nic = netdev_priv(netdev);
 +
 +      nic->mdio_ctrl(nic, addr, mdi_write, reg, data);
 +}
 +
 +/* the standard mdio_ctrl() function for usual MII-compliant hardware */
 +static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
  {
        u32 data_out = 0;
        unsigned int i;
        return (u16)data_out;
  }
  
 -static int mdio_read(struct net_device *netdev, int addr, int reg)
 -{
 -      return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0);
 +/* slightly tweaked mdio_ctrl() function for phy_82552_v specifics */
 +static u16 mdio_ctrl_phy_82552_v(struct nic *nic,
 +                               u32 addr,
 +                               u32 dir,
 +                               u32 reg,
 +                               u16 data)
 +{
 +      if ((reg == MII_BMCR) && (dir == mdi_write)) {
 +              if (data & (BMCR_ANRESTART | BMCR_ANENABLE)) {
 +                      u16 advert = mdio_read(nic->netdev, nic->mii.phy_id,
 +                                                      MII_ADVERTISE);
 +
 +                      /*
 +                       * Workaround Si issue where sometimes the part will not
 +                       * autoneg to 100Mbps even when advertised.
 +                       */
 +                      if (advert & ADVERTISE_100FULL)
 +                              data |= BMCR_SPEED100 | BMCR_FULLDPLX;
 +                      else if (advert & ADVERTISE_100HALF)
 +                              data |= BMCR_SPEED100;
 +              }
 +      }
 +      return mdio_ctrl_hw(nic, addr, dir, reg, data);
  }
  
 -static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
 -{
 -      struct nic *nic = netdev_priv(netdev);
 -
 -      if  ((nic->phy == phy_82552_v) && (reg == MII_BMCR) &&
 -           (data & (BMCR_ANRESTART | BMCR_ANENABLE))) {
 -              u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
 -
 -              /*
 -               * Workaround Si issue where sometimes the part will not
 -               * autoneg to 100Mbps even when advertised.
 -               */
 -              if (advert & ADVERTISE_100FULL)
 -                      data |= BMCR_SPEED100 | BMCR_FULLDPLX;
 -              else if (advert & ADVERTISE_100HALF)
 -                      data |= BMCR_SPEED100;
 +/* Fully software-emulated mdio_ctrl() function for cards without
 + * MII-compliant PHYs.
 + * For now, this is mainly geared towards 80c24 support; in case of further
 + * requirements for other types (i82503, ...?) either extend this mechanism
 + * or split it, whichever is cleaner.
 + */
 +static u16 mdio_ctrl_phy_mii_emulated(struct nic *nic,
 +                                    u32 addr,
 +                                    u32 dir,
 +                                    u32 reg,
 +                                    u16 data)
 +{
 +      /* might need to allocate a netdev_priv'ed register array eventually
 +       * to be able to record state changes, but for now
 +       * some fully hardcoded register handling ought to be ok I guess. */
 +
 +      if (dir == mdi_read) {
 +              switch (reg) {
 +              case MII_BMCR:
 +                      /* Auto-negotiation, right? */
 +                      return  BMCR_ANENABLE |
 +                              BMCR_FULLDPLX;
 +              case MII_BMSR:
 +                      return  BMSR_LSTATUS /* for mii_link_ok() */ |
 +                              BMSR_ANEGCAPABLE |
 +                              BMSR_10FULL;
 +              case MII_ADVERTISE:
 +                      /* 80c24 is a "combo card" PHY, right? */
 +                      return  ADVERTISE_10HALF |
 +                              ADVERTISE_10FULL;
 +              default:
 +                      DPRINTK(HW, DEBUG,
 +              "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n",
 +              dir == mdi_read ? "READ" : "WRITE", addr, reg, data);
 +                      return 0xFFFF;
 +              }
 +      } else {
 +              switch (reg) {
 +              default:
 +                      DPRINTK(HW, DEBUG,
 +              "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n",
 +              dir == mdi_read ? "READ" : "WRITE", addr, reg, data);
 +                      return 0xFFFF;
 +              }
        }
 -
 -      mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
 +}
 +static inline int e100_phy_supports_mii(struct nic *nic)
 +{
 +      /* for now, just check it by comparing whether we
 +         are using MII software emulation.
 +      */
 +      return (nic->mdio_ctrl != mdio_ctrl_phy_mii_emulated);
  }
  
  static void e100_get_defaults(struct nic *nic)
@@@ -1096,8 -1013,7 +1096,8 @@@ static void e100_configure(struct nic *
        config->standard_stat_counter = 0x1;    /* 1=standard, 0=extended */
        config->rx_discard_short_frames = 0x1;  /* 1=discard, 0=pass */
        config->tx_underrun_retry = 0x3;        /* # of underrun retries */
 -      config->mii_mode = 0x1;                 /* 1=MII mode, 0=503 mode */
 +      if (e100_phy_supports_mii(nic))
 +              config->mii_mode = 1;           /* 1=MII mode, 0=i82503 mode */
        config->pad10 = 0x6;
        config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */
        config->preamble_length = 0x2;          /* 0=1, 1=3, 2=7, 3=15 bytes */
@@@ -1354,42 -1270,6 +1354,42 @@@ static void e100_dump(struct nic *nic, 
                offsetof(struct mem, dump_buf));
  }
  
 +static int e100_phy_check_without_mii(struct nic *nic)
 +{
 +      u8 phy_type;
 +      int without_mii;
 +
 +      phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f;
 +
 +      switch (phy_type) {
 +      case NoSuchPhy: /* Non-MII PHY; UNTESTED! */
 +      case I82503: /* Non-MII PHY; UNTESTED! */
 +      case S80C24: /* Non-MII PHY; tested and working */
 +              /* paragraph from the FreeBSD driver, "FXP_PHY_80C24":
 +               * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter
 +               * doesn't have a programming interface of any sort.  The
 +               * media is sensed automatically based on how the link partner
 +               * is configured.  This is, in essence, manual configuration.
 +               */
 +              DPRINTK(PROBE, INFO,
 +                       "found MII-less i82503 or 80c24 or other PHY\n");
 +
 +              nic->mdio_ctrl = mdio_ctrl_phy_mii_emulated;
 +              nic->mii.phy_id = 0; /* is this ok for an MII-less PHY? */
 +
 +              /* these might be needed for certain MII-less cards...
 +               * nic->flags |= ich;
 +               * nic->flags |= ich_10h_workaround; */
 +
 +              without_mii = 1;
 +              break;
 +      default:
 +              without_mii = 0;
 +              break;
 +      }
 +      return without_mii;
 +}
 +
  #define NCONFIG_AUTO_SWITCH   0x0080
  #define MII_NSC_CONG          MII_RESV1
  #define NSC_CONG_ENABLE               0x0100
@@@ -1410,21 -1290,9 +1410,21 @@@ static int e100_phy_init(struct nic *ni
                if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0))))
                        break;
        }
 -      DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
 -      if (addr == 32)
 -              return -EAGAIN;
 +      if (addr == 32) {
 +              /* uhoh, no PHY detected: check whether we seem to be some
 +               * weird, rare variant which is *known* to not have any MII.
 +               * But do this AFTER MII checking only, since this does
 +               * lookup of EEPROM values which may easily be unreliable. */
 +              if (e100_phy_check_without_mii(nic))
 +                      return 0; /* simply return and hope for the best */
 +              else {
 +                      /* for unknown cases log a fatal error */
 +                      DPRINTK(HW, ERR,
 +                              "Failed to locate any known PHY, aborting.\n");
 +                      return -EAGAIN;
 +              }
 +      } else
 +              DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
  
        /* Isolate all the PHY ids */
        for (addr = 0; addr < 32; addr++)
        if (nic->phy == phy_82552_v) {
                u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
  
 +              /* assign special tweaked mdio_ctrl() function */
 +              nic->mdio_ctrl = mdio_ctrl_phy_82552_v;
 +
                /* Workaround Si not advertising flow-control during autoneg */
                advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
                mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert);
@@@ -1716,7 -1581,7 +1716,7 @@@ static int e100_xmit_frame(struct sk_bu
                /* This is a hard error - log it. */
                DPRINTK(TX_ERR, DEBUG, "Out of Tx resources, returning skb\n");
                netif_stop_queue(netdev);
 -              return 1;
 +              return NETDEV_TX_BUSY;
        }
  
        netdev->trans_start = jiffies;
@@@ -2720,7 -2585,6 +2720,7 @@@ static int __devinit e100_probe(struct 
        nic->netdev = netdev;
        nic->pdev = pdev;
        nic->msg_enable = (1 << debug) - 1;
 +      nic->mdio_ctrl = mdio_ctrl_hw;
        pci_set_drvdata(pdev, netdev);
  
        if ((err = pci_enable_device(pdev))) {
@@@ -2921,7 -2785,7 +2921,7 @@@ static int e100_resume(struct pci_dev *
        /* ack any pending wake events, disable PME */
        pci_enable_wake(pdev, 0, 0);
  
-       /* disbale reverse auto-negotiation */
+       /* disable reverse auto-negotiation */
        if (nic->phy == phy_82552_v) {
                u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
                                           E100_82552_SMARTSPEED);
@@@ -2958,13 -2822,12 +2958,13 @@@ static pci_ers_result_t e100_io_error_d
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct nic *nic = netdev_priv(netdev);
  
 -      /* Similar to calling e100_down(), but avoids adapter I/O. */
 -      e100_close(netdev);
 -
 -      /* Detach; put netif into a state similar to hotplug unplug. */
 -      napi_enable(&nic->napi);
        netif_device_detach(netdev);
 +
 +      if (state == pci_channel_io_perm_failure)
 +              return PCI_ERS_RESULT_DISCONNECT;
 +
 +      if (netif_running(netdev))
 +              e100_down(nic);
        pci_disable_device(pdev);
  
        /* Request a slot reset. */
index d6e491bc58c9f12ee5804be623bf75c62c103755,44f0bf23dafc241de92c7dfde76d4f9c5d4e24a3..981936c1fb46759846cad4b379471fe61ee1a99e
@@@ -62,7 -62,7 +62,7 @@@ struct e1000_info
        e_printk(KERN_NOTICE, adapter, format, ## arg)
  
  
- /* Interrupt modes, as used by the IntMode paramter */
+ /* Interrupt modes, as used by the IntMode parameter */
  #define E1000E_INT_MODE_LEGACY                0
  #define E1000E_INT_MODE_MSI           1
  #define E1000E_INT_MODE_MSIX          2
  /* Number of packet split data buffers (not including the header buffer) */
  #define PS_PAGE_BUFFERS                       (MAX_PS_BUFFERS - 1)
  
 +#define DEFAULT_JUMBO                 9234
 +
 +/* BM/HV Specific Registers */
 +#define BM_PORT_CTRL_PAGE                 769
 +
 +#define PHY_UPPER_SHIFT                   21
 +#define BM_PHY_REG(page, reg) \
 +      (((reg) & MAX_PHY_REG_ADDRESS) |\
 +       (((page) & 0xFFFF) << PHY_PAGE_SHIFT) |\
 +       (((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)))
 +
 +/* PHY Wakeup Registers and defines */
 +#define BM_RCTL         PHY_REG(BM_WUC_PAGE, 0)
 +#define BM_WUC          PHY_REG(BM_WUC_PAGE, 1)
 +#define BM_WUFC         PHY_REG(BM_WUC_PAGE, 2)
 +#define BM_WUS          PHY_REG(BM_WUC_PAGE, 3)
 +#define BM_RAR_L(_i)    (BM_PHY_REG(BM_WUC_PAGE, 16 + ((_i) << 2)))
 +#define BM_RAR_M(_i)    (BM_PHY_REG(BM_WUC_PAGE, 17 + ((_i) << 2)))
 +#define BM_RAR_H(_i)    (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2)))
 +#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2)))
 +#define BM_MTA(_i)      (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1)))
 +
 +#define BM_RCTL_UPE           0x0001          /* Unicast Promiscuous Mode */
 +#define BM_RCTL_MPE           0x0002          /* Multicast Promiscuous Mode */
 +#define BM_RCTL_MO_SHIFT      3               /* Multicast Offset Shift */
 +#define BM_RCTL_MO_MASK       (3 << 3)        /* Multicast Offset Mask */
 +#define BM_RCTL_BAM           0x0020          /* Broadcast Accept Mode */
 +#define BM_RCTL_PMCF          0x0040          /* Pass MAC Control Frames */
 +#define BM_RCTL_RFCE          0x0080          /* Rx Flow Control Enable */
 +
 +#define HV_SCC_UPPER          PHY_REG(778, 16) /* Single Collision Count */
 +#define HV_SCC_LOWER          PHY_REG(778, 17)
 +#define HV_ECOL_UPPER         PHY_REG(778, 18) /* Excessive Collision Count */
 +#define HV_ECOL_LOWER         PHY_REG(778, 19)
 +#define HV_MCC_UPPER          PHY_REG(778, 20) /* Multiple Collision Count */
 +#define HV_MCC_LOWER          PHY_REG(778, 21)
 +#define HV_LATECOL_UPPER      PHY_REG(778, 23) /* Late Collision Count */
 +#define HV_LATECOL_LOWER      PHY_REG(778, 24)
 +#define HV_COLC_UPPER         PHY_REG(778, 25) /* Collision Count */
 +#define HV_COLC_LOWER         PHY_REG(778, 26)
 +#define HV_DC_UPPER           PHY_REG(778, 27) /* Defer Count */
 +#define HV_DC_LOWER           PHY_REG(778, 28)
 +#define HV_TNCRS_UPPER                PHY_REG(778, 29) /* Transmit with no CRS */
 +#define HV_TNCRS_LOWER                PHY_REG(778, 30)
 +
  enum e1000_boards {
        board_82571,
        board_82572,
        board_ich8lan,
        board_ich9lan,
        board_ich10lan,
 +      board_pchlan,
  };
  
  struct e1000_queue_stats {
@@@ -339,7 -293,6 +339,7 @@@ struct e1000_adapter 
        u32 eeprom_wol;
        u32 wol;
        u32 pba;
 +      u32 max_hw_frame_size;
  
        bool fc_autoneg;
  
        unsigned int flags2;
        struct work_struct downshift_task;
        struct work_struct update_phy_task;
 +      struct work_struct led_blink_task;
  };
  
  struct e1000_info {
        unsigned int            flags;
        unsigned int            flags2;
        u32                     pba;
 +      u32                     max_hw_frame_size;
        s32                     (*get_variants)(struct e1000_adapter *);
        struct e1000_mac_operations *mac_ops;
        struct e1000_phy_operations *phy_ops;
  
  /* CRC Stripping defines */
  #define FLAG2_CRC_STRIPPING               (1 << 0)
 +#define FLAG2_HAS_PHY_WAKEUP              (1 << 1)
  
  #define E1000_RX_DESC_PS(R, i)            \
        (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
@@@ -454,7 -404,6 +454,7 @@@ extern struct e1000_info e1000_82583_in
  extern struct e1000_info e1000_ich8_info;
  extern struct e1000_info e1000_ich9_info;
  extern struct e1000_info e1000_ich10_info;
 +extern struct e1000_info e1000_pch_info;
  extern struct e1000_info e1000_es2_info;
  
  extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num);
@@@ -476,7 -425,6 +476,7 @@@ extern void e1000e_disable_gig_wol_ich8
  extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
  extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
  extern s32 e1000e_check_for_serdes_link(struct e1000_hw *hw);
 +extern s32 e1000e_setup_led_generic(struct e1000_hw *hw);
  extern s32 e1000e_cleanup_led_generic(struct e1000_hw *hw);
  extern s32 e1000e_led_on_generic(struct e1000_hw *hw);
  extern s32 e1000e_led_off_generic(struct e1000_hw *hw);
@@@ -545,15 -493,6 +545,15 @@@ extern s32 e1000e_phy_reset_dsp(struct 
  extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
  extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
  extern s32 e1000e_check_downshift(struct e1000_hw *hw);
 +extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
 +extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
 +extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow);
 +extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
 +extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
 +extern s32 e1000_check_polarity_82577(struct e1000_hw *hw);
 +extern s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
 +extern s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
 +extern s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
  
  static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
  {
index 2ad6cd756539fb3936c15cdc5ed90224f7bb1592,d488733893a6e011dada7b47270c78b3459a26f4..8e9b67ebbf8b49f888112af4fd242733489ec3c7
@@@ -45,7 -45,7 +45,7 @@@ struct igbvf_adapter
  /* Interrupt defines */
  #define IGBVF_START_ITR                 648 /* ~6000 ints/sec */
  
- /* Interrupt modes, as used by the IntMode paramter */
+ /* Interrupt modes, as used by the IntMode parameter */
  #define IGBVF_INT_MODE_LEGACY           0
  #define IGBVF_INT_MODE_MSI              1
  #define IGBVF_INT_MODE_MSIX             2
@@@ -286,7 -286,11 +286,7 @@@ struct igbvf_info 
  };
  
  /* hardware capability, feature, and workaround flags */
 -#define FLAG_HAS_HW_VLAN_FILTER           (1 << 0)
 -#define FLAG_HAS_JUMBO_FRAMES             (1 << 1)
 -#define FLAG_MSI_ENABLED                  (1 << 2)
 -#define FLAG_RX_CSUM_ENABLED              (1 << 3)
 -#define FLAG_TSO_FORCE                    (1 << 4)
 +#define IGBVF_FLAG_RX_CSUM_DISABLED             (1 << 0)
  
  #define IGBVF_RX_DESC_ADV(R, i)     \
        (&((((R).desc))[i].rx_desc))
index 0a7e78ade63fdac024d28bd77ab53aa438c771d9,e8eeef0c9c9ace85ccb9696cb81ee5fd1c94e452..e02bafdd368204a1831439ff595d110a6d3313a1
@@@ -51,14 -51,14 +51,14 @@@ static void mlx4_en_vlan_rx_register(st
        struct mlx4_en_dev *mdev = priv->mdev;
        int err;
  
 -      mlx4_dbg(HW, priv, "Registering VLAN group:%p\n", grp);
 +      en_dbg(HW, priv, "Registering VLAN group:%p\n", grp);
        priv->vlgrp = grp;
  
        mutex_lock(&mdev->state_lock);
        if (mdev->device_up && priv->port_up) {
                err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, grp);
                if (err)
 -                      mlx4_err(mdev, "Failed configuring VLAN filter\n");
 +                      en_err(priv, "Failed configuring VLAN filter\n");
        }
        mutex_unlock(&mdev->state_lock);
  }
@@@ -72,15 -72,15 +72,15 @@@ static void mlx4_en_vlan_rx_add_vid(str
        if (!priv->vlgrp)
                return;
  
 -      mlx4_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n",
 -               vid, vlan_group_get_device(priv->vlgrp, vid));
 +      en_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n",
 +             vid, vlan_group_get_device(priv->vlgrp, vid));
  
        /* Add VID to port VLAN filter */
        mutex_lock(&mdev->state_lock);
        if (mdev->device_up && priv->port_up) {
                err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
                if (err)
 -                      mlx4_err(mdev, "Failed configuring VLAN filter\n");
 +                      en_err(priv, "Failed configuring VLAN filter\n");
        }
        mutex_unlock(&mdev->state_lock);
  }
@@@ -94,8 -94,9 +94,8 @@@ static void mlx4_en_vlan_rx_kill_vid(st
        if (!priv->vlgrp)
                return;
  
 -      mlx4_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp "
 -               "entry:%p)\n", vid, priv->vlgrp,
 -               vlan_group_get_device(priv->vlgrp, vid));
 +      en_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp entry:%p)\n",
 +             vid, priv->vlgrp, vlan_group_get_device(priv->vlgrp, vid));
        vlan_group_set_device(priv->vlgrp, vid, NULL);
  
        /* Remove VID from port VLAN filter */
        if (mdev->device_up && priv->port_up) {
                err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
                if (err)
 -                      mlx4_err(mdev, "Failed configuring VLAN filter\n");
 +                      en_err(priv, "Failed configuring VLAN filter\n");
        }
        mutex_unlock(&mdev->state_lock);
  }
@@@ -149,10 -150,9 +149,10 @@@ static void mlx4_en_do_set_mac(struct w
                err = mlx4_register_mac(mdev->dev, priv->port,
                                        priv->mac, &priv->mac_index);
                if (err)
 -                      mlx4_err(mdev, "Failed changing HW MAC address\n");
 +                      en_err(priv, "Failed changing HW MAC address\n");
        } else
 -              mlx4_dbg(HW, priv, "Port is down, exiting...\n");
 +              en_dbg(HW, priv, "Port is down while "
 +                               "registering mac, exiting...\n");
  
        mutex_unlock(&mdev->state_lock);
  }
@@@ -174,6 -174,7 +174,6 @@@ static void mlx4_en_clear_list(struct n
  static void mlx4_en_cache_mclist(struct net_device *dev)
  {
        struct mlx4_en_priv *priv = netdev_priv(dev);
 -      struct mlx4_en_dev *mdev = priv->mdev;
        struct dev_mc_list *mclist;
        struct dev_mc_list *tmp;
        struct dev_mc_list *plist = NULL;
        for (mclist = dev->mc_list; mclist; mclist = mclist->next) {
                tmp = kmalloc(sizeof(struct dev_mc_list), GFP_ATOMIC);
                if (!tmp) {
 -                      mlx4_err(mdev, "failed to allocate multicast list\n");
 +                      en_err(priv, "failed to allocate multicast list\n");
                        mlx4_en_clear_list(dev);
                        return;
                }
@@@ -218,13 -219,13 +218,13 @@@ static void mlx4_en_do_set_multicast(st
  
        mutex_lock(&mdev->state_lock);
        if (!mdev->device_up) {
 -              mlx4_dbg(HW, priv, "Card is not up, ignoring "
 -                                 "multicast change.\n");
 +              en_dbg(HW, priv, "Card is not up, "
 +                               "ignoring multicast change.\n");
                goto out;
        }
        if (!priv->port_up) {
 -              mlx4_dbg(HW, priv, "Port is down, ignoring "
 -                                 "multicast change.\n");
 +              en_dbg(HW, priv, "Port is down, "
 +                               "ignoring  multicast change.\n");
                goto out;
        }
  
        if (dev->flags & IFF_PROMISC) {
                if (!(priv->flags & MLX4_EN_FLAG_PROMISC)) {
                        if (netif_msg_rx_status(priv))
 -                              mlx4_warn(mdev, "Port:%d entering promiscuous mode\n",
 -                                        priv->port);
 +                              en_warn(priv, "Entering promiscuous mode\n");
                        priv->flags |= MLX4_EN_FLAG_PROMISC;
  
                        /* Enable promiscouos mode */
                        err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
                                                     priv->base_qpn, 1);
                        if (err)
 -                              mlx4_err(mdev, "Failed enabling "
 -                                       "promiscous mode\n");
 +                              en_err(priv, "Failed enabling "
 +                                           "promiscous mode\n");
  
                        /* Disable port multicast filter (unconditionally) */
                        err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
                                                  0, MLX4_MCAST_DISABLE);
                        if (err)
 -                              mlx4_err(mdev, "Failed disabling "
 -                                       "multicast filter\n");
 +                              en_err(priv, "Failed disabling "
 +                                           "multicast filter\n");
  
                        /* Disable port VLAN filter */
                        err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL);
                        if (err)
 -                              mlx4_err(mdev, "Failed disabling "
 -                                       "VLAN filter\n");
 +                              en_err(priv, "Failed disabling VLAN filter\n");
                }
                goto out;
        }
  
        if (priv->flags & MLX4_EN_FLAG_PROMISC) {
                if (netif_msg_rx_status(priv))
 -                      mlx4_warn(mdev, "Port:%d leaving promiscuous mode\n",
 -                                priv->port);
 +                      en_warn(priv, "Leaving promiscuous mode\n");
                priv->flags &= ~MLX4_EN_FLAG_PROMISC;
  
                /* Disable promiscouos mode */
                err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
                                             priv->base_qpn, 0);
                if (err)
 -                      mlx4_err(mdev, "Failed disabling promiscous mode\n");
 +                      en_err(priv, "Failed disabling promiscous mode\n");
  
                /* Enable port VLAN filter */
                err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
                if (err)
 -                      mlx4_err(mdev, "Failed enabling VLAN filter\n");
 +                      en_err(priv, "Failed enabling VLAN filter\n");
        }
  
        /* Enable/disable the multicast filter according to IFF_ALLMULTI */
                err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
                                          0, MLX4_MCAST_DISABLE);
                if (err)
 -                      mlx4_err(mdev, "Failed disabling multicast filter\n");
 +                      en_err(priv, "Failed disabling multicast filter\n");
        } else {
                err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
                                          0, MLX4_MCAST_DISABLE);
                if (err)
 -                      mlx4_err(mdev, "Failed disabling multicast filter\n");
 +                      en_err(priv, "Failed disabling multicast filter\n");
  
                /* Flush mcast filter and init it with broadcast address */
                mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, ETH_BCAST,
                err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
                                          0, MLX4_MCAST_ENABLE);
                if (err)
 -                      mlx4_err(mdev, "Failed enabling multicast filter\n");
 +                      en_err(priv, "Failed enabling multicast filter\n");
  
                mlx4_en_clear_list(dev);
        }
@@@ -342,10 -346,10 +342,10 @@@ static void mlx4_en_tx_timeout(struct n
        struct mlx4_en_dev *mdev = priv->mdev;
  
        if (netif_msg_timer(priv))
 -              mlx4_warn(mdev, "Tx timeout called on port:%d\n", priv->port);
 +              en_warn(priv, "Tx timeout called on port:%d\n", priv->port);
  
        priv->port_stats.tx_timeout++;
 -      mlx4_dbg(DRV, priv, "Scheduling watchdog\n");
 +      en_dbg(DRV, priv, "Scheduling watchdog\n");
        queue_work(mdev->workqueue, &priv->watchdog_task);
  }
  
@@@ -367,15 -371,15 +367,15 @@@ static void mlx4_en_set_default_moderat
        int i;
  
        /* If we haven't received a specific coalescing setting
-        * (module param), we set the moderation paramters as follows:
+        * (module param), we set the moderation parameters as follows:
         * - moder_cnt is set to the number of mtu sized packets to
         *   satisfy our coelsing target.
         * - moder_time is set to a fixed value.
         */
 -      priv->rx_frames = MLX4_EN_RX_COAL_TARGET / priv->dev->mtu + 1;
 +      priv->rx_frames = MLX4_EN_RX_COAL_TARGET;
        priv->rx_usecs = MLX4_EN_RX_COAL_TIME;
 -      mlx4_dbg(INTR, priv, "Default coalesing params for mtu:%d - "
 -                           "rx_frames:%d rx_usecs:%d\n",
 +      en_dbg(INTR, priv, "Default coalesing params for mtu:%d - "
 +                         "rx_frames:%d rx_usecs:%d\n",
                 priv->dev->mtu, priv->rx_frames, priv->rx_usecs);
  
        /* Setup cq moderation params */
  static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
  {
        unsigned long period = (unsigned long) (jiffies - priv->last_moder_jiffies);
 -      struct mlx4_en_dev *mdev = priv->mdev;
        struct mlx4_en_cq *cq;
        unsigned long packets;
        unsigned long rate;
                moder_time = priv->rx_usecs;
        }
  
 -      mlx4_dbg(INTR, priv, "tx rate:%lu rx_rate:%lu\n",
 -               tx_pkt_diff * HZ / period, rx_pkt_diff * HZ / period);
 +      en_dbg(INTR, priv, "tx rate:%lu rx_rate:%lu\n",
 +             tx_pkt_diff * HZ / period, rx_pkt_diff * HZ / period);
  
 -      mlx4_dbg(INTR, priv, "Rx moder_time changed from:%d to %d period:%lu "
 -               "[jiff] packets:%lu avg_pkt_size:%lu rate:%lu [p/s])\n",
 +      en_dbg(INTR, priv, "Rx moder_time changed from:%d to %d period:%lu "
 +             "[jiff] packets:%lu avg_pkt_size:%lu rate:%lu [p/s])\n",
                 priv->last_moder_time, moder_time, period, packets,
                 avg_pkt_size, rate);
  
                        cq->moder_time = moder_time;
                        err = mlx4_en_set_cq_moder(priv, cq);
                        if (err) {
 -                              mlx4_err(mdev, "Failed modifying moderation for cq:%d "
 -                                       "on port:%d\n", i, priv->port);
 +                              en_err(priv, "Failed modifying moderation for cq:%d\n", i);
                                break;
                        }
                }
@@@ -505,7 -511,8 +505,7 @@@ static void mlx4_en_do_get_stats(struc
  
        err = mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 0);
        if (err)
 -              mlx4_dbg(HW, priv, "Could not update stats for "
 -                                 "port:%d\n", priv->port);
 +              en_dbg(HW, priv, "Could not update stats \n");
  
        mutex_lock(&mdev->state_lock);
        if (mdev->device_up) {
@@@ -529,10 -536,12 +529,10 @@@ static void mlx4_en_linkstate(struct wo
         * report to system log */
        if (priv->last_link_state != linkstate) {
                if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) {
 -                      if (netif_msg_link(priv))
 -                              mlx4_info(mdev, "Port %d - link down\n", priv->port);
 +                      en_dbg(LINK, priv, "Link Down\n");
                        netif_carrier_off(priv->dev);
                } else {
 -                      if (netif_msg_link(priv))
 -                              mlx4_info(mdev, "Port %d - link up\n", priv->port);
 +                      en_dbg(LINK, priv, "Link Up\n");
                        netif_carrier_on(priv->dev);
                }
        }
@@@ -547,53 -556,58 +547,53 @@@ int mlx4_en_start_port(struct net_devic
        struct mlx4_en_dev *mdev = priv->mdev;
        struct mlx4_en_cq *cq;
        struct mlx4_en_tx_ring *tx_ring;
 -      struct mlx4_en_rx_ring *rx_ring;
        int rx_index = 0;
        int tx_index = 0;
 -      u16 stride;
        int err = 0;
        int i;
        int j;
  
        if (priv->port_up) {
 -              mlx4_dbg(DRV, priv, "start port called while port already up\n");
 +              en_dbg(DRV, priv, "start port called while port already up\n");
                return 0;
        }
  
        /* Calculate Rx buf size */
        dev->mtu = min(dev->mtu, priv->max_mtu);
        mlx4_en_calc_rx_buf(dev);
 -      mlx4_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size);
 -      stride = roundup_pow_of_two(sizeof(struct mlx4_en_rx_desc) +
 -                                  DS_SIZE * priv->num_frags);
 +      en_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size);
 +
        /* Configure rx cq's and rings */
 +      err = mlx4_en_activate_rx_rings(priv);
 +      if (err) {
 +              en_err(priv, "Failed to activate RX rings\n");
 +              return err;
 +      }
        for (i = 0; i < priv->rx_ring_num; i++) {
                cq = &priv->rx_cq[i];
 -              rx_ring = &priv->rx_ring[i];
  
                err = mlx4_en_activate_cq(priv, cq);
                if (err) {
 -                      mlx4_err(mdev, "Failed activating Rx CQ\n");
 +                      en_err(priv, "Failed activating Rx CQ\n");
                        goto cq_err;
                }
                for (j = 0; j < cq->size; j++)
                        cq->buf[j].owner_sr_opcode = MLX4_CQE_OWNER_MASK;
                err = mlx4_en_set_cq_moder(priv, cq);
                if (err) {
 -                      mlx4_err(mdev, "Failed setting cq moderation parameters");
 +                      en_err(priv, "Failed setting cq moderation parameters");
                        mlx4_en_deactivate_cq(priv, cq);
                        goto cq_err;
                }
                mlx4_en_arm_cq(priv, cq);
 -
 +              priv->rx_ring[i].cqn = cq->mcq.cqn;
                ++rx_index;
        }
  
 -      err = mlx4_en_activate_rx_rings(priv);
 -      if (err) {
 -              mlx4_err(mdev, "Failed to activate RX rings\n");
 -              goto cq_err;
 -      }
 -
        err = mlx4_en_config_rss_steer(priv);
        if (err) {
 -              mlx4_err(mdev, "Failed configuring rss steering\n");
 -              goto rx_err;
 +              en_err(priv, "Failed configuring rss steering\n");
 +              goto cq_err;
        }
  
        /* Configure tx cq's and rings */
                cq = &priv->tx_cq[i];
                err = mlx4_en_activate_cq(priv, cq);
                if (err) {
 -                      mlx4_err(mdev, "Failed allocating Tx CQ\n");
 +                      en_err(priv, "Failed allocating Tx CQ\n");
                        goto tx_err;
                }
                err = mlx4_en_set_cq_moder(priv, cq);
                if (err) {
 -                      mlx4_err(mdev, "Failed setting cq moderation parameters");
 +                      en_err(priv, "Failed setting cq moderation parameters");
                        mlx4_en_deactivate_cq(priv, cq);
                        goto tx_err;
                }
 -              mlx4_dbg(DRV, priv, "Resetting index of collapsed CQ:%d to -1\n", i);
 +              en_dbg(DRV, priv, "Resetting index of collapsed CQ:%d to -1\n", i);
                cq->buf->wqe_index = cpu_to_be16(0xffff);
  
                /* Configure ring */
                err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn,
                                               priv->rx_ring[0].srq.srqn);
                if (err) {
 -                      mlx4_err(mdev, "Failed allocating Tx ring\n");
 +                      en_err(priv, "Failed allocating Tx ring\n");
                        mlx4_en_deactivate_cq(priv, cq);
                        goto tx_err;
                }
                                    priv->prof->rx_pause,
                                    priv->prof->rx_ppp);
        if (err) {
 -              mlx4_err(mdev, "Failed setting port general configurations"
 -                             " for port %d, with error %d\n", priv->port, err);
 +              en_err(priv, "Failed setting port general configurations "
 +                           "for port %d, with error %d\n", priv->port, err);
                goto tx_err;
        }
        /* Set default qp number */
        err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, priv->base_qpn, 0);
        if (err) {
 -              mlx4_err(mdev, "Failed setting default qp numbers\n");
 +              en_err(priv, "Failed setting default qp numbers\n");
                goto tx_err;
        }
        /* Set port mac number */
 -      mlx4_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
 +      en_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
        err = mlx4_register_mac(mdev->dev, priv->port,
                                priv->mac, &priv->mac_index);
        if (err) {
 -              mlx4_err(mdev, "Failed setting port mac\n");
 +              en_err(priv, "Failed setting port mac\n");
                goto tx_err;
        }
  
        /* Init port */
 -      mlx4_dbg(HW, priv, "Initializing port\n");
 +      en_dbg(HW, priv, "Initializing port\n");
        err = mlx4_INIT_PORT(mdev->dev, priv->port);
        if (err) {
 -              mlx4_err(mdev, "Failed Initializing port\n");
 +              en_err(priv, "Failed Initializing port\n");
                goto mac_err;
        }
  
@@@ -680,11 -694,12 +680,11 @@@ tx_err
        }
  
        mlx4_en_release_rss_steer(priv);
 -rx_err:
 -      for (i = 0; i < priv->rx_ring_num; i++)
 -              mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
  cq_err:
        while (rx_index--)
                mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]);
 +      for (i = 0; i < priv->rx_ring_num; i++)
 +              mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
  
        return err; /* need to close devices */
  }
@@@ -697,7 -712,8 +697,7 @@@ void mlx4_en_stop_port(struct net_devic
        int i;
  
        if (!priv->port_up) {
 -              mlx4_dbg(DRV, priv, "stop port (%d) called while port already down\n",
 -                       priv->port);
 +              en_dbg(DRV, priv, "stop port called while port already down\n");
                return;
        }
        netif_stop_queue(dev);
@@@ -742,13 -758,13 +742,13 @@@ static void mlx4_en_restart(struct work
        struct mlx4_en_dev *mdev = priv->mdev;
        struct net_device *dev = priv->dev;
  
 -      mlx4_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port);
 +      en_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port);
  
        mutex_lock(&mdev->state_lock);
        if (priv->port_up) {
                mlx4_en_stop_port(dev);
                if (mlx4_en_start_port(dev))
 -                      mlx4_err(mdev, "Failed restarting port %d\n", priv->port);
 +                      en_err(priv, "Failed restarting port %d\n", priv->port);
        }
        mutex_unlock(&mdev->state_lock);
  }
@@@ -764,14 -780,14 +764,14 @@@ static int mlx4_en_open(struct net_devi
        mutex_lock(&mdev->state_lock);
  
        if (!mdev->device_up) {
 -              mlx4_err(mdev, "Cannot open - device down/disabled\n");
 +              en_err(priv, "Cannot open - device down/disabled\n");
                err = -EBUSY;
                goto out;
        }
  
        /* Reset HW statistics and performance counters */
        if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
 -              mlx4_dbg(HW, priv, "Failed dumping statistics\n");
 +              en_dbg(HW, priv, "Failed dumping statistics\n");
  
        memset(&priv->stats, 0, sizeof(priv->stats));
        memset(&priv->pstats, 0, sizeof(priv->pstats));
        mlx4_en_set_default_moderation(priv);
        err = mlx4_en_start_port(dev);
        if (err)
 -              mlx4_err(mdev, "Failed starting port:%d\n", priv->port);
 +              en_err(priv, "Failed starting port:%d\n", priv->port);
  
  out:
        mutex_unlock(&mdev->state_lock);
@@@ -801,7 -817,8 +801,7 @@@ static int mlx4_en_close(struct net_dev
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
  
 -      if (netif_msg_ifdown(priv))
 -              mlx4_info(mdev, "Close called for port:%d\n", priv->port);
 +      en_dbg(IFDOWN, priv, "Close port called\n");
  
        mutex_lock(&mdev->state_lock);
  
@@@ -833,6 -850,7 +833,6 @@@ void mlx4_en_free_resources(struct mlx4
  
  int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
  {
 -      struct mlx4_en_dev *mdev = priv->mdev;
        struct mlx4_en_port_profile *prof = priv->prof;
        int i;
  
        return 0;
  
  err:
 -      mlx4_err(mdev, "Failed to allocate NIC resources\n");
 +      en_err(priv, "Failed to allocate NIC resources\n");
        return -ENOMEM;
  }
  
@@@ -871,7 -889,7 +871,7 @@@ void mlx4_en_destroy_netdev(struct net_
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
  
 -      mlx4_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
 +      en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
  
        /* Unregister device - this will close the port if it was up */
        if (priv->registered)
@@@ -900,11 -918,11 +900,11 @@@ static int mlx4_en_change_mtu(struct ne
        struct mlx4_en_dev *mdev = priv->mdev;
        int err = 0;
  
 -      mlx4_dbg(DRV, priv, "Change MTU called - current:%d new:%d\n",
 +      en_dbg(DRV, priv, "Change MTU called - current:%d new:%d\n",
                 dev->mtu, new_mtu);
  
        if ((new_mtu < MLX4_EN_MIN_MTU) || (new_mtu > priv->max_mtu)) {
 -              mlx4_err(mdev, "Bad MTU size:%d.\n", new_mtu);
 +              en_err(priv, "Bad MTU size:%d.\n", new_mtu);
                return -EPERM;
        }
        dev->mtu = new_mtu;
                if (!mdev->device_up) {
                        /* NIC is probably restarting - let watchdog task reset
                         * the port */
 -                      mlx4_dbg(DRV, priv, "Change MTU called with card down!?\n");
 +                      en_dbg(DRV, priv, "Change MTU called with card down!?\n");
                } else {
                        mlx4_en_stop_port(dev);
                        mlx4_en_set_default_moderation(priv);
                        err = mlx4_en_start_port(dev);
                        if (err) {
 -                              mlx4_err(mdev, "Failed restarting port:%d\n",
 +                              en_err(priv, "Failed restarting port:%d\n",
                                         priv->port);
                                queue_work(mdev->workqueue, &priv->watchdog_task);
                        }
@@@ -934,7 -952,6 +934,7 @@@ static const struct net_device_ops mlx4
        .ndo_open               = mlx4_en_open,
        .ndo_stop               = mlx4_en_close,
        .ndo_start_xmit         = mlx4_en_xmit,
 +      .ndo_select_queue       = mlx4_en_select_queue,
        .ndo_get_stats          = mlx4_en_get_stats,
        .ndo_set_multicast_list = mlx4_en_set_multicast,
        .ndo_set_mac_address    = mlx4_en_set_mac,
@@@ -957,7 -974,7 +957,7 @@@ int mlx4_en_init_netdev(struct mlx4_en_
        int i;
        int err;
  
 -      dev = alloc_etherdev(sizeof(struct mlx4_en_priv));
 +      dev = alloc_etherdev_mq(sizeof(struct mlx4_en_priv), prof->tx_ring_num);
        if (dev == NULL) {
                mlx4_err(mdev, "Net device allocation failed\n");
                return -ENOMEM;
        priv->max_mtu = mdev->dev->caps.eth_mtu_cap[priv->port];
        priv->mac = mdev->dev->caps.def_mac[priv->port];
        if (ILLEGAL_MAC(priv->mac)) {
 -              mlx4_err(mdev, "Port: %d, invalid mac burned: 0x%llx, quiting\n",
 +              en_err(priv, "Port: %d, invalid mac burned: 0x%llx, quiting\n",
                         priv->port, priv->mac);
                err = -EINVAL;
                goto out;
        err = mlx4_alloc_hwq_res(mdev->dev, &priv->res,
                                MLX4_EN_PAGE_SIZE, MLX4_EN_PAGE_SIZE);
        if (err) {
 -              mlx4_err(mdev, "Failed to allocate page for rx qps\n");
 +              en_err(priv, "Failed to allocate page for rx qps\n");
                goto out;
        }
        priv->allocated = 1;
  
 -      /* Populate Tx priority mappings */
 -      mlx4_en_set_prio_map(priv, priv->tx_prio_map, prof->tx_ring_num);
 -
        /*
         * Initialize netdev entry points
         */
        dev->netdev_ops = &mlx4_netdev_ops;
        dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
 +      dev->real_num_tx_queues = MLX4_EN_NUM_TX_RINGS;
  
        SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
  
         * Set driver features
         */
        dev->features |= NETIF_F_SG;
 +      dev->vlan_features |= NETIF_F_SG;
        dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 +      dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        dev->features |= NETIF_F_HIGHDMA;
        dev->features |= NETIF_F_HW_VLAN_TX |
                         NETIF_F_HW_VLAN_RX |
        if (mdev->LSO_support) {
                dev->features |= NETIF_F_TSO;
                dev->features |= NETIF_F_TSO6;
 +              dev->vlan_features |= NETIF_F_TSO;
 +              dev->vlan_features |= NETIF_F_TSO6;
        }
  
        mdev->pndev[port] = dev;
        netif_carrier_off(dev);
        err = register_netdev(dev);
        if (err) {
 -              mlx4_err(mdev, "Netdev registration failed\n");
 +              en_err(priv, "Netdev registration failed for port %d\n", port);
                goto out;
        }
 +
 +      en_warn(priv, "Using %d TX rings\n", prof->tx_ring_num);
 +      en_warn(priv, "Using %d RX rings\n", prof->rx_ring_num);
 +
        priv->registered = 1;
        queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
        return 0;
diff --combined drivers/net/mlx4/eq.c
index dee188761a3cad79031985301c5b945f2bae2f8e,ce064e324200ab58de0836a2f6fc4bcff40e3715..b9ceddde46c0adf5f7e9602235bef02cd534babf
@@@ -497,8 -497,10 +497,10 @@@ static void mlx4_free_irqs(struct mlx4_
        if (eq_table->have_irq)
                free_irq(dev->pdev->irq, dev);
        for (i = 0; i < dev->caps.num_comp_vectors + 1; ++i)
-               if (eq_table->eq[i].have_irq)
+               if (eq_table->eq[i].have_irq) {
                        free_irq(eq_table->eq[i].irq, eq_table->eq + i);
+                       eq_table->eq[i].have_irq = 0;
+               }
  
        kfree(eq_table->irq_names);
  }
@@@ -623,10 -625,8 +625,10 @@@ int mlx4_init_eq_table(struct mlx4_dev 
                err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE,
                                     (dev->flags & MLX4_FLAG_MSI_X) ? i : 0,
                                     &priv->eq_table.eq[i]);
 -              if (err)
 +              if (err) {
 +                      --i;
                        goto err_out_unmap;
 +              }
        }
  
        err = mlx4_create_eq(dev, MLX4_NUM_ASYNC_EQE + MLX4_NUM_SPARE_EQE,
diff --combined drivers/net/mlx4/mr.c
index 0a467785f065601691ec9ba9728845c04b03f06f,3b8973d19933d7bf2b2aa4f418ce13bc1aeca860..5887e4764d220a7019439d98892b21d87039a2d3
@@@ -209,7 -209,7 +209,7 @@@ int mlx4_mtt_init(struct mlx4_dev *dev
        } else
                mtt->page_shift = page_shift;
  
-       for (mtt->order = 0, i = MLX4_MTT_ENTRY_PER_SEG; i < npages; i <<= 1)
+       for (mtt->order = 0, i = dev->caps.mtts_per_seg; i < npages; i <<= 1)
                ++mtt->order;
  
        mtt->first_seg = mlx4_alloc_mtt_range(dev, mtt->order);
@@@ -350,7 -350,7 +350,7 @@@ int mlx4_mr_enable(struct mlx4_dev *dev
                mpt_entry->pd_flags |= cpu_to_be32(MLX4_MPT_PD_FLAG_FAST_REG |
                                                   MLX4_MPT_PD_FLAG_RAE);
                mpt_entry->mtt_sz    = cpu_to_be32((1 << mr->mtt.order) *
-                                                  MLX4_MTT_ENTRY_PER_SEG);
+                                                  dev->caps.mtts_per_seg);
        } else {
                mpt_entry->flags    |= cpu_to_be32(MLX4_MPT_FLAG_SW_OWNS);
        }
@@@ -391,7 -391,7 +391,7 @@@ static int mlx4_write_mtt_chunk(struct 
            (start_index + npages - 1) / (PAGE_SIZE / sizeof (u64)))
                return -EINVAL;
  
-       if (start_index & (MLX4_MTT_ENTRY_PER_SEG - 1))
+       if (start_index & (dev->caps.mtts_per_seg - 1))
                return -EINVAL;
  
        mtts = mlx4_table_find(&priv->mr_table.mtt_table, mtt->first_seg +
        for (i = 0; i < npages; ++i)
                mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT);
  
 -      dma_sync_single(&dev->pdev->dev, dma_handle, npages * sizeof (u64), DMA_TO_DEVICE);
 +      dma_sync_single_for_cpu(&dev->pdev->dev, dma_handle,
 +                              npages * sizeof (u64), DMA_TO_DEVICE);
  
        return 0;
  }
@@@ -550,8 -549,8 +550,8 @@@ int mlx4_map_phys_fmr(struct mlx4_dev *
        for (i = 0; i < npages; ++i)
                fmr->mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT);
  
 -      dma_sync_single(&dev->pdev->dev, fmr->dma_handle,
 -                      npages * sizeof(u64), DMA_TO_DEVICE);
 +      dma_sync_single_for_cpu(&dev->pdev->dev, fmr->dma_handle,
 +                              npages * sizeof(u64), DMA_TO_DEVICE);
  
        fmr->mpt->key    = cpu_to_be32(key);
        fmr->mpt->lkey   = cpu_to_be32(key);
index b9a5f59d6c9b5fab8a5f7ef6ec6df573ead3d3b5,1fd5ecb24425c4b9c44db951368abbcc14a08249..90d1f76c0e8b074729047d5d7aed9440b8d8315f
@@@ -675,12 -675,11 +675,12 @@@ static int ql_get_8000_flash_params(str
        int status;
        __le32 *p = (__le32 *)&qdev->flash;
        u32 offset;
 +      u8 mac_addr[6];
  
        /* Get flash offset for function and adjust
         * for dword access.
         */
 -      if (!qdev->func)
 +      if (!qdev->port)
                offset = FUNC0_FLASH_OFFSET / sizeof(u32);
        else
                offset = FUNC1_FLASH_OFFSET / sizeof(u32);
                goto exit;
        }
  
 -      if (!is_valid_ether_addr(qdev->flash.flash_params_8000.mac_addr)) {
 +      /* Extract either manufacturer or BOFM modified
 +       * MAC address.
 +       */
 +      if (qdev->flash.flash_params_8000.data_type1 == 2)
 +              memcpy(mac_addr,
 +                      qdev->flash.flash_params_8000.mac_addr1,
 +                      qdev->ndev->addr_len);
 +      else
 +              memcpy(mac_addr,
 +                      qdev->flash.flash_params_8000.mac_addr,
 +                      qdev->ndev->addr_len);
 +
 +      if (!is_valid_ether_addr(mac_addr)) {
                QPRINTK(qdev, IFUP, ERR, "Invalid MAC address.\n");
                status = -EINVAL;
                goto exit;
        }
  
        memcpy(qdev->ndev->dev_addr,
 -              qdev->flash.flash_params_8000.mac_addr,
 +              mac_addr,
                qdev->ndev->addr_len);
  
  exit:
@@@ -744,7 -731,7 +744,7 @@@ static int ql_get_8012_flash_params(str
        /* Second function's parameters follow the first
         * function's.
         */
 -      if (qdev->func)
 +      if (qdev->port)
                offset = size;
  
        if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
@@@ -850,13 -837,6 +850,13 @@@ exit
  static int ql_8000_port_initialize(struct ql_adapter *qdev)
  {
        int status;
 +      /*
 +       * Get MPI firmware version for driver banner
 +       * and ethool info.
 +       */
 +      status = ql_mb_about_fw(qdev);
 +      if (status)
 +              goto exit;
        status = ql_mb_get_fw_state(qdev);
        if (status)
                goto exit;
@@@ -1538,22 -1518,6 +1538,22 @@@ static void ql_process_mac_rx_intr(stru
                return;
        }
  
 +      /* Frame error, so drop the packet. */
 +      if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
 +              QPRINTK(qdev, DRV, ERR, "Receive error, flags2 = 0x%x\n",
 +                                      ib_mac_rsp->flags2);
 +              dev_kfree_skb_any(skb);
 +              return;
 +      }
 +
 +      /* The max framesize filter on this chip is set higher than
 +       * MTU since FCoE uses 2k frames.
 +       */
 +      if (skb->len > ndev->mtu + ETH_HLEN) {
 +              dev_kfree_skb_any(skb);
 +              return;
 +      }
 +
        prefetch(skb->data);
        skb->dev = ndev;
        if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) {
         * csum or frame errors.
         */
        if (qdev->rx_csum &&
 -              !(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) &&
                !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
                /* TCP frame. */
                if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@@ -2143,6 -2108,7 +2143,6 @@@ static int qlge_send(struct sk_buff *sk
        wmb();
  
        ql_write_db_reg(tx_ring->prod_idx, tx_ring->prod_idx_db_reg);
 -      ndev->trans_start = jiffies;
        QPRINTK(qdev, TX_QUEUED, DEBUG, "tx queued, slot %d, len %d\n",
                tx_ring->prod_idx, skb->len);
  
@@@ -2237,7 -2203,7 +2237,7 @@@ static int ql_alloc_tx_resources(struc
                                 &tx_ring->wq_base_dma);
  
        if ((tx_ring->wq_base == NULL)
 -          || tx_ring->wq_base_dma & (tx_ring->wq_size - 1)) {
 +              || tx_ring->wq_base_dma & WQ_ADDR_ALIGN) {
                QPRINTK(qdev, IFUP, ERR, "tx_ring alloc failed.\n");
                return -ENOMEM;
        }
@@@ -2552,16 -2518,14 +2552,16 @@@ static int ql_start_rx_ring(struct ql_a
  {
        struct cqicb *cqicb = &rx_ring->cqicb;
        void *shadow_reg = qdev->rx_ring_shadow_reg_area +
 -          (rx_ring->cq_id * sizeof(u64) * 4);
 +              (rx_ring->cq_id * RX_RING_SHADOW_SPACE);
        u64 shadow_reg_dma = qdev->rx_ring_shadow_reg_dma +
 -          (rx_ring->cq_id * sizeof(u64) * 4);
 +              (rx_ring->cq_id * RX_RING_SHADOW_SPACE);
        void __iomem *doorbell_area =
            qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id));
        int err = 0;
        u16 bq_len;
        u64 tmp;
 +      __le64 *base_indirect_ptr;
 +      int page_entries;
  
        /* Set up the shadow registers for this ring. */
        rx_ring->prod_idx_sh_reg = shadow_reg;
        shadow_reg_dma += sizeof(u64);
        rx_ring->lbq_base_indirect = shadow_reg;
        rx_ring->lbq_base_indirect_dma = shadow_reg_dma;
 -      shadow_reg += sizeof(u64);
 -      shadow_reg_dma += sizeof(u64);
 +      shadow_reg += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len));
 +      shadow_reg_dma += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len));
        rx_ring->sbq_base_indirect = shadow_reg;
        rx_ring->sbq_base_indirect_dma = shadow_reg_dma;
  
        if (rx_ring->lbq_len) {
                cqicb->flags |= FLAGS_LL;       /* Load lbq values */
                tmp = (u64)rx_ring->lbq_base_dma;;
 -              *((__le64 *) rx_ring->lbq_base_indirect) = cpu_to_le64(tmp);
 +              base_indirect_ptr = (__le64 *) rx_ring->lbq_base_indirect;
 +              page_entries = 0;
 +              do {
 +                      *base_indirect_ptr = cpu_to_le64(tmp);
 +                      tmp += DB_PAGE_SIZE;
 +                      base_indirect_ptr++;
 +                      page_entries++;
 +              } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len));
                cqicb->lbq_addr =
                    cpu_to_le64(rx_ring->lbq_base_indirect_dma);
                bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 :
        if (rx_ring->sbq_len) {
                cqicb->flags |= FLAGS_LS;       /* Load sbq values */
                tmp = (u64)rx_ring->sbq_base_dma;;
 -              *((__le64 *) rx_ring->sbq_base_indirect) = cpu_to_le64(tmp);
 +              base_indirect_ptr = (__le64 *) rx_ring->sbq_base_indirect;
 +              page_entries = 0;
 +              do {
 +                      *base_indirect_ptr = cpu_to_le64(tmp);
 +                      tmp += DB_PAGE_SIZE;
 +                      base_indirect_ptr++;
 +                      page_entries++;
 +              } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->sbq_len));
                cqicb->sbq_addr =
                    cpu_to_le64(rx_ring->sbq_base_indirect_dma);
                cqicb->sbq_buf_size =
@@@ -3224,7 -3174,7 +3224,7 @@@ static int ql_adapter_reset(struct ql_a
  
        if (value & RST_FO_FR) {
                QPRINTK(qdev, IFDOWN, ERR,
-                       "ETIMEOUT!!! errored out of resetting the chip!\n");
+                       "ETIMEDOUT!!! errored out of resetting the chip!\n");
                status = -ETIMEDOUT;
        }
  
@@@ -3236,10 -3186,9 +3236,10 @@@ static void ql_display_dev_info(struct 
        struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
  
        QPRINTK(qdev, PROBE, INFO,
 -              "Function #%d, NIC Roll %d, NIC Rev = %d, "
 +              "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, "
                "XG Roll = %d, XG Rev = %d.\n",
                qdev->func,
 +              qdev->port,
                qdev->chip_rev_id & 0x0000000f,
                qdev->chip_rev_id >> 4 & 0x0000000f,
                qdev->chip_rev_id >> 8 & 0x0000000f,
@@@ -3315,6 -3264,7 +3315,6 @@@ static int ql_adapter_up(struct ql_adap
        err = ql_adapter_initialize(qdev);
        if (err) {
                QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n");
 -              spin_unlock(&qdev->hw_lock);
                goto err_init;
        }
        set_bit(QL_ADAPTER_UP, &qdev->flags);
@@@ -3411,6 -3361,7 +3411,6 @@@ static int ql_configure_rings(struct ql
         * completion handler rx_rings.
         */
        qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1;
 -      netif_set_gso_max_size(qdev->ndev, 65536);
  
        for (i = 0; i < qdev->tx_ring_count; i++) {
                tx_ring = &qdev->tx_ring[i];
@@@ -3693,53 -3644,12 +3693,53 @@@ static struct nic_operations qla8000_ni
        .port_initialize        = ql_8000_port_initialize,
  };
  
 +/* Find the pcie function number for the other NIC
 + * on this chip.  Since both NIC functions share a
 + * common firmware we have the lowest enabled function
 + * do any common work.  Examples would be resetting
 + * after a fatal firmware error, or doing a firmware
 + * coredump.
 + */
 +static int ql_get_alt_pcie_func(struct ql_adapter *qdev)
 +{
 +      int status = 0;
 +      u32 temp;
 +      u32 nic_func1, nic_func2;
 +
 +      status = ql_read_mpi_reg(qdev, MPI_TEST_FUNC_PORT_CFG,
 +                      &temp);
 +      if (status)
 +              return status;
 +
 +      nic_func1 = ((temp >> MPI_TEST_NIC1_FUNC_SHIFT) &
 +                      MPI_TEST_NIC_FUNC_MASK);
 +      nic_func2 = ((temp >> MPI_TEST_NIC2_FUNC_SHIFT) &
 +                      MPI_TEST_NIC_FUNC_MASK);
 +
 +      if (qdev->func == nic_func1)
 +              qdev->alt_func = nic_func2;
 +      else if (qdev->func == nic_func2)
 +              qdev->alt_func = nic_func1;
 +      else
 +              status = -EIO;
 +
 +      return status;
 +}
  
 -static void ql_get_board_info(struct ql_adapter *qdev)
 +static int ql_get_board_info(struct ql_adapter *qdev)
  {
 +      int status;
        qdev->func =
            (ql_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT;
 -      if (qdev->func) {
 +      if (qdev->func > 3)
 +              return -EIO;
 +
 +      status = ql_get_alt_pcie_func(qdev);
 +      if (status)
 +              return status;
 +
 +      qdev->port = (qdev->func < qdev->alt_func) ? 0 : 1;
 +      if (qdev->port) {
                qdev->xg_sem_mask = SEM_XGMAC1_MASK;
                qdev->port_link_up = STS_PL1;
                qdev->port_init = STS_PI1;
                qdev->nic_ops = &qla8012_nic_ops;
        else if (qdev->device_id == QLGE_DEVICE_ID_8000)
                qdev->nic_ops = &qla8000_nic_ops;
 +      return status;
  }
  
  static void ql_release_all(struct pci_dev *pdev)
@@@ -3853,12 -3762,7 +3853,12 @@@ static int __devinit ql_init_device(str
  
        qdev->ndev = ndev;
        qdev->pdev = pdev;
 -      ql_get_board_info(qdev);
 +      err = ql_get_board_info(qdev);
 +      if (err) {
 +              dev_err(&pdev->dev, "Register access failed.\n");
 +              err = -EIO;
 +              goto err_out;
 +      }
        qdev->msg_enable = netif_msg_init(debug, default_msg);
        spin_lock_init(&qdev->hw_lock);
        spin_lock_init(&qdev->stats_lock);
index a67c14a7befd7d1cb0ded74edb51d143827f399e,ac9493f6c1a149f1c5ccbc07f020f656256b8060..71afbf8b9c50c23d9c36acbc788dcda20d7e5336
@@@ -90,14 -90,14 +90,14 @@@ static int ql_get_mb_sts(struct ql_adap
   */
  static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev)
  {
 -      int count = 50; /* TODO: arbitrary for now. */
 +      int count = 100;
        u32 value;
  
        do {
                value = ql_read32(qdev, STS);
                if (value & STS_PI)
                        return 0;
 -              udelay(UDELAY_DELAY); /* 10us */
 +              mdelay(UDELAY_DELAY); /* 100ms */
        } while (--count);
        return -ETIMEDOUT;
  }
@@@ -141,7 -141,7 +141,7 @@@ end
  /* We are being asked by firmware to accept
   * a change to the port.  This is only
   * a change to max frame sizes (Tx/Rx), pause
-  * paramters, or loopback mode. We wake up a worker
+  * parameters, or loopback mode. We wake up a worker
   * to handler processing this since a mailbox command
   * will need to be sent to ACK the request.
   */
@@@ -371,7 -371,7 +371,7 @@@ static int ql_mpi_handler(struct ql_ada
        /* We are being asked by firmware to accept
         * a change to the port.  This is only
         * a change to max frame sizes (Tx/Rx), pause
-        * paramters, or loopback mode.
+        * parameters, or loopback mode.
         */
        case AEN_IDC_REQ:
                status = ql_idc_req_aen(qdev);
        /* Process and inbound IDC event.
         * This will happen when we're trying to
         * change tx/rx max frame size, change pause
-        * paramters or loopback mode.
+        * parameters or loopback mode.
         */
        case AEN_IDC_CMPLT:
        case AEN_IDC_EXT:
        }
  end:
        ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
 +      /* Restore the original mailbox count to
 +       * what the caller asked for.  This can get
 +       * changed when a mailbox command is waiting
 +       * for a response and an AEN arrives and
 +       * is handled.
 +       * */
 +      mbcp->out_count = orig_count;
        return status;
  }
  
@@@ -547,40 -540,6 +547,40 @@@ end
        return status;
  }
  
 +
 +/* Get MPI firmware version. This will be used for
 + * driver banner and for ethtool info.
 + * Returns zero on success.
 + */
 +int ql_mb_about_fw(struct ql_adapter *qdev)
 +{
 +      struct mbox_params mbc;
 +      struct mbox_params *mbcp = &mbc;
 +      int status = 0;
 +
 +      memset(mbcp, 0, sizeof(struct mbox_params));
 +
 +      mbcp->in_count = 1;
 +      mbcp->out_count = 3;
 +
 +      mbcp->mbox_in[0] = MB_CMD_ABOUT_FW;
 +
 +      status = ql_mailbox_command(qdev, mbcp);
 +      if (status)
 +              return status;
 +
 +      if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
 +              QPRINTK(qdev, DRV, ERR,
 +                      "Failed about firmware command\n");
 +              status = -EIO;
 +      }
 +
 +      /* Store the firmware version */
 +      qdev->fw_rev_id = mbcp->mbox_out[1];
 +
 +      return status;
 +}
 +
  /* Get functional state for MPI firmware.
   * Returns zero on success.
   */
@@@ -795,6 -754,7 +795,6 @@@ void ql_mpi_port_cfg_work(struct work_s
  {
        struct ql_adapter *qdev =
            container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
 -      struct net_device *ndev = qdev->ndev;
        int status;
  
        status = ql_mb_get_port_cfg(qdev);
                goto err;
        }
  
 -      if (ndev->mtu <= 2500)
 -              goto end;
 -      else if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
 +      if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
                        qdev->max_frame_size ==
                        CFG_DEFAULT_MAX_FRAME_SIZE)
                goto end;
@@@ -869,19 -831,13 +869,19 @@@ void ql_mpi_work(struct work_struct *wo
            container_of(work, struct ql_adapter, mpi_work.work);
        struct mbox_params mbc;
        struct mbox_params *mbcp = &mbc;
 +      int err = 0;
  
        mutex_lock(&qdev->mpi_mutex);
  
        while (ql_read32(qdev, STS) & STS_PI) {
                memset(mbcp, 0, sizeof(struct mbox_params));
                mbcp->out_count = 1;
 -              ql_mpi_handler(qdev, mbcp);
 +              /* Don't continue if an async event
 +               * did not complete properly.
 +               */
 +              err = ql_mpi_handler(qdev, mbcp);
 +              if (err)
 +                      break;
        }
  
        mutex_unlock(&qdev->mpi_mutex);
diff --combined drivers/net/r8169.c
index 007c881896d22a41535229346aa71f83f6d1d76c,3b19e0ce290fa4b6ba5f53a0b33c23b30ef098f8..35196faa084e87f797bdb33c2ce150590279d560
@@@ -66,7 -66,6 +66,6 @@@ static const int multicast_filter_limi
  #define RX_DMA_BURST  6       /* Maximum PCI burst, '6' is 1024 */
  #define TX_DMA_BURST  6       /* Maximum PCI burst, '6' is 1024 */
  #define EarlyTxThld   0x3F    /* 0x3F means NO early transmit */
- #define RxPacketMaxSize       0x3FE8  /* 16K - 1 - ETH_HLEN - VLAN - CRC... */
  #define SafeMtu               0x1c20  /* ... actually life sucks beyond ~7k */
  #define InterFrameGap 0x03    /* 3 means InterFrameGap = the shortest one */
  
@@@ -94,7 -93,6 +93,7 @@@
  #define RTL_R32(reg)          ((unsigned long) readl (ioaddr + (reg)))
  
  enum mac_version {
 +      RTL_GIGA_MAC_NONE   = 0x00,
        RTL_GIGA_MAC_VER_01 = 0x01, // 8169
        RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
        RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
@@@ -480,6 -478,7 +479,6 @@@ struct rtl8169_private 
        u16 intr_event;
        u16 napi_event;
        u16 intr_mask;
 -      int phy_auto_nego_reg;
        int phy_1000_ctrl_reg;
  #ifdef CONFIG_R8169_VLAN
        struct vlan_group *vlgrp;
@@@ -844,81 -843,76 +843,81 @@@ static int rtl8169_set_speed_xmii(struc
  {
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
 -      int auto_nego, giga_ctrl;
 -
 -      auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
 -      auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
 -                     ADVERTISE_100HALF | ADVERTISE_100FULL);
 -      giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
 -      giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
 +      int giga_ctrl, bmcr;
  
        if (autoneg == AUTONEG_ENABLE) {
 +              int auto_nego;
 +
 +              auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
                auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
                              ADVERTISE_100HALF | ADVERTISE_100FULL);
 -              giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
 -      } else {
 -              if (speed == SPEED_10)
 -                      auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL;
 -              else if (speed == SPEED_100)
 -                      auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL;
 -              else if (speed == SPEED_1000)
 -                      giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
 -
 -              if (duplex == DUPLEX_HALF)
 -                      auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL);
 -
 -              if (duplex == DUPLEX_FULL)
 -                      auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF);
 +              auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
  
 -              /* This tweak comes straight from Realtek's driver. */
 -              if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
 -                  ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
 -                   (tp->mac_version == RTL_GIGA_MAC_VER_16))) {
 -                      auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA;
 -              }
 -      }
 +              giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
 +              giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
  
 -      /* The 8100e/8101e/8102e do Fast Ethernet only. */
 -      if ((tp->mac_version == RTL_GIGA_MAC_VER_07) ||
 -          (tp->mac_version == RTL_GIGA_MAC_VER_08) ||
 -          (tp->mac_version == RTL_GIGA_MAC_VER_09) ||
 -          (tp->mac_version == RTL_GIGA_MAC_VER_10) ||
 -          (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
 -          (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
 -          (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
 -          (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
 -              if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
 -                  netif_msg_link(tp)) {
 +              /* The 8100e/8101e/8102e do Fast Ethernet only. */
 +              if ((tp->mac_version != RTL_GIGA_MAC_VER_07) &&
 +                  (tp->mac_version != RTL_GIGA_MAC_VER_08) &&
 +                  (tp->mac_version != RTL_GIGA_MAC_VER_09) &&
 +                  (tp->mac_version != RTL_GIGA_MAC_VER_10) &&
 +                  (tp->mac_version != RTL_GIGA_MAC_VER_13) &&
 +                  (tp->mac_version != RTL_GIGA_MAC_VER_14) &&
 +                  (tp->mac_version != RTL_GIGA_MAC_VER_15) &&
 +                  (tp->mac_version != RTL_GIGA_MAC_VER_16)) {
 +                      giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
 +              } else if (netif_msg_link(tp)) {
                        printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
                               dev->name);
                }
 -              giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
 -      }
  
 -      auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
 +              bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
 +
 +              if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
 +                  (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
 +                  (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
 +                      /*
 +                       * Wake up the PHY.
 +                       * Vendor specific (0x1f) and reserved (0x0e) MII
 +                       * registers.
 +                       */
 +                      mdio_write(ioaddr, 0x1f, 0x0000);
 +                      mdio_write(ioaddr, 0x0e, 0x0000);
 +              }
 +
 +              mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
 +              mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
 +      } else {
 +              giga_ctrl = 0;
 +
 +              if (speed == SPEED_10)
 +                      bmcr = 0;
 +              else if (speed == SPEED_100)
 +                      bmcr = BMCR_SPEED100;
 +              else
 +                      return -EINVAL;
 +
 +              if (duplex == DUPLEX_FULL)
 +                      bmcr |= BMCR_FULLDPLX;
  
 -      if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
 -          (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
 -          (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
 -              /*
 -               * Wake up the PHY.
 -               * Vendor specific (0x1f) and reserved (0x0e) MII registers.
 -               */
                mdio_write(ioaddr, 0x1f, 0x0000);
 -              mdio_write(ioaddr, 0x0e, 0x0000);
        }
  
 -      tp->phy_auto_nego_reg = auto_nego;
        tp->phy_1000_ctrl_reg = giga_ctrl;
  
 -      mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
 -      mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
 -      mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
 +      mdio_write(ioaddr, MII_BMCR, bmcr);
 +
 +      if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
 +          (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
 +              if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) {
 +                      mdio_write(ioaddr, 0x17, 0x2138);
 +                      mdio_write(ioaddr, 0x0e, 0x0260);
 +              } else {
 +                      mdio_write(ioaddr, 0x17, 0x2108);
 +                      mdio_write(ioaddr, 0x0e, 0x0000);
 +              }
 +      }
 +
        return 0;
  }
  
@@@ -1301,8 -1295,7 +1300,8 @@@ static void rtl8169_get_mac_version(str
                { 0xfc800000, 0x00800000,       RTL_GIGA_MAC_VER_02 },
                { 0xfc800000, 0x00000000,       RTL_GIGA_MAC_VER_01 },
  
 -              { 0x00000000, 0x00000000,       RTL_GIGA_MAC_VER_01 }   /* Catch-all */
 +              /* Catch-all */
 +              { 0x00000000, 0x00000000,       RTL_GIGA_MAC_NONE   }
        }, *p = mac_info;
        u32 reg;
  
        while ((reg & p->mask) != p->val)
                p++;
        tp->mac_version = p->mac_version;
 -
 -      if (p->mask == 0x00000000) {
 -              struct pci_dev *pdev = tp->pci_dev;
 -
 -              dev_info(&pdev->dev, "unknown MAC (%08x)\n", reg);
 -      }
  }
  
  static void rtl8169_print_mac_version(struct rtl8169_private *tp)
@@@ -1885,7 -1884,6 +1884,7 @@@ static const struct rtl_cfg_info 
        u16 intr_event;
        u16 napi_event;
        unsigned features;
 +      u8 default_ver;
  } rtl_cfg_infos [] = {
        [RTL_CFG_0] = {
                .hw_start       = rtl_hw_start_8169,
                .intr_event     = SYSErr | LinkChg | RxOverflow |
                                  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
                .napi_event     = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
 -              .features       = RTL_FEATURE_GMII
 +              .features       = RTL_FEATURE_GMII,
 +              .default_ver    = RTL_GIGA_MAC_VER_01,
        },
        [RTL_CFG_1] = {
                .hw_start       = rtl_hw_start_8168,
                .intr_event     = SYSErr | LinkChg | RxOverflow |
                                  TxErr | TxOK | RxOK | RxErr,
                .napi_event     = TxErr | TxOK | RxOK | RxOverflow,
 -              .features       = RTL_FEATURE_GMII | RTL_FEATURE_MSI
 +              .features       = RTL_FEATURE_GMII | RTL_FEATURE_MSI,
 +              .default_ver    = RTL_GIGA_MAC_VER_11,
        },
        [RTL_CFG_2] = {
                .hw_start       = rtl_hw_start_8101,
                .intr_event     = SYSErr | LinkChg | RxOverflow | PCSTimeout |
                                  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
                .napi_event     = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
 -              .features       = RTL_FEATURE_MSI
 +              .features       = RTL_FEATURE_MSI,
 +              .default_ver    = RTL_GIGA_MAC_VER_13,
        }
  };
  
@@@ -2096,15 -2091,6 +2095,15 @@@ rtl8169_init_one(struct pci_dev *pdev, 
        /* Identify chip attached to board */
        rtl8169_get_mac_version(tp, ioaddr);
  
 +      /* Use appropriate default if unknown */
 +      if (tp->mac_version == RTL_GIGA_MAC_NONE) {
 +              if (netif_msg_probe(tp)) {
 +                      dev_notice(&pdev->dev,
 +                                 "unknown MAC, using family default\n");
 +              }
 +              tp->mac_version = cfg->default_ver;
 +      }
 +
        rtl8169_print_mac_version(tp);
  
        for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) {
                        break;
        }
        if (i == ARRAY_SIZE(rtl_chip_info)) {
 -              /* Unknown chip: assume array element #0, original RTL-8169 */
 -              if (netif_msg_probe(tp)) {
 -                      dev_printk(KERN_DEBUG, &pdev->dev,
 -                              "unknown chip version, assuming %s\n",
 -                              rtl_chip_info[0].name);
 -              }
 -              i = 0;
 +              dev_err(&pdev->dev,
 +                      "driver bug, MAC version not found in rtl_chip_info\n");
 +              goto err_out_msi_5;
        }
        tp->chipset = i;
  
@@@ -2366,10 -2356,10 +2365,10 @@@ static u16 rtl_rw_cpluscmd(void __iome
        return cmd;
  }
  
- static void rtl_set_rx_max_size(void __iomem *ioaddr)
+ static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz)
  {
        /* Low hurts. Let's disable the filtering. */
-       RTL_W16(RxMaxSize, 16383);
+       RTL_W16(RxMaxSize, rx_buf_sz);
  }
  
  static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
@@@ -2416,7 -2406,7 +2415,7 @@@ static void rtl_hw_start_8169(struct ne
  
        RTL_W8(EarlyTxThres, EarlyTxThld);
  
-       rtl_set_rx_max_size(ioaddr);
+       rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
  
        if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
            (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
@@@ -2677,7 -2667,7 +2676,7 @@@ static void rtl_hw_start_8168(struct ne
  
        RTL_W8(EarlyTxThres, EarlyTxThld);
  
-       rtl_set_rx_max_size(ioaddr);
+       rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
  
        tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
  
@@@ -2855,7 -2845,7 +2854,7 @@@ static void rtl_hw_start_8101(struct ne
  
        RTL_W8(EarlyTxThres, EarlyTxThld);
  
-       rtl_set_rx_max_size(ioaddr);
+       rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
  
        tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
  
@@@ -3279,6 -3269,8 +3278,6 @@@ static int rtl8169_start_xmit(struct sk
        status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
        txd->opts1 = cpu_to_le32(status);
  
 -      dev->trans_start = jiffies;
 -
        tp->cur_tx += frags + 1;
  
        smp_wmb();
@@@ -3379,7 -3371,7 +3378,7 @@@ static void rtl8169_tx_interrupt(struc
                rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
  
                if (status & LastFrag) {
 -                      dev_kfree_skb_irq(tx_skb->skb);
 +                      dev_kfree_skb(tx_skb->skb);
                        tx_skb->skb = NULL;
                }
                dirty_tx++;
@@@ -3810,13 -3802,16 +3809,13 @@@ static struct net_device_stats *rtl8169
        return &dev->stats;
  }
  
 -#ifdef CONFIG_PM
 -
 -static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
 +static void rtl8169_net_suspend(struct net_device *dev)
  {
 -      struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
  
        if (!netif_running(dev))
 -              goto out_pci_suspend;
 +              return;
  
        netif_device_detach(dev);
        netif_stop_queue(dev);
        rtl8169_rx_missed(dev, ioaddr);
  
        spin_unlock_irq(&tp->lock);
 +}
  
 -out_pci_suspend:
 -      pci_save_state(pdev);
 -      pci_enable_wake(pdev, pci_choose_state(pdev, state),
 -              (tp->features & RTL_FEATURE_WOL) ? 1 : 0);
 -      pci_set_power_state(pdev, pci_choose_state(pdev, state));
 +#ifdef CONFIG_PM
 +
 +static int rtl8169_suspend(struct device *device)
 +{
 +      struct pci_dev *pdev = to_pci_dev(device);
 +      struct net_device *dev = pci_get_drvdata(pdev);
 +
 +      rtl8169_net_suspend(dev);
  
        return 0;
  }
  
 -static int rtl8169_resume(struct pci_dev *pdev)
 +static int rtl8169_resume(struct device *device)
  {
 +      struct pci_dev *pdev = to_pci_dev(device);
        struct net_device *dev = pci_get_drvdata(pdev);
  
 -      pci_set_power_state(pdev, PCI_D0);
 -      pci_restore_state(pdev);
 -      pci_enable_wake(pdev, PCI_D0, 0);
 -
        if (!netif_running(dev))
                goto out;
  
        return 0;
  }
  
 +static struct dev_pm_ops rtl8169_pm_ops = {
 +      .suspend = rtl8169_suspend,
 +      .resume = rtl8169_resume,
 +      .freeze = rtl8169_suspend,
 +      .thaw = rtl8169_resume,
 +      .poweroff = rtl8169_suspend,
 +      .restore = rtl8169_resume,
 +};
 +
 +#define RTL8169_PM_OPS        (&rtl8169_pm_ops)
 +
 +#else /* !CONFIG_PM */
 +
 +#define RTL8169_PM_OPS        NULL
 +
 +#endif /* !CONFIG_PM */
 +
  static void rtl_shutdown(struct pci_dev *pdev)
  {
 -      rtl8169_suspend(pdev, PMSG_SUSPEND);
 -}
 +      struct net_device *dev = pci_get_drvdata(pdev);
 +
 +      rtl8169_net_suspend(dev);
  
 -#endif /* CONFIG_PM */
 +      if (system_state == SYSTEM_POWER_OFF) {
 +              pci_wake_from_d3(pdev, true);
 +              pci_set_power_state(pdev, PCI_D3hot);
 +      }
 +}
  
  static struct pci_driver rtl8169_pci_driver = {
        .name           = MODULENAME,
        .id_table       = rtl8169_pci_tbl,
        .probe          = rtl8169_init_one,
        .remove         = __devexit_p(rtl8169_remove_one),
 -#ifdef CONFIG_PM
 -      .suspend        = rtl8169_suspend,
 -      .resume         = rtl8169_resume,
        .shutdown       = rtl_shutdown,
 -#endif
 +      .driver.pm      = RTL8169_PM_OPS,
  };
  
  static int __init rtl8169_init_module(void)
index 13dbc59bfe42f0f81785446499fe4568d52a79db,0337b9d673f46d45bbbbf083545ba4a76d5d0fbb..b40b6de2d086fc8a8d761c30e9fb74e99062b4e4
@@@ -79,7 -79,7 +79,7 @@@ MODULE_AUTHOR("Mike Phillips <mikep@lin
  MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver \n") ;
  MODULE_FIRMWARE(FW_NAME);
  
- /* Module paramters */
+ /* Module parameters */
  
  /* Ring Speed 0,4,16 
   * 0 = Autosense   
@@@ -1243,7 -1243,7 +1243,7 @@@ static int xl_xmit(struct sk_buff *skb
                return 0;
        } else {
                spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; 
 -              return 1;
 +              return NETDEV_TX_BUSY;
        }
  
  }
index b358bbbce33aba450c7741d834706d871de54dec,46a2cc92d97988ab605a9c6209a81737bd424dd8..b3715efdce562ee13acb5ac860191c0c07637260
@@@ -169,7 -169,7 +169,7 @@@ static char *open_min_error[] = 
        "Monitor Contention failer for RPL", "FDX Protocol Error"
  };
  
- /* Module paramters */
+ /* Module parameters */
  
  /* Ring Speed 0,4,16
   * 0 = Autosense         
@@@ -1187,7 -1187,7 +1187,7 @@@ static int streamer_xmit(struct sk_buf
        } else {
                netif_stop_queue(dev);
                spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
 -              return 1;
 +              return NETDEV_TX_BUSY;
        }
  }
  
index c36974925c1544cc4fbc7d88ef59bef00a290ae5,2d819fc85589609b42debab889e29ab00ade265d..451b54136ede04a82d1db929a136c440647a3799
@@@ -132,7 -132,7 +132,7 @@@ static char *open_min_error[] = {"No er
                                   "Reserved", "Reserved", "No Monitor Detected for RPL", 
                                   "Monitor Contention failer for RPL", "FDX Protocol Error"};
  
- /* Module paramters */
+ /* Module parameters */
  
  MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ; 
  MODULE_DESCRIPTION("Olympic PCI/Cardbus Chipset Driver") ; 
@@@ -1055,7 -1055,7 +1055,7 @@@ static int olympic_xmit(struct sk_buff 
                return 0;
        } else {
                spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
 -              return 1;
 +              return NETDEV_TX_BUSY;
        } 
  
  }
diff --combined drivers/net/usb/usbnet.c
index c94de6243140f00044fb9a2ee8d593006356e511,47f68cfa7e21344b6ebcb426023f032af43a9f28..22c0585a03198f75ea73b3974d394fc984a4ecc1
@@@ -37,7 -37,6 +37,7 @@@
  #include <linux/init.h>
  #include <linux/netdevice.h>
  #include <linux/etherdevice.h>
 +#include <linux/ctype.h>
  #include <linux/ethtool.h>
  #include <linux/workqueue.h>
  #include <linux/mii.h>
@@@ -157,36 -156,6 +157,36 @@@ int usbnet_get_endpoints(struct usbnet 
  }
  EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
  
 +static u8 nibble(unsigned char c)
 +{
 +      if (likely(isdigit(c)))
 +              return c - '0';
 +      c = toupper(c);
 +      if (likely(isxdigit(c)))
 +              return 10 + c - 'A';
 +      return 0;
 +}
 +
 +int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress)
 +{
 +      int             tmp, i;
 +      unsigned char   buf [13];
 +
 +      tmp = usb_string(dev->udev, iMACAddress, buf, sizeof buf);
 +      if (tmp != 12) {
 +              dev_dbg(&dev->udev->dev,
 +                      "bad MAC string %d fetch, %d\n", iMACAddress, tmp);
 +              if (tmp >= 0)
 +                      tmp = -EINVAL;
 +              return tmp;
 +      }
 +      for (i = tmp = 0; i < 6; i++, tmp += 2)
 +              dev->net->dev_addr [i] =
 +                      (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
 +      return 0;
 +}
 +EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr);
 +
  static void intr_complete (struct urb *urb);
  
  static int init_status (struct usbnet *dev, struct usb_interface *intf)
@@@ -429,7 -398,7 +429,7 @@@ static void rx_complete (struct urb *ur
  
        /* stalls need manual reset. this is rare ... except that
         * when going through USB 2.0 TTs, unplug appears this way.
-        * we avoid the highspeed version of the ETIMEOUT/EILSEQ
+        * we avoid the highspeed version of the ETIMEDOUT/EILSEQ
         * storm, recovering as needed.
         */
        case -EPIPE:
@@@ -1216,6 -1185,12 +1216,6 @@@ usbnet_probe (struct usb_interface *ude
  #endif
  
        net->netdev_ops = &usbnet_netdev_ops;
 -#ifdef CONFIG_COMPAT_NET_DEV_OPS
 -      net->hard_start_xmit = usbnet_start_xmit;
 -      net->open = usbnet_open;
 -      net->stop = usbnet_stop;
 -      net->tx_timeout = usbnet_tx_timeout;
 -#endif
        net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
        net->ethtool_ops = &usbnet_ethtool_ops;
  
diff --combined drivers/net/virtio_net.c
index f0bb1a4c83238c59243232b15928edaab66f2203,7fa620ddeb2170ea7b3393ea6b5cfdbf9adfb2e8..52198f6797a48a88a76bfee8cc4f6cfe64925ea8
@@@ -283,11 -283,10 +283,11 @@@ static void try_fill_recv_maxbufs(struc
        for (;;) {
                struct virtio_net_hdr *hdr;
  
 -              skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
 +              skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN + NET_IP_ALIGN);
                if (unlikely(!skb))
                        break;
  
 +              skb_reserve(skb, NET_IP_ALIGN);
                skb_put(skb, MAX_PACKET_LEN);
  
                hdr = skb_vnet_hdr(skb);
@@@ -471,7 -470,7 +471,7 @@@ static int xmit_skb(struct virtnet_inf
        }
  
        if (skb_is_gso(skb)) {
 -              hdr->hdr_len = skb_transport_header(skb) - skb->data;
 +              hdr->hdr_len = skb_headlen(skb);
                hdr->gso_size = skb_shinfo(skb)->gso_size;
                if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
                        hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
@@@ -623,9 -622,12 +623,9 @@@ static bool virtnet_send_command(struc
        unsigned int tmp;
        int i;
  
 -      if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
 -              BUG();  /* Caller should know better */
 -              return false;
 -      }
 -
 -      BUG_ON(out + in > VIRTNET_SEND_COMMAND_SG_MAX);
 +      /* Caller should know better */
 +      BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ||
 +              (out + in > VIRTNET_SEND_COMMAND_SG_MAX));
  
        out++; /* Add header */
        in++; /* Add return status */
                sg_set_buf(&sg[i + 1], sg_virt(s), s->length);
        sg_set_buf(&sg[out + in - 1], &status, sizeof(status));
  
 -      if (vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) != 0)
 -              BUG();
 +      BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi));
  
        vi->cvq->vq_ops->kick(vi->cvq);
  
@@@ -681,7 -684,6 +681,7 @@@ static void virtnet_set_rx_mode(struct 
        u8 promisc, allmulti;
        struct virtio_net_ctrl_mac *mac_data;
        struct dev_addr_list *addr;
 +      struct netdev_hw_addr *ha;
        void *buf;
        int i;
  
  
        /* Store the unicast list and count in the front of the buffer */
        mac_data->entries = dev->uc_count;
 -      addr = dev->uc_list;
 -      for (i = 0; i < dev->uc_count; i++, addr = addr->next)
 -              memcpy(&mac_data->macs[i][0], addr->da_addr, ETH_ALEN);
 +      i = 0;
 +      list_for_each_entry(ha, &dev->uc_list, list)
 +              memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN);
  
        sg_set_buf(&sg[0], mac_data,
                   sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN));
@@@ -843,6 -845,10 +843,10 @@@ static int virtnet_probe(struct virtio_
        int err;
        struct net_device *dev;
        struct virtnet_info *vi;
+       struct virtqueue *vqs[3];
+       vq_callback_t *callbacks[] = { skb_recv_done, skb_xmit_done, NULL};
+       const char *names[] = { "input", "output", "control" };
+       int nvqs;
  
        /* Allocate ourselves a network device with room for our info */
        dev = alloc_etherdev(sizeof(struct virtnet_info));
        if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
                vi->mergeable_rx_bufs = true;
  
-       /* We expect two virtqueues, receive then send. */
-       vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done);
-       if (IS_ERR(vi->rvq)) {
-               err = PTR_ERR(vi->rvq);
+       /* We expect two virtqueues, receive then send,
+        * and optionally control. */
+       nvqs = virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ? 3 : 2;
+       err = vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names);
+       if (err)
                goto free;
-       }
  
-       vi->svq = vdev->config->find_vq(vdev, 1, skb_xmit_done);
-       if (IS_ERR(vi->svq)) {
-               err = PTR_ERR(vi->svq);
-               goto free_recv;
-       }
+       vi->rvq = vqs[0];
+       vi->svq = vqs[1];
  
        if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
-               vi->cvq = vdev->config->find_vq(vdev, 2, NULL);
-               if (IS_ERR(vi->cvq)) {
-                       err = PTR_ERR(vi->svq);
-                       goto free_send;
-               }
+               vi->cvq = vqs[2];
  
                if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN))
                        dev->features |= NETIF_F_HW_VLAN_FILTER;
        err = register_netdev(dev);
        if (err) {
                pr_debug("virtio_net: registering device failed\n");
-               goto free_ctrl;
+               goto free_vqs;
        }
  
        /* Last of all, set up some receive buffers. */
  
  unregister:
        unregister_netdev(dev);
- free_ctrl:
-       if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
-               vdev->config->del_vq(vi->cvq);
- free_send:
-       vdev->config->del_vq(vi->svq);
- free_recv:
-       vdev->config->del_vq(vi->rvq);
+ free_vqs:
+       vdev->config->del_vqs(vdev);
  free:
        free_netdev(dev);
        return err;
@@@ -992,12 -987,10 +985,10 @@@ static void virtnet_remove(struct virti
  
        BUG_ON(vi->num != 0);
  
-       vdev->config->del_vq(vi->svq);
-       vdev->config->del_vq(vi->rvq);
-       if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
-               vdev->config->del_vq(vi->cvq);
        unregister_netdev(vi->dev);
  
+       vdev->config->del_vqs(vi->vdev);
        while (vi->pages)
                __free_pages(get_a_page(vi, GFP_KERNEL), 0);
  
index 08b1a284b6907ffcb7ae11760c5c6559ddb3b77a,a6dc317083d32c66ed027d440a295931125be25a..bb719b6114cb264fea47523f5e8ccab070101351
@@@ -579,7 -579,8 +579,8 @@@ static inline void queue_put_desc(unsig
        debug_desc(phys, desc);
        BUG_ON(phys & 0x1F);
        qmgr_put_entry(queue, phys);
-       BUG_ON(qmgr_stat_overflow(queue));
+       /* Don't check for queue overflow here, we've allocated sufficient
+          length and queues >= 32 don't support this check anyway. */
  }
  
  
@@@ -731,8 -732,8 +732,8 @@@ static int hss_hdlc_poll(struct napi_st
                dma_unmap_single(&dev->dev, desc->data,
                                 RX_SIZE, DMA_FROM_DEVICE);
  #else
 -              dma_sync_single(&dev->dev, desc->data,
 -                              RX_SIZE, DMA_FROM_DEVICE);
 +              dma_sync_single_for_cpu(&dev->dev, desc->data,
 +                                      RX_SIZE, DMA_FROM_DEVICE);
                memcpy_swab32((u32 *)skb->data, (u32 *)port->rx_buff_tab[n],
                              ALIGN(desc->pkt_len, 4) / 4);
  #endif
@@@ -789,10 -790,10 +790,10 @@@ static void hss_hdlc_txdone_irq(void *p
                free_buffer_irq(port->tx_buff_tab[n_desc]);
                port->tx_buff_tab[n_desc] = NULL;
  
-               start = qmgr_stat_empty(port->plat->txreadyq);
+               start = qmgr_stat_below_low_watermark(port->plat->txreadyq);
                queue_put_desc(port->plat->txreadyq,
                               tx_desc_phys(port, n_desc), desc);
-               if (start) {
+               if (start) { /* TX-ready queue was empty */
  #if DEBUG_TX
                        printk(KERN_DEBUG "%s: hss_hdlc_txdone_irq xmit"
                               " ready\n", dev->name);
@@@ -867,13 -868,13 +868,13 @@@ static int hss_hdlc_xmit(struct sk_buf
        queue_put_desc(queue_ids[port->id].tx, tx_desc_phys(port, n), desc);
        dev->trans_start = jiffies;
  
-       if (qmgr_stat_empty(txreadyq)) {
+       if (qmgr_stat_below_low_watermark(txreadyq)) { /* empty */
  #if DEBUG_TX
                printk(KERN_DEBUG "%s: hss_hdlc_xmit queue full\n", dev->name);
  #endif
                netif_stop_queue(dev);
                /* we could miss TX ready interrupt */
-               if (!qmgr_stat_empty(txreadyq)) {
+               if (!qmgr_stat_below_low_watermark(txreadyq)) {
  #if DEBUG_TX
                        printk(KERN_DEBUG "%s: hss_hdlc_xmit ready again\n",
                               dev->name);
index fb7541c28e587a4213dc9c78d00308181c9f0e63,3359497012aa468f32654388558887fb298e8f4c..5bc00db21b24f6e28f576613ab9dc6f22b95b3d6
@@@ -146,14 -146,14 +146,14 @@@ config LIBERTAS_C
          A driver for Marvell Libertas 8385 CompactFlash devices.
  
  config LIBERTAS_SDIO
 -      tristate "Marvell Libertas 8385 and 8686 SDIO 802.11b/g cards"
 +      tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
        depends on LIBERTAS && MMC
        ---help---
 -        A driver for Marvell Libertas 8385 and 8686 SDIO devices.
 +        A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
  
  config LIBERTAS_SPI
        tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
 -      depends on LIBERTAS && SPI && GENERIC_GPIO
 +      depends on LIBERTAS && SPI
        ---help---
          A driver for Marvell Libertas 8686 SPI devices.
  
@@@ -310,7 -310,7 +310,7 @@@ config PRISM5
          If you want to compile the driver as a module ( = code which can be
          inserted in and removed from the running kernel whenever you want),
          say M here and read <file:Documentation/kbuild/modules.txt>.
-         The module will be called prism54.ko.
+         The module will be called prism54.
  
  config USB_ZD1201
        tristate "USB ZD1201 based Wireless device support"
  config USB_NET_RNDIS_WLAN
        tristate "Wireless RNDIS USB support"
        depends on USB && WLAN_80211 && EXPERIMENTAL
 +      depends on CFG80211
        select USB_USBNET
        select USB_NET_CDCETHER
        select USB_NET_RNDIS_HOST
@@@ -435,13 -434,6 +435,13 @@@ config RTL818
  
          Thanks to Realtek for their support!
  
 +# If possible, automatically enable LEDs for RTL8187.
 +
 +config RTL8187_LEDS
 +      bool
 +      depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
 +      default y
 +
  config ADM8211
        tristate "ADMtek ADM8211 support"
        depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
@@@ -492,7 -484,9 +492,7 @@@ config MWL8
          will be called mwl8k.  If unsure, say N.
  
  source "drivers/net/wireless/p54/Kconfig"
 -source "drivers/net/wireless/ath5k/Kconfig"
 -source "drivers/net/wireless/ath9k/Kconfig"
 -source "drivers/net/wireless/ar9170/Kconfig"
 +source "drivers/net/wireless/ath/Kconfig"
  source "drivers/net/wireless/ipw2x00/Kconfig"
  source "drivers/net/wireless/iwlwifi/Kconfig"
  source "drivers/net/wireless/hostap/Kconfig"
@@@ -501,7 -495,5 +501,7 @@@ source "drivers/net/wireless/b43legacy/
  source "drivers/net/wireless/zd1211rw/Kconfig"
  source "drivers/net/wireless/rt2x00/Kconfig"
  source "drivers/net/wireless/orinoco/Kconfig"
 +source "drivers/net/wireless/wl12xx/Kconfig"
 +source "drivers/net/wireless/iwmc3200wifi/Kconfig"
  
  endmenu
index 029ccb6bdbaa0fb67c11e4453652a139a811df63,736162324ba4e8457bbaaabaa3176d9c697e8e9c..e092af09d6bfa46e9f5adaf95fcfdd75ab3a13b6
@@@ -5,11 -5,16 +5,11 @@@ config IWLWIF
        select FW_LOADER
        select MAC80211_LEDS if IWLWIFI_LEDS
        select LEDS_CLASS if IWLWIFI_LEDS
 -      select RFKILL if IWLWIFI_RFKILL
  
  config IWLWIFI_LEDS
        bool "Enable LED support in iwlagn and iwl3945 drivers"
        depends on IWLWIFI
  
 -config IWLWIFI_RFKILL
 -      bool "Enable RF kill support in iwlagn and iwl3945 drivers"
 -      depends on IWLWIFI
 -
  config IWLWIFI_SPECTRUM_MEASUREMENT
        bool "Enable Spectrum Measurement in iwlagn driver"
        depends on IWLWIFI
@@@ -70,7 -75,7 +70,7 @@@ config IWLAG
          If you want to compile the driver as a module ( = code which can be
          inserted in and removed from the running kernel whenever you want),
          say M here and read <file:Documentation/kbuild/modules.txt>.  The
-         module will be called iwlagn.ko.
+         module will be called iwlagn.
  
  
  config IWL4965
@@@ -108,7 -113,7 +108,7 @@@ config IWL394
          If you want to compile the driver as a module ( = code which can be
          inserted in and removed from the running kernel whenever you want),
          say M here and read <file:Documentation/kbuild/modules.txt>.  The
-         module will be called iwl3945.ko.
+         module will be called iwl3945.
  
  config IWL3945_SPECTRUM_MEASUREMENT
        bool "Enable Spectrum Measurement in iwl3945 driver"
index 7441d558511081981e47a4b2d2e1fecaf84d4082,ff0042ffe3e9d84820311decf72aa9ddd9a7cb21..3bec3dbd3450cf105e91fbc72c062da7b16e21e7
@@@ -2,7 -2,7 +2,7 @@@
   * Driver for RNDIS based wireless USB devices.
   *
   * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net>
 - * Copyright (C) 2008 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
 + * Copyright (C) 2008-2009 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
@@@ -42,7 -42,6 +42,7 @@@
  #include <linux/ctype.h>
  #include <linux/spinlock.h>
  #include <net/iw_handler.h>
 +#include <net/cfg80211.h>
  #include <linux/usb/usbnet.h>
  #include <linux/usb/rndis_host.h>
  
@@@ -157,55 -156,43 +157,55 @@@ MODULE_PARM_DESC(workaround_interval
  #define NDIS_802_11_LENGTH_RATES_EX 16
  
  enum ndis_80211_net_type {
 -      ndis_80211_type_freq_hop,
 -      ndis_80211_type_direct_seq,
 -      ndis_80211_type_ofdm_a,
 -      ndis_80211_type_ofdm_g
 +      NDIS_80211_TYPE_FREQ_HOP,
 +      NDIS_80211_TYPE_DIRECT_SEQ,
 +      NDIS_80211_TYPE_OFDM_A,
 +      NDIS_80211_TYPE_OFDM_G
  };
  
  enum ndis_80211_net_infra {
 -      ndis_80211_infra_adhoc,
 -      ndis_80211_infra_infra,
 -      ndis_80211_infra_auto_unknown
 +      NDIS_80211_INFRA_ADHOC,
 +      NDIS_80211_INFRA_INFRA,
 +      NDIS_80211_INFRA_AUTO_UNKNOWN
  };
  
  enum ndis_80211_auth_mode {
 -      ndis_80211_auth_open,
 -      ndis_80211_auth_shared,
 -      ndis_80211_auth_auto_switch,
 -      ndis_80211_auth_wpa,
 -      ndis_80211_auth_wpa_psk,
 -      ndis_80211_auth_wpa_none,
 -      ndis_80211_auth_wpa2,
 -      ndis_80211_auth_wpa2_psk
 +      NDIS_80211_AUTH_OPEN,
 +      NDIS_80211_AUTH_SHARED,
 +      NDIS_80211_AUTH_AUTO_SWITCH,
 +      NDIS_80211_AUTH_WPA,
 +      NDIS_80211_AUTH_WPA_PSK,
 +      NDIS_80211_AUTH_WPA_NONE,
 +      NDIS_80211_AUTH_WPA2,
 +      NDIS_80211_AUTH_WPA2_PSK
  };
  
  enum ndis_80211_encr_status {
 -      ndis_80211_encr_wep_enabled,
 -      ndis_80211_encr_disabled,
 -      ndis_80211_encr_wep_key_absent,
 -      ndis_80211_encr_not_supported,
 -      ndis_80211_encr_tkip_enabled,
 -      ndis_80211_encr_tkip_key_absent,
 -      ndis_80211_encr_ccmp_enabled,
 -      ndis_80211_encr_ccmp_key_absent
 +      NDIS_80211_ENCR_WEP_ENABLED,
 +      NDIS_80211_ENCR_DISABLED,
 +      NDIS_80211_ENCR_WEP_KEY_ABSENT,
 +      NDIS_80211_ENCR_NOT_SUPPORTED,
 +      NDIS_80211_ENCR_TKIP_ENABLED,
 +      NDIS_80211_ENCR_TKIP_KEY_ABSENT,
 +      NDIS_80211_ENCR_CCMP_ENABLED,
 +      NDIS_80211_ENCR_CCMP_KEY_ABSENT
  };
  
  enum ndis_80211_priv_filter {
 -      ndis_80211_priv_accept_all,
 -      ndis_80211_priv_8021x_wep
 +      NDIS_80211_PRIV_ACCEPT_ALL,
 +      NDIS_80211_PRIV_8021X_WEP
 +};
 +
 +enum ndis_80211_addkey_bits {
 +      NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28),
 +      NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29),
 +      NDIS_80211_ADDKEY_PAIRWISE_KEY = cpu_to_le32(1 << 30),
 +      NDIS_80211_ADDKEY_TRANSMIT_KEY = cpu_to_le32(1 << 31)
 +};
 +
 +enum ndis_80211_addwep_bits {
 +      NDIS_80211_ADDWEP_PERCLIENT_KEY = cpu_to_le32(1 << 30),
 +      NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31)
  };
  
  struct ndis_80211_ssid {
@@@ -321,6 -308,7 +321,6 @@@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KE
  #define CAP_MODE_80211B               2
  #define CAP_MODE_80211G               4
  #define CAP_MODE_MASK         7
 -#define CAP_SUPPORT_TXPOWER   8
  
  #define WORK_LINK_UP          (1<<0)
  #define WORK_LINK_DOWN                (1<<1)
  
  #define COMMAND_BUFFER_SIZE   (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set))
  
 -/* RNDIS device private data */
 -struct rndis_wext_private {
 -      char name[32];
 +static const struct ieee80211_channel rndis_channels[] = {
 +      { .center_freq = 2412 },
 +      { .center_freq = 2417 },
 +      { .center_freq = 2422 },
 +      { .center_freq = 2427 },
 +      { .center_freq = 2432 },
 +      { .center_freq = 2437 },
 +      { .center_freq = 2442 },
 +      { .center_freq = 2447 },
 +      { .center_freq = 2452 },
 +      { .center_freq = 2457 },
 +      { .center_freq = 2462 },
 +      { .center_freq = 2467 },
 +      { .center_freq = 2472 },
 +      { .center_freq = 2484 },
 +};
  
 +static const struct ieee80211_rate rndis_rates[] = {
 +      { .bitrate = 10 },
 +      { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 +      { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 +      { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 +      { .bitrate = 60 },
 +      { .bitrate = 90 },
 +      { .bitrate = 120 },
 +      { .bitrate = 180 },
 +      { .bitrate = 240 },
 +      { .bitrate = 360 },
 +      { .bitrate = 480 },
 +      { .bitrate = 540 }
 +};
 +
 +/* RNDIS device private data */
 +struct rndis_wlan_private {
        struct usbnet *usbdev;
  
 +      struct wireless_dev wdev;
 +
 +      struct cfg80211_scan_request *scan_request;
 +
        struct workqueue_struct *workqueue;
        struct delayed_work stats_work;
 +      struct delayed_work scan_work;
        struct work_struct work;
        struct mutex command_lock;
        spinlock_t stats_lock;
        unsigned long work_pending;
  
 +      struct ieee80211_supported_band band;
 +      struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)];
 +      struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)];
 +
        struct iw_statistics iwstats;
        struct iw_statistics privstats;
  
 -      int  nick_len;
 -      char nick[32];
 -
        int caps;
        int multicast_size;
  
        int  encr_tx_key_index;
        char encr_keys[4][32];
        int  encr_key_len[4];
 +      char encr_key_wpa[4];
        int  wpa_version;
        int  wpa_keymgmt;
        int  wpa_authalg;
        u8 command_buffer[COMMAND_BUFFER_SIZE];
  };
  
 +/*
 + * cfg80211 ops
 + */
 +static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
 +                                      enum nl80211_iftype type, u32 *flags,
 +                                      struct vif_params *params);
 +
 +static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
 +                      struct cfg80211_scan_request *request);
  
 -static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
 +static struct cfg80211_ops rndis_config_ops = {
 +      .change_virtual_intf = rndis_change_virtual_intf,
 +      .scan = rndis_scan,
 +};
 +
 +static void *rndis_wiphy_privid = &rndis_wiphy_privid;
  
  static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
  
@@@ -441,13 -378,13 +441,13 @@@ static const unsigned char ffff_bssid[E
                                                        0xff, 0xff, 0xff };
  
  
 -static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev)
 +static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev)
  {
 -      return (struct rndis_wext_private *)dev->driver_priv;
 +      return (struct rndis_wlan_private *)dev->driver_priv;
  }
  
  
 -static u32 get_bcm4320_power(struct rndis_wext_private *priv)
 +static u32 get_bcm4320_power(struct rndis_wlan_private *priv)
  {
        return BCM4320_DEFAULT_TXPOWER *
                bcm4320_power_output[priv->param_power_output] / 100;
@@@ -480,7 -417,7 +480,7 @@@ static int rndis_error_status(__le32 rn
  
  static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
        union {
                void                    *buf;
                struct rndis_msg_hdr    *header;
  
  static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
        union {
                void                    *buf;
                struct rndis_msg_hdr    *header;
@@@ -647,7 -584,7 +647,7 @@@ static int rndis_set_config_parameter(s
        ret = rndis_set_oid(dev, OID_GEN_RNDIS_CONFIG_PARAMETER,
                                                        infobuf, info_len);
        if (ret != 0)
-               devdbg(dev, "setting rndis config paramater failed, %d.", ret);
+               devdbg(dev, "setting rndis config parameter failed, %d.", ret);
  
        kfree(infobuf);
        return ret;
@@@ -747,7 -684,7 +747,7 @@@ static int get_essid(struct usbnet *usb
  
  static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        int ret;
  
        ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
@@@ -794,7 -731,7 +794,7 @@@ static int is_associated(struct usbnet 
  
  static int disassociate(struct usbnet *usbdev, int reset_ssid)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_ssid ssid;
        int i, ret = 0;
  
  
  static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tmp;
        int auth_mode, ret;
  
  
        if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) {
                if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
 -                      auth_mode = ndis_80211_auth_wpa2;
 +                      auth_mode = NDIS_80211_AUTH_WPA2;
                else
 -                      auth_mode = ndis_80211_auth_wpa2_psk;
 +                      auth_mode = NDIS_80211_AUTH_WPA2_PSK;
        } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) {
                if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
 -                      auth_mode = ndis_80211_auth_wpa;
 +                      auth_mode = NDIS_80211_AUTH_WPA;
                else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK)
 -                      auth_mode = ndis_80211_auth_wpa_psk;
 +                      auth_mode = NDIS_80211_AUTH_WPA_PSK;
                else
 -                      auth_mode = ndis_80211_auth_wpa_none;
 +                      auth_mode = NDIS_80211_AUTH_WPA_NONE;
        } else if (authalg & IW_AUTH_ALG_SHARED_KEY) {
                if (authalg & IW_AUTH_ALG_OPEN_SYSTEM)
 -                      auth_mode = ndis_80211_auth_auto_switch;
 +                      auth_mode = NDIS_80211_AUTH_AUTO_SWITCH;
                else
 -                      auth_mode = ndis_80211_auth_shared;
 +                      auth_mode = NDIS_80211_AUTH_SHARED;
        } else
 -              auth_mode = ndis_80211_auth_open;
 +              auth_mode = NDIS_80211_AUTH_OPEN;
  
        tmp = cpu_to_le32(auth_mode);
        ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
  
  static int set_priv_filter(struct usbnet *usbdev)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tmp;
  
        devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version);
  
        if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 ||
            priv->wpa_version & IW_AUTH_WPA_VERSION_WPA)
 -              tmp = cpu_to_le32(ndis_80211_priv_8021x_wep);
 +              tmp = cpu_to_le32(NDIS_80211_PRIV_8021X_WEP);
        else
 -              tmp = cpu_to_le32(ndis_80211_priv_accept_all);
 +              tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL);
  
        return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp,
                                                                sizeof(tmp));
  
  static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tmp;
        int encr_mode, ret;
  
                groupwise);
  
        if (pairwise & IW_AUTH_CIPHER_CCMP)
 -              encr_mode = ndis_80211_encr_ccmp_enabled;
 +              encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
        else if (pairwise & IW_AUTH_CIPHER_TKIP)
 -              encr_mode = ndis_80211_encr_tkip_enabled;
 +              encr_mode = NDIS_80211_ENCR_TKIP_ENABLED;
        else if (pairwise &
                 (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
 -              encr_mode = ndis_80211_encr_wep_enabled;
 +              encr_mode = NDIS_80211_ENCR_WEP_ENABLED;
        else if (groupwise & IW_AUTH_CIPHER_CCMP)
 -              encr_mode = ndis_80211_encr_ccmp_enabled;
 +              encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
        else if (groupwise & IW_AUTH_CIPHER_TKIP)
 -              encr_mode = ndis_80211_encr_tkip_enabled;
 +              encr_mode = NDIS_80211_ENCR_TKIP_ENABLED;
        else
 -              encr_mode = ndis_80211_encr_disabled;
 +              encr_mode = NDIS_80211_ENCR_DISABLED;
  
        tmp = cpu_to_le32(encr_mode);
        ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp,
  
  static int set_assoc_params(struct usbnet *usbdev)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
  
        set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg);
        set_priv_filter(usbdev);
  
  static int set_infra_mode(struct usbnet *usbdev, int mode)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tmp;
        int ret, i;
  
        if (priv->wpa_keymgmt == 0 ||
                priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) {
                for (i = 0; i < 4; i++) {
 -                      if (priv->encr_key_len[i] > 0)
 +                      if (priv->encr_key_len[i] > 0 && !priv->encr_key_wpa[i])
                                add_wep_key(usbdev, priv->encr_keys[i],
                                                priv->encr_key_len[i], i);
                }
  
  static void set_default_iw_params(struct usbnet *usbdev)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
  
        priv->wpa_keymgmt = 0;
        priv->wpa_version = 0;
  
 -      set_infra_mode(usbdev, ndis_80211_infra_infra);
 +      set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
        set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
                                IW_AUTH_ALG_OPEN_SYSTEM);
        set_priv_filter(usbdev);
@@@ -996,7 -933,7 +996,7 @@@ static int deauthenticate(struct usbne
  /* index must be 0 - N, as per NDIS  */
  static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_wep_key ndis_key;
        int ret;
  
        memcpy(&ndis_key.material, key, key_len);
  
        if (index == priv->encr_tx_key_index) {
 -              ndis_key.index |= cpu_to_le32(1 << 31);
 +              ndis_key.index |= NDIS_80211_ADDWEP_TRANSMIT_KEY;
                ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104,
                                                IW_AUTH_CIPHER_NONE);
                if (ret)
        }
  
        priv->encr_key_len[index] = key_len;
 +      priv->encr_key_wpa[index] = 0;
        memcpy(&priv->encr_keys[index], key, key_len);
  
        return 0;
  }
  
  
 +static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
 +                      int index, const struct sockaddr *addr,
 +                      const u8 *rx_seq, int alg, int flags)
 +{
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 +      struct ndis_80211_key ndis_key;
 +      int ret;
 +
 +      if (index < 0 || index >= 4)
 +              return -EINVAL;
 +      if (key_len > sizeof(ndis_key.material) || key_len < 0)
 +              return -EINVAL;
 +      if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq)
 +              return -EINVAL;
 +      if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !addr)
 +              return -EINVAL;
 +
 +      devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index,
 +                      !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY),
 +                      !!(flags & NDIS_80211_ADDKEY_PAIRWISE_KEY),
 +                      !!(flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ));
 +
 +      memset(&ndis_key, 0, sizeof(ndis_key));
 +
 +      ndis_key.size = cpu_to_le32(sizeof(ndis_key) -
 +                              sizeof(ndis_key.material) + key_len);
 +      ndis_key.length = cpu_to_le32(key_len);
 +      ndis_key.index = cpu_to_le32(index) | flags;
 +
 +      if (alg == IW_ENCODE_ALG_TKIP && key_len == 32) {
 +              /* wpa_supplicant gives us the Michael MIC RX/TX keys in
 +               * different order than NDIS spec, so swap the order here. */
 +              memcpy(ndis_key.material, key, 16);
 +              memcpy(ndis_key.material + 16, key + 24, 8);
 +              memcpy(ndis_key.material + 24, key + 16, 8);
 +      } else
 +              memcpy(ndis_key.material, key, key_len);
 +
 +      if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ)
 +              memcpy(ndis_key.rsc, rx_seq, 6);
 +
 +      if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) {
 +              /* pairwise key */
 +              memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN);
 +      } else {
 +              /* group key */
 +              if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
 +                      memset(ndis_key.bssid, 0xff, ETH_ALEN);
 +              else
 +                      get_bssid(usbdev, ndis_key.bssid);
 +      }
 +
 +      ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
 +                                      le32_to_cpu(ndis_key.size));
 +      devdbg(usbdev, "add_wpa_key: OID_802_11_ADD_KEY -> %08X", ret);
 +      if (ret != 0)
 +              return ret;
 +
 +      priv->encr_key_len[index] = key_len;
 +      priv->encr_key_wpa[index] = 1;
 +
 +      if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY)
 +              priv->encr_tx_key_index = index;
 +
 +      return 0;
 +}
 +
 +
  /* remove_key is for both wep and wpa */
  static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_remove_key remove_key;
        __le32 keyindex;
        int ret;
                return 0;
  
        priv->encr_key_len[index] = 0;
 +      priv->encr_key_wpa[index] = 0;
        memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index]));
  
        if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP ||
                if (bssid) {
                        /* pairwise key */
                        if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0)
 -                              remove_key.index |= cpu_to_le32(1 << 30);
 +                              remove_key.index |=
 +                                      NDIS_80211_ADDKEY_PAIRWISE_KEY;
                        memcpy(remove_key.bssid, bssid,
                                        sizeof(remove_key.bssid));
                } else
  
  static void set_multicast_list(struct usbnet *usbdev)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct dev_mc_list *mclist;
        __le32 filter;
        int ret, i, size;
  
  
  /*
 - * wireless extension handlers
 + * cfg80211 ops
   */
 -
 -static int rndis_iw_commit(struct net_device *dev,
 -    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 +static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
 +                                      enum nl80211_iftype type, u32 *flags,
 +                                      struct vif_params *params)
  {
 -      /* dummy op */
 -      return 0;
 +      struct net_device *dev;
 +      struct usbnet *usbdev;
 +      int mode;
 +
 +      /* we're under RTNL */
 +      dev = __dev_get_by_index(&init_net, ifindex);
 +      if (!dev)
 +              return -ENODEV;
 +      usbdev = netdev_priv(dev);
 +
 +      switch (type) {
 +      case NL80211_IFTYPE_ADHOC:
 +              mode = NDIS_80211_INFRA_ADHOC;
 +              break;
 +      case NL80211_IFTYPE_STATION:
 +              mode = NDIS_80211_INFRA_INFRA;
 +              break;
 +      default:
 +              return -EINVAL;
 +      }
 +
 +      return set_infra_mode(usbdev, mode);
  }
  
  
 -static int rndis_iw_get_range(struct net_device *dev,
 -    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 +#define SCAN_DELAY_JIFFIES (HZ)
 +static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
 +                      struct cfg80211_scan_request *request)
  {
 -      struct iw_range *range = (struct iw_range *)extra;
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 -      int len, ret, i, j, num, has_80211g_rates;
 -      u8 rates[8];
 -      __le32 tx_power;
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 +      int ret;
 +      __le32 tmp;
 +
 +      devdbg(usbdev, "cfg80211.scan");
  
 -      devdbg(usbdev, "SIOCGIWRANGE");
 +      if (!request)
 +              return -EINVAL;
  
 -      /* clear iw_range struct */
 -      memset(range, 0, sizeof(*range));
 -      wrqu->data.length = sizeof(*range);
 +      if (priv->scan_request && priv->scan_request != request)
 +              return -EBUSY;
  
 -      range->txpower_capa = IW_TXPOW_MWATT;
 -      range->num_txpower = 1;
 -      if (priv->caps & CAP_SUPPORT_TXPOWER) {
 -              len = sizeof(tx_power);
 -              ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
 -                                              &tx_power, &len);
 -              if (ret == 0 && le32_to_cpu(tx_power) != 0xFF)
 -                      range->txpower[0] = le32_to_cpu(tx_power);
 -              else
 -                      range->txpower[0] = get_bcm4320_power(priv);
 -      } else
 -              range->txpower[0] = get_bcm4320_power(priv);
 +      priv->scan_request = request;
  
 -      len = sizeof(rates);
 -      ret = rndis_query_oid(usbdev, OID_802_11_SUPPORTED_RATES, &rates,
 -                                                              &len);
 -      has_80211g_rates = 0;
 +      tmp = cpu_to_le32(1);
 +      ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
 +                                                      sizeof(tmp));
        if (ret == 0) {
 -              j = 0;
 -              for (i = 0; i < len; i++) {
 -                      if (rates[i] == 0)
 -                              break;
 -                      range->bitrate[j] = (rates[i] & 0x7f) * 500000;
 -                      /* check for non 802.11b rates */
 -                      if (range->bitrate[j] == 6000000 ||
 -                              range->bitrate[j] == 9000000 ||
 -                              (range->bitrate[j] >= 12000000 &&
 -                              range->bitrate[j] != 22000000))
 -                              has_80211g_rates = 1;
 -                      j++;
 -              }
 -              range->num_bitrates = j;
 -      } else
 -              range->num_bitrates = 0;
 -
 -      /* fill in 802.11g rates */
 -      if (has_80211g_rates) {
 -              num = range->num_bitrates;
 -              for (i = 0; i < ARRAY_SIZE(rates_80211g); i++) {
 -                      for (j = 0; j < num; j++) {
 -                              if (range->bitrate[j] ==
 -                                      rates_80211g[i] * 1000000)
 -                                      break;
 -                      }
 -                      if (j == num)
 -                              range->bitrate[range->num_bitrates++] =
 -                                      rates_80211g[i] * 1000000;
 -                      if (range->num_bitrates == IW_MAX_BITRATES)
 -                              break;
 -              }
 +              /* Wait before retrieving scan results from device */
 +              queue_delayed_work(priv->workqueue, &priv->scan_work,
 +                      SCAN_DELAY_JIFFIES);
 +      }
  
 -              /* estimated max real througput in bps */
 -              range->throughput = 54 * 1000 * 1000 / 2;
 +      return ret;
 +}
  
 -              /* ~35% more with afterburner */
 -              if (priv->param_afterburner)
 -                      range->throughput = range->throughput / 100 * 135;
 -      } else {
 -              /* estimated max real througput in bps */
 -              range->throughput = 11 * 1000 * 1000 / 2;
 +
 +static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
 +                                      struct ndis_80211_bssid_ex *bssid)
 +{
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 +      struct ieee80211_channel *channel;
 +      s32 signal;
 +      u64 timestamp;
 +      u16 capability;
 +      u16 beacon_interval;
 +      struct ndis_80211_fixed_ies *fixed;
 +      int ie_len, bssid_len;
 +      u8 *ie;
 +
 +      /* parse bssid structure */
 +      bssid_len = le32_to_cpu(bssid->length);
 +
 +      if (bssid_len < sizeof(struct ndis_80211_bssid_ex) +
 +                      sizeof(struct ndis_80211_fixed_ies))
 +              return NULL;
 +
 +      fixed = (struct ndis_80211_fixed_ies *)bssid->ies;
 +
 +      ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
 +      ie_len = min(bssid_len - (int)sizeof(*bssid),
 +                                      (int)le32_to_cpu(bssid->ie_length));
 +      ie_len -= sizeof(struct ndis_80211_fixed_ies);
 +      if (ie_len < 0)
 +              return NULL;
 +
 +      /* extract data for cfg80211_inform_bss */
 +      channel = ieee80211_get_channel(priv->wdev.wiphy,
 +                      KHZ_TO_MHZ(le32_to_cpu(bssid->config.ds_config)));
 +      if (!channel)
 +              return NULL;
 +
 +      signal = level_to_qual(le32_to_cpu(bssid->rssi));
 +      timestamp = le64_to_cpu(*(__le64 *)fixed->timestamp);
 +      capability = le16_to_cpu(fixed->capabilities);
 +      beacon_interval = le16_to_cpu(fixed->beacon_interval);
 +
 +      return cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac,
 +              timestamp, capability, beacon_interval, ie, ie_len, signal,
 +              GFP_KERNEL);
 +}
 +
 +
 +static int rndis_check_bssid_list(struct usbnet *usbdev)
 +{
 +      void *buf = NULL;
 +      struct ndis_80211_bssid_list_ex *bssid_list;
 +      struct ndis_80211_bssid_ex *bssid;
 +      int ret = -EINVAL, len, count, bssid_len;
 +
 +      devdbg(usbdev, "check_bssid_list");
 +
 +      len = CONTROL_BUFFER_SIZE;
 +      buf = kmalloc(len, GFP_KERNEL);
 +      if (!buf) {
 +              ret = -ENOMEM;
 +              goto out;
        }
  
 -      range->num_channels = 14;
 +      ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
 +      if (ret != 0)
 +              goto out;
  
 -      for (i = 0; (i < 14) && (i < IW_MAX_FREQUENCIES); i++) {
 -              range->freq[i].i = i + 1;
 -              range->freq[i].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
 -              range->freq[i].e = 1;
 +      bssid_list = buf;
 +      bssid = bssid_list->bssid;
 +      bssid_len = le32_to_cpu(bssid->length);
 +      count = le32_to_cpu(bssid_list->num_items);
 +      devdbg(usbdev, "check_bssid_list: %d BSSIDs found", count);
 +
 +      while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
 +              rndis_bss_info_update(usbdev, bssid);
 +
 +              bssid = (void *)bssid + bssid_len;
 +              bssid_len = le32_to_cpu(bssid->length);
 +              count--;
        }
 -      range->num_frequency = i;
  
 -      range->min_rts = 0;
 -      range->max_rts = 2347;
 -      range->min_frag = 256;
 -      range->max_frag = 2346;
 +out:
 +      kfree(buf);
 +      return ret;
 +}
  
 -      range->max_qual.qual = 100;
 -      range->max_qual.level = 154;
 -      range->max_qual.updated = IW_QUAL_QUAL_UPDATED
 -                              | IW_QUAL_LEVEL_UPDATED
 -                              | IW_QUAL_NOISE_INVALID;
  
 -      range->we_version_compiled = WIRELESS_EXT;
 -      range->we_version_source = WIRELESS_EXT;
 +static void rndis_get_scan_results(struct work_struct *work)
 +{
 +      struct rndis_wlan_private *priv =
 +              container_of(work, struct rndis_wlan_private, scan_work.work);
 +      struct usbnet *usbdev = priv->usbdev;
 +      int ret;
 +
 +      devdbg(usbdev, "get_scan_results");
  
 -      range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
 -                      IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 -      return 0;
 +      ret = rndis_check_bssid_list(usbdev);
 +
 +      cfg80211_scan_done(priv->scan_request, ret < 0);
 +
 +      priv->scan_request = NULL;
  }
  
  
 -static int rndis_iw_get_name(struct net_device *dev,
 +/*
 + * wireless extension handlers
 + */
 +
 +static int rndis_iw_commit(struct net_device *dev,
      struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  {
 -      struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 -
 -      strcpy(wrqu->name, priv->name);
 +      /* dummy op */
        return 0;
  }
  
@@@ -1497,7 -1314,7 +1497,7 @@@ static int rndis_iw_set_auth(struct net
  {
        struct iw_param *p = &wrqu->param;
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        int ret = -ENOTSUPP;
  
        switch (p->flags & IW_AUTH_INDEX) {
@@@ -1578,7 -1395,7 +1578,7 @@@ static int rndis_iw_get_auth(struct net
  {
        struct iw_param *p = &wrqu->param;
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
  
        switch (p->flags & IW_AUTH_INDEX) {
        case IW_AUTH_WPA_VERSION:
  }
  
  
 -static int rndis_iw_get_mode(struct net_device *dev,
 -                              struct iw_request_info *info,
 -                              union iwreq_data *wrqu, char *extra)
 -{
 -      struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 -
 -      switch (priv->infra_mode) {
 -      case ndis_80211_infra_adhoc:
 -              wrqu->mode = IW_MODE_ADHOC;
 -              break;
 -      case ndis_80211_infra_infra:
 -              wrqu->mode = IW_MODE_INFRA;
 -              break;
 -      /*case ndis_80211_infra_auto_unknown:*/
 -      default:
 -              wrqu->mode = IW_MODE_AUTO;
 -              break;
 -      }
 -      devdbg(usbdev, "SIOCGIWMODE: %08x", wrqu->mode);
 -      return 0;
 -}
 -
 -
 -static int rndis_iw_set_mode(struct net_device *dev,
 -    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 -{
 -      struct usbnet *usbdev = netdev_priv(dev);
 -      int mode;
 -
 -      devdbg(usbdev, "SIOCSIWMODE: %08x", wrqu->mode);
 -
 -      switch (wrqu->mode) {
 -      case IW_MODE_ADHOC:
 -              mode = ndis_80211_infra_adhoc;
 -              break;
 -      case IW_MODE_INFRA:
 -              mode = ndis_80211_infra_infra;
 -              break;
 -      /*case IW_MODE_AUTO:*/
 -      default:
 -              mode = ndis_80211_infra_auto_unknown;
 -              break;
 -      }
 -
 -      return set_infra_mode(usbdev, mode);
 -}
 -
 -
  static int rndis_iw_set_encode(struct net_device *dev,
      struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  {
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        int ret, index, key_len;
        u8 *key;
  
@@@ -1672,8 -1538,10 +1672,8 @@@ static int rndis_iw_set_encode_ext(stru
  {
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 -      struct ndis_80211_key ndis_key;
 -      int keyidx, ret;
 -      u8 *addr;
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 +      int keyidx, flags;
  
        keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
  
            ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
                return remove_key(usbdev, keyidx, NULL);
  
 -      if (ext->key_len > sizeof(ndis_key.material))
 -              return -1;
 -
 -      memset(&ndis_key, 0, sizeof(ndis_key));
 -
 -      ndis_key.size = cpu_to_le32(sizeof(ndis_key) -
 -                              sizeof(ndis_key.material) + ext->key_len);
 -      ndis_key.length = cpu_to_le32(ext->key_len);
 -      ndis_key.index = cpu_to_le32(keyidx);
 -
 -      if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
 -              memcpy(ndis_key.rsc, ext->rx_seq, 6);
 -              ndis_key.index |= cpu_to_le32(1 << 29);
 -      }
 -
 -      addr = ext->addr.sa_data;
 -      if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
 -              /* group key */
 -              if (priv->infra_mode == ndis_80211_infra_adhoc)
 -                      memset(ndis_key.bssid, 0xff, ETH_ALEN);
 -              else
 -                      get_bssid(usbdev, ndis_key.bssid);
 -      } else {
 -              /* pairwise key */
 -              ndis_key.index |= cpu_to_le32(1 << 30);
 -              memcpy(ndis_key.bssid, addr, ETH_ALEN);
 -      }
 -
 -      if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
 -              ndis_key.index |= cpu_to_le32(1 << 31);
 -
 -      if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) {
 -              /* wpa_supplicant gives us the Michael MIC RX/TX keys in
 -               * different order than NDIS spec, so swap the order here. */
 -              memcpy(ndis_key.material, ext->key, 16);
 -              memcpy(ndis_key.material + 16, ext->key + 24, 8);
 -              memcpy(ndis_key.material + 24, ext->key + 16, 8);
 -      } else
 -              memcpy(ndis_key.material, ext->key, ext->key_len);
 -
 -      ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
 -                                      le32_to_cpu(ndis_key.size));
 -      devdbg(usbdev, "SIOCSIWENCODEEXT: OID_802_11_ADD_KEY -> %08X", ret);
 -      if (ret != 0)
 -              return ret;
 -
 -      priv->encr_key_len[keyidx] = ext->key_len;
 -      memcpy(&priv->encr_keys[keyidx], ndis_key.material, ext->key_len);
 +      flags = 0;
 +      if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
 +              flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ;
 +      if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
 +              flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY;
        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
 -              priv->encr_tx_key_index = keyidx;
 -
 -      return 0;
 -}
 -
 -
 -static int rndis_iw_set_scan(struct net_device *dev,
 -    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 -{
 -      struct usbnet *usbdev = netdev_priv(dev);
 -      union iwreq_data evt;
 -      int ret = -EINVAL;
 -      __le32 tmp;
 -
 -      devdbg(usbdev, "SIOCSIWSCAN");
 -
 -      if (wrqu->data.flags == 0) {
 -              tmp = cpu_to_le32(1);
 -              ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
 -                                                              sizeof(tmp));
 -              evt.data.flags = 0;
 -              evt.data.length = 0;
 -              wireless_send_event(dev, SIOCGIWSCAN, &evt, NULL);
 -      }
 -      return ret;
 -}
 -
 -
 -static char *rndis_translate_scan(struct net_device *dev,
 -                                struct iw_request_info *info, char *cev,
 -                                char *end_buf,
 -                                struct ndis_80211_bssid_ex *bssid)
 -{
 -      struct usbnet *usbdev = netdev_priv(dev);
 -      u8 *ie;
 -      char *current_val;
 -      int bssid_len, ie_len, i;
 -      u32 beacon, atim;
 -      struct iw_event iwe;
 -      unsigned char sbuf[32];
 -
 -      bssid_len = le32_to_cpu(bssid->length);
 -
 -      devdbg(usbdev, "BSSID %pM", bssid->mac);
 -      iwe.cmd = SIOCGIWAP;
 -      iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 -      memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
 -      cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN);
 -
 -      devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
 -                                              bssid->ssid.essid);
 -      iwe.cmd = SIOCGIWESSID;
 -      iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
 -      iwe.u.essid.flags = 1;
 -      cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid);
 -
 -      devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
 -      iwe.cmd = SIOCGIWMODE;
 -      switch (le32_to_cpu(bssid->net_infra)) {
 -      case ndis_80211_infra_adhoc:
 -              iwe.u.mode = IW_MODE_ADHOC;
 -              break;
 -      case ndis_80211_infra_infra:
 -              iwe.u.mode = IW_MODE_INFRA;
 -              break;
 -      /*case ndis_80211_infra_auto_unknown:*/
 -      default:
 -              iwe.u.mode = IW_MODE_AUTO;
 -              break;
 -      }
 -      cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN);
 -
 -      devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
 -      iwe.cmd = SIOCGIWFREQ;
 -      dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
 -      cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN);
 -
 -      devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
 -      iwe.cmd = IWEVQUAL;
 -      iwe.u.qual.qual  = level_to_qual(le32_to_cpu(bssid->rssi));
 -      iwe.u.qual.level = le32_to_cpu(bssid->rssi);
 -      iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
 -                      | IW_QUAL_LEVEL_UPDATED
 -                      | IW_QUAL_NOISE_INVALID;
 -      cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN);
 -
 -      devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
 -      iwe.cmd = SIOCGIWENCODE;
 -      iwe.u.data.length = 0;
 -      if (le32_to_cpu(bssid->privacy) == ndis_80211_priv_accept_all)
 -              iwe.u.data.flags = IW_ENCODE_DISABLED;
 -      else
 -              iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
 -
 -      cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
 -
 -      devdbg(usbdev, "RATES:");
 -      current_val = cev + iwe_stream_lcp_len(info);
 -      iwe.cmd = SIOCGIWRATE;
 -      for (i = 0; i < sizeof(bssid->rates); i++) {
 -              if (bssid->rates[i] & 0x7f) {
 -                      iwe.u.bitrate.value =
 -                              ((bssid->rates[i] & 0x7f) *
 -                              500000);
 -                      devdbg(usbdev, " %d", iwe.u.bitrate.value);
 -                      current_val = iwe_stream_add_value(info, cev,
 -                              current_val, end_buf, &iwe,
 -                              IW_EV_PARAM_LEN);
 -              }
 -      }
 -
 -      if ((current_val - cev) > iwe_stream_lcp_len(info))
 -              cev = current_val;
 -
 -      beacon = le32_to_cpu(bssid->config.beacon_period);
 -      devdbg(usbdev, "BCN_INT %d", beacon);
 -      iwe.cmd = IWEVCUSTOM;
 -      snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
 -      iwe.u.data.length = strlen(sbuf);
 -      cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
 -
 -      atim = le32_to_cpu(bssid->config.atim_window);
 -      devdbg(usbdev, "ATIM %d", atim);
 -      iwe.cmd = IWEVCUSTOM;
 -      snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
 -      iwe.u.data.length = strlen(sbuf);
 -      cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
 -
 -      ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
 -      ie_len = min(bssid_len - (int)sizeof(*bssid),
 -                                      (int)le32_to_cpu(bssid->ie_length));
 -      ie_len -= sizeof(struct ndis_80211_fixed_ies);
 -      while (ie_len >= 2 && 2 + ie[1] <= ie_len) {
 -              if ((ie[0] == WLAN_EID_GENERIC && ie[1] >= 4 &&
 -                   memcmp(ie + 2, "\x00\x50\xf2\x01", 4) == 0) ||
 -                  ie[0] == WLAN_EID_RSN) {
 -                      devdbg(usbdev, "IE: WPA%d",
 -                                      (ie[0] == WLAN_EID_RSN) ? 2 : 1);
 -                      iwe.cmd = IWEVGENIE;
 -                      /* arbitrary cut-off at 64 */
 -                      iwe.u.data.length = min(ie[1] + 2, 64);
 -                      cev = iwe_stream_add_point(info, cev, end_buf, &iwe, ie);
 -              }
 -
 -              ie_len -= 2 + ie[1];
 -              ie += 2 + ie[1];
 -      }
 -
 -      return cev;
 -}
 -
 -
 -static int rndis_iw_get_scan(struct net_device *dev,
 -    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 -{
 -      struct usbnet *usbdev = netdev_priv(dev);
 -      void *buf = NULL;
 -      char *cev = extra;
 -      struct ndis_80211_bssid_list_ex *bssid_list;
 -      struct ndis_80211_bssid_ex *bssid;
 -      int ret = -EINVAL, len, count, bssid_len;
 -
 -      devdbg(usbdev, "SIOCGIWSCAN");
 +              flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY;
  
 -      len = CONTROL_BUFFER_SIZE;
 -      buf = kmalloc(len, GFP_KERNEL);
 -      if (!buf) {
 -              ret = -ENOMEM;
 -              goto out;
 -      }
 -
 -      ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
 -
 -      if (ret != 0)
 -              goto out;
 -
 -      bssid_list = buf;
 -      bssid = bssid_list->bssid;
 -      bssid_len = le32_to_cpu(bssid->length);
 -      count = le32_to_cpu(bssid_list->num_items);
 -      devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
 -
 -      while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
 -              cev = rndis_translate_scan(dev, info, cev,
 -                                         extra + IW_SCAN_MAX_DATA, bssid);
 -              bssid = (void *)bssid + bssid_len;
 -              bssid_len = le32_to_cpu(bssid->length);
 -              count--;
 -      }
 -
 -out:
 -      wrqu->data.length = cev - extra;
 -      wrqu->data.flags = 0;
 -      kfree(buf);
 -      return ret;
 +      return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr,
 +                              ext->rx_seq, ext->alg, flags);
  }
  
  
@@@ -1713,7 -1815,7 +1713,7 @@@ static int rndis_iw_set_genie(struct ne
      struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  {
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        int ret = 0;
  
  #ifdef DEBUG
@@@ -1747,7 -1849,7 +1747,7 @@@ static int rndis_iw_get_genie(struct ne
      struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  {
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
  
        devdbg(usbdev, "SIOCGIWGENIE");
  
@@@ -1834,6 -1936,39 +1834,6 @@@ static int rndis_iw_get_frag(struct net
  }
  
  
 -static int rndis_iw_set_nick(struct net_device *dev,
 -    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 -{
 -      struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 -
 -      devdbg(usbdev, "SIOCSIWNICK");
 -
 -      priv->nick_len = wrqu->data.length;
 -      if (priv->nick_len > 32)
 -              priv->nick_len = 32;
 -
 -      memcpy(priv->nick, extra, priv->nick_len);
 -      return 0;
 -}
 -
 -
 -static int rndis_iw_get_nick(struct net_device *dev,
 -    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 -{
 -      struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 -
 -      wrqu->data.flags = 1;
 -      wrqu->data.length = priv->nick_len;
 -      memcpy(extra, priv->nick, priv->nick_len);
 -
 -      devdbg(usbdev, "SIOCGIWNICK: '%s'", priv->nick);
 -
 -      return 0;
 -}
 -
 -
  static int rndis_iw_set_freq(struct net_device *dev,
      struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  {
@@@ -1886,12 -2021,20 +1886,12 @@@ static int rndis_iw_get_txpower(struct 
      struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  {
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tx_power;
 -      int ret = 0, len;
  
        if (priv->radio_on) {
 -              if (priv->caps & CAP_SUPPORT_TXPOWER) {
 -                      len = sizeof(tx_power);
 -                      ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
 -                                                      &tx_power, &len);
 -                      if (ret != 0)
 -                              return ret;
 -              } else
 -                      /* fake incase not supported */
 -                      tx_power = cpu_to_le32(get_bcm4320_power(priv));
 +              /* fake since changing tx_power (by userlevel) not supported */
 +              tx_power = cpu_to_le32(get_bcm4320_power(priv));
  
                wrqu->txpower.flags = IW_TXPOW_MWATT;
                wrqu->txpower.value = le32_to_cpu(tx_power);
  
        devdbg(usbdev, "SIOCGIWTXPOW: %d", wrqu->txpower.value);
  
 -      return ret;
 +      return 0;
  }
  
  
@@@ -1912,8 -2055,9 +1912,8 @@@ static int rndis_iw_set_txpower(struct 
      struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  {
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tx_power = 0;
 -      int ret = 0;
  
        if (!wrqu->txpower.disabled) {
                if (wrqu->txpower.flags == IW_TXPOW_MWATT)
        devdbg(usbdev, "SIOCSIWTXPOW: %d", le32_to_cpu(tx_power));
  
        if (le32_to_cpu(tx_power) != 0) {
 -              if (priv->caps & CAP_SUPPORT_TXPOWER) {
 -                      /* turn radio on first */
 -                      if (!priv->radio_on)
 -                              disassociate(usbdev, 1);
 -
 -                      ret = rndis_set_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
 -                                              &tx_power, sizeof(tx_power));
 -                      if (ret != 0)
 -                              ret = -EOPNOTSUPP;
 -                      return ret;
 -              } else {
 -                      /* txpower unsupported, just turn radio on */
 -                      if (!priv->radio_on)
 -                              return disassociate(usbdev, 1);
 -                      return 0; /* all ready on */
 -              }
 +              /* txpower unsupported, just turn radio on */
 +              if (!priv->radio_on)
 +                      return disassociate(usbdev, 1);
 +              return 0; /* all ready on */
        }
  
        /* tx_power == 0, turn off radio */
@@@ -1969,7 -2125,7 +1969,7 @@@ static int rndis_iw_set_mlme(struct net
      struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
  {
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct iw_mlme *mlme = (struct iw_mlme *)extra;
        unsigned char bssid[ETH_ALEN];
  
  static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
  {
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        unsigned long flags;
  
        spin_lock_irqsave(&priv->stats_lock, flags);
  static const iw_handler rndis_iw_handler[] =
  {
        IW_IOCTL(SIOCSIWCOMMIT)    = rndis_iw_commit,
 -      IW_IOCTL(SIOCGIWNAME)      = rndis_iw_get_name,
 +      IW_IOCTL(SIOCGIWNAME)      = (iw_handler) cfg80211_wext_giwname,
        IW_IOCTL(SIOCSIWFREQ)      = rndis_iw_set_freq,
        IW_IOCTL(SIOCGIWFREQ)      = rndis_iw_get_freq,
 -      IW_IOCTL(SIOCSIWMODE)      = rndis_iw_set_mode,
 -      IW_IOCTL(SIOCGIWMODE)      = rndis_iw_get_mode,
 -      IW_IOCTL(SIOCGIWRANGE)     = rndis_iw_get_range,
 +      IW_IOCTL(SIOCSIWMODE)      = (iw_handler) cfg80211_wext_siwmode,
 +      IW_IOCTL(SIOCGIWMODE)      = (iw_handler) cfg80211_wext_giwmode,
 +      IW_IOCTL(SIOCGIWRANGE)     = (iw_handler) cfg80211_wext_giwrange,
        IW_IOCTL(SIOCSIWAP)        = rndis_iw_set_bssid,
        IW_IOCTL(SIOCGIWAP)        = rndis_iw_get_bssid,
 -      IW_IOCTL(SIOCSIWSCAN)      = rndis_iw_set_scan,
 -      IW_IOCTL(SIOCGIWSCAN)      = rndis_iw_get_scan,
 +      IW_IOCTL(SIOCSIWSCAN)      = (iw_handler) cfg80211_wext_siwscan,
 +      IW_IOCTL(SIOCGIWSCAN)      = (iw_handler) cfg80211_wext_giwscan,
        IW_IOCTL(SIOCSIWESSID)     = rndis_iw_set_essid,
        IW_IOCTL(SIOCGIWESSID)     = rndis_iw_get_essid,
 -      IW_IOCTL(SIOCSIWNICKN)     = rndis_iw_set_nick,
 -      IW_IOCTL(SIOCGIWNICKN)     = rndis_iw_get_nick,
        IW_IOCTL(SIOCGIWRATE)      = rndis_iw_get_rate,
        IW_IOCTL(SIOCSIWRTS)       = rndis_iw_set_rts,
        IW_IOCTL(SIOCGIWRTS)       = rndis_iw_get_rts,
        IW_IOCTL(SIOCSIWMLME)      = rndis_iw_set_mlme,
  };
  
 -static const iw_handler rndis_wext_private_handler[] = {
 +static const iw_handler rndis_wlan_private_handler[] = {
  };
  
 -static const struct iw_priv_args rndis_wext_private_args[] = {
 +static const struct iw_priv_args rndis_wlan_private_args[] = {
  };
  
  
  static const struct iw_handler_def rndis_iw_handlers = {
        .num_standard = ARRAY_SIZE(rndis_iw_handler),
 -      .num_private  = ARRAY_SIZE(rndis_wext_private_handler),
 -      .num_private_args = ARRAY_SIZE(rndis_wext_private_args),
 +      .num_private  = ARRAY_SIZE(rndis_wlan_private_handler),
 +      .num_private_args = ARRAY_SIZE(rndis_wlan_private_args),
        .standard = (iw_handler *)rndis_iw_handler,
 -      .private  = (iw_handler *)rndis_wext_private_handler,
 -      .private_args = (struct iw_priv_args *)rndis_wext_private_args,
 +      .private  = (iw_handler *)rndis_wlan_private_handler,
 +      .private_args = (struct iw_priv_args *)rndis_wlan_private_args,
        .get_wireless_stats = rndis_get_wireless_stats,
  };
  
  
 -static void rndis_wext_worker(struct work_struct *work)
 +static void rndis_wlan_worker(struct work_struct *work)
  {
 -      struct rndis_wext_private *priv =
 -              container_of(work, struct rndis_wext_private, work);
 +      struct rndis_wlan_private *priv =
 +              container_of(work, struct rndis_wlan_private, work);
        struct usbnet *usbdev = priv->usbdev;
        union iwreq_data evt;
        unsigned char bssid[ETH_ALEN];
@@@ -2119,10 -2277,10 +2119,10 @@@ get_bssid
                set_multicast_list(usbdev);
  }
  
 -static void rndis_wext_set_multicast_list(struct net_device *dev)
 +static void rndis_wlan_set_multicast_list(struct net_device *dev)
  {
        struct usbnet *usbdev = netdev_priv(dev);
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
  
        if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
                return;
        queue_work(priv->workqueue, &priv->work);
  }
  
 -static void rndis_wext_link_change(struct usbnet *usbdev, int state)
 +static void rndis_wlan_link_change(struct usbnet *usbdev, int state)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
  
        /* queue work to avoid recursive calls into rndis_command */
        set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending);
  }
  
  
 -static int rndis_wext_get_caps(struct usbnet *usbdev)
 +static int rndis_wlan_get_caps(struct usbnet *usbdev)
  {
        struct {
                __le32  num_items;
                __le32  items[8];
        } networks_supported;
        int len, retval, i, n;
 -      __le32 tx_power;
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 -
 -      /* determine if supports setting txpower */
 -      len = sizeof(tx_power);
 -      retval = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, &tx_power,
 -                                                                      &len);
 -      if (retval == 0 && le32_to_cpu(tx_power) != 0xFF)
 -              priv->caps |= CAP_SUPPORT_TXPOWER;
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
  
        /* determine supported modes */
        len = sizeof(networks_supported);
                        n = 8;
                for (i = 0; i < n; i++) {
                        switch (le32_to_cpu(networks_supported.items[i])) {
 -                      case ndis_80211_type_freq_hop:
 -                      case ndis_80211_type_direct_seq:
 +                      case NDIS_80211_TYPE_FREQ_HOP:
 +                      case NDIS_80211_TYPE_DIRECT_SEQ:
                                priv->caps |= CAP_MODE_80211B;
                                break;
 -                      case ndis_80211_type_ofdm_a:
 +                      case NDIS_80211_TYPE_OFDM_A:
                                priv->caps |= CAP_MODE_80211A;
                                break;
 -                      case ndis_80211_type_ofdm_g:
 +                      case NDIS_80211_TYPE_OFDM_G:
                                priv->caps |= CAP_MODE_80211G;
                                break;
                        }
                }
 -              if (priv->caps & CAP_MODE_80211A)
 -                      strcat(priv->name, "a");
 -              if (priv->caps & CAP_MODE_80211B)
 -                      strcat(priv->name, "b");
 -              if (priv->caps & CAP_MODE_80211G)
 -                      strcat(priv->name, "g");
        }
  
        return retval;
  #define STATS_UPDATE_JIFFIES (HZ)
  static void rndis_update_wireless_stats(struct work_struct *work)
  {
 -      struct rndis_wext_private *priv =
 -              container_of(work, struct rndis_wext_private, stats_work.work);
 +      struct rndis_wlan_private *priv =
 +              container_of(work, struct rndis_wlan_private, stats_work.work);
        struct usbnet *usbdev = priv->usbdev;
        struct iw_statistics iwstats;
        __le32 rssi, tmp;
        if (ret == 0) {
                memset(&iwstats.qual, 0, sizeof(iwstats.qual));
                iwstats.qual.qual  = level_to_qual(le32_to_cpu(rssi));
 -              iwstats.qual.level = le32_to_cpu(rssi);
 +              iwstats.qual.level = level_to_qual(le32_to_cpu(rssi));
                iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
                                | IW_QUAL_LEVEL_UPDATED
                                | IW_QUAL_NOISE_INVALID;
  }
  
  
 -static int bcm4320_early_init(struct usbnet *usbdev)
 +static int bcm4320a_early_init(struct usbnet *usbdev)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      /* bcm4320a doesn't handle configuration parameters well. Try
 +       * set any and you get partially zeroed mac and broken device.
 +       */
 +
 +      return 0;
 +}
 +
 +
 +static int bcm4320b_early_init(struct usbnet *usbdev)
 +{
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        char buf[8];
  
        /* Early initialization settings, setting these won't have effect
  }
  
  /* same as rndis_netdev_ops but with local multicast handler */
 -static const struct net_device_ops rndis_wext_netdev_ops = {
 +static const struct net_device_ops rndis_wlan_netdev_ops = {
        .ndo_open               = usbnet_open,
        .ndo_stop               = usbnet_stop,
        .ndo_start_xmit         = usbnet_start_xmit,
        .ndo_tx_timeout         = usbnet_tx_timeout,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
 -      .ndo_set_multicast_list = rndis_wext_set_multicast_list,
 +      .ndo_set_multicast_list = rndis_wlan_set_multicast_list,
  };
  
  
 -static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
 +static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
  {
 -      struct rndis_wext_private *priv;
 +      struct wiphy *wiphy;
 +      struct rndis_wlan_private *priv;
        int retval, len;
        __le32 tmp;
  
 -      /* allocate rndis private data */
 -      priv = kzalloc(sizeof(struct rndis_wext_private), GFP_KERNEL);
 -      if (!priv)
 +      /* allocate wiphy and rndis private data
 +       * NOTE: We only support a single virtual interface, so wiphy
 +       * and wireless_dev are somewhat synonymous for this device.
 +       */
 +      wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wlan_private));
 +      if (!wiphy)
                return -ENOMEM;
  
 +      priv = wiphy_priv(wiphy);
 +      usbdev->net->ieee80211_ptr = &priv->wdev;
 +      priv->wdev.wiphy = wiphy;
 +      priv->wdev.iftype = NL80211_IFTYPE_STATION;
 +
        /* These have to be initialized before calling generic_rndis_bind().
 -       * Otherwise we'll be in big trouble in rndis_wext_early_init().
 +       * Otherwise we'll be in big trouble in rndis_wlan_early_init().
         */
        usbdev->driver_priv = priv;
 -      strcpy(priv->name, "IEEE802.11");
        usbdev->net->wireless_handlers = &rndis_iw_handlers;
        priv->usbdev = usbdev;
  
  
        /* because rndis_command() sleeps we need to use workqueue */
        priv->workqueue = create_singlethread_workqueue("rndis_wlan");
 -      INIT_WORK(&priv->work, rndis_wext_worker);
 +      INIT_WORK(&priv->work, rndis_wlan_worker);
        INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
 +      INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results);
  
        /* try bind rndis_host */
        retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS);
         * picks up rssi to closest station instead of to access point).
         *
         * rndis_host wants to avoid all OID as much as possible
 -       * so do promisc/multicast handling in rndis_wext.
 +       * so do promisc/multicast handling in rndis_wlan.
         */
 -      usbdev->net->netdev_ops = &rndis_wext_netdev_ops;
 +      usbdev->net->netdev_ops = &rndis_wlan_netdev_ops;
  
        tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
        retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
                                        | IW_QUAL_QUAL_INVALID
                                        | IW_QUAL_LEVEL_INVALID;
  
 -      rndis_wext_get_caps(usbdev);
 +      /* fill-out wiphy structure and register w/ cfg80211 */
 +      memcpy(wiphy->perm_addr, usbdev->net->dev_addr, ETH_ALEN);
 +      wiphy->privid = rndis_wiphy_privid;
 +      wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
 +                                      | BIT(NL80211_IFTYPE_ADHOC);
 +      wiphy->max_scan_ssids = 1;
 +
 +      /* TODO: fill-out band information based on priv->caps */
 +      rndis_wlan_get_caps(usbdev);
 +
 +      memcpy(priv->channels, rndis_channels, sizeof(rndis_channels));
 +      memcpy(priv->rates, rndis_rates, sizeof(rndis_rates));
 +      priv->band.channels = priv->channels;
 +      priv->band.n_channels = ARRAY_SIZE(rndis_channels);
 +      priv->band.bitrates = priv->rates;
 +      priv->band.n_bitrates = ARRAY_SIZE(rndis_rates);
 +      wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
 +      wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
 +
 +      set_wiphy_dev(wiphy, &usbdev->udev->dev);
 +
 +      if (wiphy_register(wiphy)) {
 +              retval = -ENODEV;
 +              goto fail;
 +      }
 +
        set_default_iw_params(usbdev);
  
        /* turn radio on */
  
  fail:
        cancel_delayed_work_sync(&priv->stats_work);
 +      cancel_delayed_work_sync(&priv->scan_work);
        cancel_work_sync(&priv->work);
        flush_workqueue(priv->workqueue);
        destroy_workqueue(priv->workqueue);
  
 -      kfree(priv);
 +      wiphy_free(wiphy);
        return retval;
  }
  
  
 -static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf)
 +static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
  {
 -      struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 +      struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
  
        /* turn radio off */
        disassociate(usbdev, 0);
  
        cancel_delayed_work_sync(&priv->stats_work);
 +      cancel_delayed_work_sync(&priv->scan_work);
        cancel_work_sync(&priv->work);
        flush_workqueue(priv->workqueue);
        destroy_workqueue(priv->workqueue);
  
        if (priv && priv->wpa_ie_len)
                kfree(priv->wpa_ie);
 -      kfree(priv);
  
        rndis_unbind(usbdev, intf);
 +
 +      wiphy_unregister(priv->wdev.wiphy);
 +      wiphy_free(priv->wdev.wiphy);
  }
  
  
 -static int rndis_wext_reset(struct usbnet *usbdev)
 +static int rndis_wlan_reset(struct usbnet *usbdev)
  {
        return deauthenticate(usbdev);
  }
  static const struct driver_info       bcm4320b_info = {
        .description =  "Wireless RNDIS device, BCM4320b based",
        .flags =        FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
 -      .bind =         rndis_wext_bind,
 -      .unbind =       rndis_wext_unbind,
 +      .bind =         rndis_wlan_bind,
 +      .unbind =       rndis_wlan_unbind,
        .status =       rndis_status,
        .rx_fixup =     rndis_rx_fixup,
        .tx_fixup =     rndis_tx_fixup,
 -      .reset =        rndis_wext_reset,
 -      .early_init =   bcm4320_early_init,
 -      .link_change =  rndis_wext_link_change,
 +      .reset =        rndis_wlan_reset,
 +      .early_init =   bcm4320b_early_init,
 +      .link_change =  rndis_wlan_link_change,
  };
  
  static const struct driver_info       bcm4320a_info = {
        .description =  "Wireless RNDIS device, BCM4320a based",
        .flags =        FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
 -      .bind =         rndis_wext_bind,
 -      .unbind =       rndis_wext_unbind,
 +      .bind =         rndis_wlan_bind,
 +      .unbind =       rndis_wlan_unbind,
        .status =       rndis_status,
        .rx_fixup =     rndis_rx_fixup,
        .tx_fixup =     rndis_tx_fixup,
 -      .reset =        rndis_wext_reset,
 -      .early_init =   bcm4320_early_init,
 -      .link_change =  rndis_wext_link_change,
 +      .reset =        rndis_wlan_reset,
 +      .early_init =   bcm4320a_early_init,
 +      .link_change =  rndis_wlan_link_change,
  };
  
 -static const struct driver_info rndis_wext_info = {
 +static const struct driver_info rndis_wlan_info = {
        .description =  "Wireless RNDIS device",
        .flags =        FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
 -      .bind =         rndis_wext_bind,
 -      .unbind =       rndis_wext_unbind,
 +      .bind =         rndis_wlan_bind,
 +      .unbind =       rndis_wlan_unbind,
        .status =       rndis_status,
        .rx_fixup =     rndis_rx_fixup,
        .tx_fixup =     rndis_tx_fixup,
 -      .reset =        rndis_wext_reset,
 -      .early_init =   bcm4320_early_init,
 -      .link_change =  rndis_wext_link_change,
 +      .reset =        rndis_wlan_reset,
 +      .early_init =   bcm4320a_early_init,
 +      .link_change =  rndis_wlan_link_change,
  };
  
  /*-------------------------------------------------------------------------*/
@@@ -2672,11 -2796,11 +2672,11 @@@ static const struct usb_device_id produ
  {
        /* RNDIS is MSFT's un-official variant of CDC ACM */
        USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
 -      .driver_info = (unsigned long) &rndis_wext_info,
 +      .driver_info = (unsigned long) &rndis_wlan_info,
  }, {
        /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
        USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
 -      .driver_info = (unsigned long) &rndis_wext_info,
 +      .driver_info = (unsigned long) &rndis_wlan_info,
  },
        { },            // END
  };
index 18ee7d6c4028af9fb1f04f3783159f0cfb3ef623,1ae11c7f17affe210ed50782611c15f6db99796d..8aab3e6754bdae25d331ca1b0f627d96d6622820
@@@ -9,11 -9,11 +9,11 @@@ menuconfig RT2X0
  
          When building one of the individual drivers, the rt2x00 library
          will also be created. That library (when the driver is built as
-         a module) will be called "rt2x00lib.ko".
+         a module) will be called rt2x00lib.
  
          Additionally PCI and USB libraries will also be build depending
          on the types of drivers being selected, these libraries will be
-         called "rt2x00pci.ko" and "rt2x00usb.ko".
+         called rt2x00pci and rt2x00usb.
  
  if RT2X00
  
@@@ -26,7 -26,7 +26,7 @@@ config RT2400PC
          This adds support for rt2400 wireless chipset family.
          Supported chips: RT2460.
  
-         When compiled as a module, this driver will be called "rt2400pci.ko".
+         When compiled as a module, this driver will be called rt2400pci.
  
  config RT2500PCI
        tristate "Ralink rt2500 (PCI/PCMCIA) support"
@@@ -37,7 -37,7 +37,7 @@@
          This adds support for rt2500 wireless chipset family.
          Supported chips: RT2560.
  
-         When compiled as a module, this driver will be called "rt2500pci.ko".
+         When compiled as a module, this driver will be called rt2500pci.
  
  config RT61PCI
        tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support"
@@@ -51,7 -51,7 +51,7 @@@
          This adds support for rt2501 wireless chipset family.
          Supported chips: RT2561, RT2561S & RT2661.
  
-         When compiled as a module, this driver will be called "rt61pci.ko".
+         When compiled as a module, this driver will be called rt61pci.
  
  config RT2500USB
        tristate "Ralink rt2500 (USB) support"
@@@ -62,7 -62,7 +62,7 @@@
          This adds support for rt2500 wireless chipset family.
          Supported chips: RT2571 & RT2572.
  
-         When compiled as a module, this driver will be called "rt2500usb.ko".
+         When compiled as a module, this driver will be called rt2500usb.
  
  config RT73USB
        tristate "Ralink rt2501/rt73 (USB) support"
          This adds support for rt2501 wireless chipset family.
          Supported chips: RT2571W, RT2573 & RT2671.
  
-         When compiled as a module, this driver will be called "rt73usb.ko".
+         When compiled as a module, this driver will be called rt73usb.
  
 +config RT2800USB
 +      tristate "Ralink rt2800 (USB) support"
 +      depends on USB
 +      select RT2X00_LIB_USB
 +      select RT2X00_LIB_HT
 +      select RT2X00_LIB_FIRMWARE
 +      select RT2X00_LIB_CRYPTO
 +      select CRC_CCITT
 +      ---help---
 +        This adds support for rt2800 wireless chipset family.
 +        Supported chips: RT2770, RT2870 & RT3070.
 +
 +        When compiled as a module, this driver will be called "rt2800usb.ko".
 +
  config RT2X00_LIB_PCI
        tristate
        select RT2X00_LIB
@@@ -102,9 -88,6 +102,9 @@@ config RT2X00_LIB_US
  config RT2X00_LIB
        tristate
  
 +config RT2X00_LIB_HT
 +      boolean
 +
  config RT2X00_LIB_FIRMWARE
        boolean
        select FW_LOADER
index 39e00b3d781128b2feb837668c03914d3a86d215,d83e3794d340fd3d6a78abdf24c67128b596e51b..0bf2715fa93a7bc59bf437ffad5237ccb686bdfc
@@@ -32,8 -32,8 +32,8 @@@
   * Interval defines
   * Both the link tuner as the rfkill will be called once per second.
   */
 -#define LINK_TUNE_INTERVAL    ( round_jiffies_relative(HZ) )
 -#define RFKILL_POLL_INTERVAL  ( 1000 )
 +#define LINK_TUNE_INTERVAL    round_jiffies_relative(HZ)
 +#define RFKILL_POLL_INTERVAL  1000
  
  /*
   * rt2x00_rate: Per rate device information
@@@ -48,7 -48,6 +48,7 @@@ struct rt2x00_rate 
        unsigned short ratemask;
  
        unsigned short plcp;
 +      unsigned short mcs;
  };
  
  extern const struct rt2x00_rate rt2x00_supported_rates[12];
@@@ -58,14 -57,6 +58,14 @@@ static inline const struct rt2x00_rate 
        return &rt2x00_supported_rates[hw_value & 0xff];
  }
  
 +#define RATE_MCS(__mode, __mcs) \
 +      ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) )
 +
 +static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
 +{
 +      return (mcs_value & 0x00ff);
 +}
 +
  /*
   * Radio control handlers.
   */
@@@ -121,23 -112,6 +121,23 @@@ void rt2x00queue_unmap_skb(struct rt2x0
   */
  void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
  
 +/**
 + * rt2x00queue_payload_align - Align 802.11 payload to 4-byte boundary
 + * @skb: The skb to align
 + * @l2pad: Should L2 padding be used
 + * @header_length: Length of 802.11 header
 + *
 + * This function prepares the @skb to be send to the device or mac80211.
 + * If @l2pad is set to true padding will occur between the 802.11 header
 + * and payload. Otherwise the padding will be done in front of the 802.11
 + * header.
 + * When @l2pad is set the function will check for the &SKBDESC_L2_PADDED
 + * flag in &skb_frame_desc. If that flag is set, the padding is removed
 + * and the flag cleared. Otherwise the padding is added and the flag is set.
 + */
 +void rt2x00queue_payload_align(struct sk_buff *skb,
 +                             bool l2pad, unsigned int header_length);
 +
  /**
   * rt2x00queue_write_tx_frame - Write TX frame to hardware
   * @queue: Queue over which the frame should be send
@@@ -261,7 -235,7 +261,7 @@@ void rt2x00link_reset_tuner(struct rt2x
   * @rt2x00dev: Pointer to &struct rt2x00_dev.
   *
   * Initialize work structure and all link tuning related
-  * paramters. This will not start the link tuning process itself.
+  * parameters. This will not start the link tuning process itself.
   */
  void rt2x00link_register(struct rt2x00_dev *rt2x00dev);
  
@@@ -321,12 -295,10 +321,12 @@@ void rt2x00crypto_create_tx_descriptor(
                                       struct txentry_desc *txdesc);
  unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
                                      struct sk_buff *skb);
 -void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len);
 -void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len);
 -void rt2x00crypto_tx_insert_iv(struct sk_buff *skb);
 -void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
 +void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
 +                           struct txentry_desc *txdesc);
 +void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
 +                             struct txentry_desc *txdesc);
 +void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length);
 +void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
                               unsigned int header_length,
                               struct rxdone_entry_desc *rxdesc);
  #else
@@@ -347,42 -319,27 +347,42 @@@ static inline unsigned int rt2x00crypto
  }
  
  static inline void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
 -                                         unsigned int iv_len)
 +                                         struct txentry_desc *txdesc)
  {
  }
  
  static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
 -                                           unsigned int iv_len)
 +                                           struct txentry_desc *txdesc)
  {
  }
  
 -static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
 +static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb,
 +                                           unsigned int header_length)
  {
  }
  
 -static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
 -                                           unsigned int align,
 +static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
                                             unsigned int header_length,
                                             struct rxdone_entry_desc *rxdesc)
  {
  }
  #endif /* CONFIG_RT2X00_LIB_CRYPTO */
  
 +/*
 + * HT handlers.
 + */
 +#ifdef CONFIG_RT2X00_LIB_HT
 +void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
 +                                 struct txentry_desc *txdesc,
 +                                 const struct rt2x00_rate *hwrate);
 +#else
 +static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
 +                                               struct txentry_desc *txdesc,
 +                                               const struct rt2x00_rate *hwrate)
 +{
 +}
 +#endif /* CONFIG_RT2X00_LIB_HT */
 +
  /*
   * RFkill handlers.
   */
index 1a90d69f18a9bc0859544ca19cd4d8ef5bf3a610,fa2821be44c2d43e83bfbfb375ed1453788c2e8f..6af706408ac08bf252a4a97105af0379734db621
@@@ -138,7 -138,7 +138,7 @@@ psa_read(struct net_device *       dev
  
  /*------------------------------------------------------------------*/
  /*
-  * Write the Paramter Storage Area to the WaveLAN card's memory
+  * Write the Parameter Storage Area to the WaveLAN card's memory
   */
  static void
  psa_write(struct net_device * dev,
@@@ -3107,6 -3107,11 +3107,6 @@@ wavelan_packet_xmit(struct sk_buff *   sk
         * so the Tx buffer is now free */
      }
  
 -#ifdef DEBUG_TX_ERROR
 -      if (skb->next)
 -              printk(KERN_INFO "skb has next\n");
 -#endif
 -
        /* Check if we need some padding */
        /* Note : on wireless the propagation time is in the order of 1us,
         * and we don't have the Ethernet specific requirement of beeing
diff --combined drivers/of/Kconfig
index 6fe043bd3770414cb087c97c4e33af44fa86f400,27f3b81333dec00bf0c5c212b2f0162261a40564..d2fa27c5c1b28e444748214e363bb3c462a43f0e
@@@ -1,27 -1,21 +1,27 @@@
  config OF_DEVICE
        def_bool y
-       depends on OF && (SPARC || PPC_OF)
+       depends on OF && (SPARC || PPC_OF || MICROBLAZE)
  
  config OF_GPIO
        def_bool y
-       depends on OF && PPC_OF && GPIOLIB
+       depends on OF && (PPC_OF || MICROBLAZE) && GPIOLIB
        help
          OpenFirmware GPIO accessors
  
  config OF_I2C
        def_tristate I2C
-       depends on PPC_OF && I2C
+       depends on (PPC_OF || MICROBLAZE) && I2C
        help
          OpenFirmware I2C accessors
  
  config OF_SPI
        def_tristate SPI
-       depends on OF && PPC_OF && SPI
+       depends on OF && (PPC_OF || MICROBLAZE) && SPI
        help
          OpenFirmware SPI accessors
 +
 +config OF_MDIO
 +      def_tristate PHYLIB
 +      depends on OF && PHYLIB
 +      help
 +        OpenFirmware MDIO bus (Ethernet PHY) accessors
diff --combined drivers/scsi/fcoe/fcoe.c
index f791348871fc36d25eb750951fa3ec438e578ccc,e606b4829d4430684a973c743d721bf81ba66d1f..c15878e881570e6ae6344b92869b1457840e7f69
@@@ -54,7 -54,6 +54,6 @@@ MODULE_LICENSE("GPL v2")
  /* fcoe host list */
  LIST_HEAD(fcoe_hostlist);
  DEFINE_RWLOCK(fcoe_hostlist_lock);
- DEFINE_TIMER(fcoe_timer, NULL, 0, 0);
  DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
  
  /* Function Prototypes */
@@@ -71,7 -70,7 +70,7 @@@ static struct fc_lport *fcoe_hostlist_l
  static int fcoe_hostlist_add(const struct fc_lport *);
  static int fcoe_hostlist_remove(const struct fc_lport *);
  
- static int fcoe_check_wait_queue(struct fc_lport *);
+ static void fcoe_check_wait_queue(struct fc_lport *, struct sk_buff *);
  static int fcoe_device_notification(struct notifier_block *, ulong, void *);
  static void fcoe_dev_setup(void);
  static void fcoe_dev_cleanup(void);
@@@ -135,58 -134,6 +134,58 @@@ static struct scsi_host_template fcoe_s
        .max_sectors = 0xffff,
  };
  
 +/**
 + * fcoe_fip_recv - handle a received FIP frame.
 + * @skb: the receive skb
 + * @dev: associated &net_device
 + * @ptype: the &packet_type structure which was used to register this handler.
 + * @orig_dev: original receive &net_device, in case @dev is a bond.
 + *
 + * Returns: 0 for success
 + */
 +static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
 +                       struct packet_type *ptype,
 +                       struct net_device *orig_dev)
 +{
 +      struct fcoe_softc *fc;
 +
 +      fc = container_of(ptype, struct fcoe_softc, fip_packet_type);
 +      fcoe_ctlr_recv(&fc->ctlr, skb);
 +      return 0;
 +}
 +
 +/**
 + * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame.
 + * @fip: FCoE controller.
 + * @skb: FIP Packet.
 + */
 +static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
 +{
 +      skb->dev = fcoe_from_ctlr(fip)->real_dev;
 +      dev_queue_xmit(skb);
 +}
 +
 +/**
 + * fcoe_update_src_mac() - Update Ethernet MAC filters.
 + * @fip: FCoE controller.
 + * @old: Unicast MAC address to delete if the MAC is non-zero.
 + * @new: Unicast MAC address to add.
 + *
 + * Remove any previously-set unicast MAC filter.
 + * Add secondary FCoE MAC address filter for our OUI.
 + */
 +static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
 +{
 +      struct fcoe_softc *fc;
 +
 +      fc = fcoe_from_ctlr(fip);
 +      rtnl_lock();
 +      if (!is_zero_ether_addr(old))
 +              dev_unicast_delete(fc->real_dev, old);
 +      dev_unicast_add(fc->real_dev, new);
 +      rtnl_unlock();
 +}
 +
  /**
   * fcoe_lport_config() - sets up the fc_lport
   * @lp: ptr to the fc_lport
@@@ -198,6 -145,7 +197,7 @@@ static int fcoe_lport_config(struct fc_
        lp->link_up = 0;
        lp->qfull = 0;
        lp->max_retry_count = 3;
+       lp->max_rport_retry_count = 3;
        lp->e_d_tov = 2 * 1000; /* FC-FS default */
        lp->r_a_tov = 2 * 2 * 1000;
        lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
        return 0;
  }
  
 +/**
 + * fcoe_netdev_cleanup() - clean up netdev configurations
 + * @fc: ptr to the fcoe_softc
 + */
 +void fcoe_netdev_cleanup(struct fcoe_softc *fc)
 +{
 +      u8 flogi_maddr[ETH_ALEN];
 +
 +      /* Don't listen for Ethernet packets anymore */
 +      dev_remove_pack(&fc->fcoe_packet_type);
 +      dev_remove_pack(&fc->fip_packet_type);
 +
 +      /* Delete secondary MAC addresses */
 +      rtnl_lock();
 +      memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
 +      dev_unicast_delete(fc->real_dev, flogi_maddr);
 +      if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
 +              dev_unicast_delete(fc->real_dev, fc->ctlr.data_src_addr);
 +      if (fc->ctlr.spma)
 +              dev_unicast_delete(fc->real_dev, fc->ctlr.ctl_src_addr);
 +      dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
 +      rtnl_unlock();
 +}
 +
+ /**
+  * fcoe_queue_timer() - fcoe queue timer
+  * @lp: the fc_lport pointer
+  *
+  * Calls fcoe_check_wait_queue on timeout
+  *
+  */
+ static void fcoe_queue_timer(ulong lp)
+ {
+       fcoe_check_wait_queue((struct fc_lport *)lp, NULL);
+ }
  /**
   * fcoe_netdev_config() - Set up netdev for SW FCoE
   * @lp : ptr to the fc_lport
@@@ -257,7 -193,6 +269,7 @@@ static int fcoe_netdev_config(struct fc
        u64 wwnn, wwpn;
        struct fcoe_softc *fc;
        u8 flogi_maddr[ETH_ALEN];
 +      struct netdev_hw_addr *ha;
  
        /* Setup lport private data to point to fcoe softc */
        fc = lport_priv(lp);
        }
        skb_queue_head_init(&fc->fcoe_pending_queue);
        fc->fcoe_pending_queue_active = 0;
+       setup_timer(&fc->timer, fcoe_queue_timer, (unsigned long)lp);
  
 +      /* look for SAN MAC address, if multiple SAN MACs exist, only
 +       * use the first one for SPMA */
 +      rcu_read_lock();
 +      for_each_dev_addr(netdev, ha) {
 +              if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
 +                  (is_valid_ether_addr(fc->ctlr.ctl_src_addr))) {
 +                      memcpy(fc->ctlr.ctl_src_addr, ha->addr, ETH_ALEN);
 +                      fc->ctlr.spma = 1;
 +                      break;
 +              }
 +      }
 +      rcu_read_unlock();
 +
        /* setup Source Mac Address */
 -      memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
 -             fc->real_dev->addr_len);
 +      if (!fc->ctlr.spma)
 +              memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
 +                     fc->real_dev->addr_len);
  
        wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
        fc_set_wwnn(lp, wwnn);
         */
        rtnl_lock();
        memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
 -      dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
 +      dev_unicast_add(fc->real_dev, flogi_maddr);
 +      if (fc->ctlr.spma)
 +              dev_unicast_add(fc->real_dev, fc->ctlr.ctl_src_addr);
        dev_mc_add(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
        rtnl_unlock();
  
        fc->fcoe_packet_type.dev = fc->real_dev;
        dev_add_pack(&fc->fcoe_packet_type);
  
 +      fc->fip_packet_type.func = fcoe_fip_recv;
 +      fc->fip_packet_type.type = htons(ETH_P_FIP);
 +      fc->fip_packet_type.dev = fc->real_dev;
 +      dev_add_pack(&fc->fip_packet_type);
 +
        return 0;
  }
  
@@@ -432,6 -347,7 +445,6 @@@ static int fcoe_if_destroy(struct net_d
  {
        struct fc_lport *lp = NULL;
        struct fcoe_softc *fc;
 -      u8 flogi_maddr[ETH_ALEN];
  
        BUG_ON(!netdev);
  
        /* Remove the instance from fcoe's list */
        fcoe_hostlist_remove(lp);
  
 -      /* Don't listen for Ethernet packets anymore */
 -      dev_remove_pack(&fc->fcoe_packet_type);
 -      dev_remove_pack(&fc->fip_packet_type);
 +      /* clean up netdev configurations */
 +      fcoe_netdev_cleanup(fc);
 +
 +      /* tear-down the FCoE controller */
        fcoe_ctlr_destroy(&fc->ctlr);
  
        /* Cleanup the fc_lport */
        if (lp->emp)
                fc_exch_mgr_free(lp->emp);
  
 -      /* Delete secondary MAC addresses */
 -      rtnl_lock();
 -      memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
 -      dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
 -      if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
 -              dev_unicast_delete(fc->real_dev,
 -                                 fc->ctlr.data_src_addr, ETH_ALEN);
 -      dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
 -      rtnl_unlock();
 -
        /* Free the per-CPU receive threads */
        fcoe_percpu_clean(lp);
  
        /* Free existing skbs */
        fcoe_clean_pending_queue(lp);
  
+       /* Stop the timer */
+       del_timer_sync(&fc->timer);
        /* Free memory used by statistical counters */
        fc_lport_free_stats(lp);
  
@@@ -526,6 -454,58 +542,6 @@@ static struct libfc_function_template f
        .ddp_done = fcoe_ddp_done,
  };
  
 -/**
 - * fcoe_fip_recv - handle a received FIP frame.
 - * @skb: the receive skb
 - * @dev: associated &net_device
 - * @ptype: the &packet_type structure which was used to register this handler.
 - * @orig_dev: original receive &net_device, in case @dev is a bond.
 - *
 - * Returns: 0 for success
 - */
 -static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
 -                       struct packet_type *ptype,
 -                       struct net_device *orig_dev)
 -{
 -      struct fcoe_softc *fc;
 -
 -      fc = container_of(ptype, struct fcoe_softc, fip_packet_type);
 -      fcoe_ctlr_recv(&fc->ctlr, skb);
 -      return 0;
 -}
 -
 -/**
 - * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame.
 - * @fip: FCoE controller.
 - * @skb: FIP Packet.
 - */
 -static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
 -{
 -      skb->dev = fcoe_from_ctlr(fip)->real_dev;
 -      dev_queue_xmit(skb);
 -}
 -
 -/**
 - * fcoe_update_src_mac() - Update Ethernet MAC filters.
 - * @fip: FCoE controller.
 - * @old: Unicast MAC address to delete if the MAC is non-zero.
 - * @new: Unicast MAC address to add.
 - *
 - * Remove any previously-set unicast MAC filter.
 - * Add secondary FCoE MAC address filter for our OUI.
 - */
 -static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
 -{
 -      struct fcoe_softc *fc;
 -
 -      fc = fcoe_from_ctlr(fip);
 -      rtnl_lock();
 -      if (!is_zero_ether_addr(old))
 -              dev_unicast_delete(fc->real_dev, old, ETH_ALEN);
 -      dev_unicast_add(fc->real_dev, new, ETH_ALEN);
 -      rtnl_unlock();
 -}
 -
  /**
   * fcoe_if_create() - this function creates the fcoe interface
   * @netdev: pointer the associated netdevice
@@@ -567,6 -547,13 +583,6 @@@ static int fcoe_if_create(struct net_de
                goto out_host_put;
        }
  
 -      /* configure lport network properties */
 -      rc = fcoe_netdev_config(lp, netdev);
 -      if (rc) {
 -              FC_DBG("Could not configure netdev for lport\n");
 -              goto out_host_put;
 -      }
 -
        /*
         * Initialize FIP.
         */
        fc->ctlr.send = fcoe_fip_send;
        fc->ctlr.update_mac = fcoe_update_src_mac;
  
 -      fc->fip_packet_type.func = fcoe_fip_recv;
 -      fc->fip_packet_type.type = htons(ETH_P_FIP);
 -      fc->fip_packet_type.dev = fc->real_dev;
 -      dev_add_pack(&fc->fip_packet_type);
 +      /* configure lport network properties */
 +      rc = fcoe_netdev_config(lp, netdev);
 +      if (rc) {
 +              FC_DBG("Could not configure netdev for the interface\n");
 +              goto out_netdev_cleanup;
 +      }
  
        /* configure lport scsi host properties */
        rc = fcoe_shost_config(lp, shost, &netdev->dev);
        if (rc) {
                FC_DBG("Could not configure shost for lport\n");
 -              goto out_host_put;
 +              goto out_netdev_cleanup;
        }
  
        /* lport exch manager allocation */
        rc = fcoe_em_config(lp);
        if (rc) {
                FC_DBG("Could not configure em for lport\n");
 -              goto out_host_put;
 +              goto out_netdev_cleanup;
        }
  
        /* Initialize the library */
  
  out_lp_destroy:
        fc_exch_mgr_free(lp->emp); /* Free the EM */
 +out_netdev_cleanup:
 +      fcoe_netdev_cleanup(fc);
  out_host_put:
        scsi_host_put(lp->host);
        return rc;
@@@ -1021,7 -1004,7 +1037,7 @@@ u32 fcoe_fc_crc(struct fc_frame *fp
   */
  int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
  {
-       int wlen, rc = 0;
+       int wlen;
        u32 crc;
        struct ethhdr *eh;
        struct fcoe_crc_eof *cp;
        sof = fr_sof(fp);
        eof = fr_eof(fp);
  
-       elen = (fc->real_dev->priv_flags & IFF_802_1Q_VLAN) ?
-               sizeof(struct vlan_ethhdr) : sizeof(struct ethhdr);
+       elen = sizeof(struct ethhdr);
        hlen = sizeof(struct fcoe_hdr);
        tlen = sizeof(struct fcoe_crc_eof);
        wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
        /* send down to lld */
        fr_dev(fp) = lp;
        if (fc->fcoe_pending_queue.qlen)
-               rc = fcoe_check_wait_queue(lp);
-       if (rc == 0)
-               rc = fcoe_start_io(skb);
-       if (rc) {
-               spin_lock_bh(&fc->fcoe_pending_queue.lock);
-               __skb_queue_tail(&fc->fcoe_pending_queue, skb);
-               spin_unlock_bh(&fc->fcoe_pending_queue.lock);
-               if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
-                       lp->qfull = 1;
-       }
+               fcoe_check_wait_queue(lp, skb);
+       else if (fcoe_start_io(skb))
+               fcoe_check_wait_queue(lp, skb);
  
        return 0;
  }
@@@ -1300,32 -1273,6 +1306,6 @@@ int fcoe_percpu_receive_thread(void *ar
        return 0;
  }
  
- /**
-  * fcoe_watchdog() - fcoe timer callback
-  * @vp:
-  *
-  * This checks the pending queue length for fcoe and set lport qfull
-  * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the
-  * fcoe_hostlist.
-  *
-  * Returns: 0 for success
-  */
- void fcoe_watchdog(ulong vp)
- {
-       struct fcoe_softc *fc;
-       read_lock(&fcoe_hostlist_lock);
-       list_for_each_entry(fc, &fcoe_hostlist, list) {
-               if (fc->ctlr.lp)
-                       fcoe_check_wait_queue(fc->ctlr.lp);
-       }
-       read_unlock(&fcoe_hostlist_lock);
-       fcoe_timer.expires = jiffies + (1 * HZ);
-       add_timer(&fcoe_timer);
- }
  /**
   * fcoe_check_wait_queue() - attempt to clear the transmit backlog
   * @lp: the fc_lport
   * The wait_queue is used when the skb transmit fails. skb will go
   * in the wait_queue which will be emptied by the timer function or
   * by the next skb transmit.
-  *
-  * Returns: 0 for success
   */
- static int fcoe_check_wait_queue(struct fc_lport *lp)
+ static void fcoe_check_wait_queue(struct fc_lport *lp, struct sk_buff *skb)
  {
        struct fcoe_softc *fc = lport_priv(lp);
-       struct sk_buff *skb;
-       int rc = -1;
+       int rc;
  
        spin_lock_bh(&fc->fcoe_pending_queue.lock);
+       if (skb)
+               __skb_queue_tail(&fc->fcoe_pending_queue, skb);
        if (fc->fcoe_pending_queue_active)
                goto out;
        fc->fcoe_pending_queue_active = 1;
  
        if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
                lp->qfull = 0;
+       if (fc->fcoe_pending_queue.qlen && !timer_pending(&fc->timer))
+               mod_timer(&fc->timer, jiffies + 2);
        fc->fcoe_pending_queue_active = 0;
-       rc = fc->fcoe_pending_queue.qlen;
  out:
+       if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
+               lp->qfull = 1;
        spin_unlock_bh(&fc->fcoe_pending_queue.lock);
-       return rc;
+       return;
  }
  
  /**
   * fcoe_dev_setup() - setup link change notification interface
   */
- static void fcoe_dev_setup()
+ static void fcoe_dev_setup(void)
  {
        register_netdevice_notifier(&fcoe_notifier);
  }
  
  /**
-  * fcoe_dev_setup() - cleanup link change notification interface
+  * fcoe_dev_cleanup() - cleanup link change notification interface
   */
  static void fcoe_dev_cleanup(void)
  {
@@@ -1848,10 -1799,6 +1832,6 @@@ static int __init fcoe_init(void
        /* Setup link change notification */
        fcoe_dev_setup();
  
-       setup_timer(&fcoe_timer, fcoe_watchdog, 0);
-       mod_timer(&fcoe_timer, jiffies + (10 * HZ));
        fcoe_if_init();
  
        return 0;
@@@ -1877,9 -1824,6 +1857,6 @@@ static void __exit fcoe_exit(void
  
        fcoe_dev_cleanup();
  
-       /* Stop the timer */
-       del_timer_sync(&fcoe_timer);
        /* releases the associated fcoe hosts */
        list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
                fcoe_if_destroy(fc->real_dev);
index b9aa280100b08a07d23b16d2e7bf82cb5519693c,929411880e4b16c010ca7ca3d7369fddec6abd88..2f5bc7fd3fa90c5c3834fef6a377e025feb70f9f
@@@ -198,8 -198,6 +198,8 @@@ static void fcoe_ctlr_solicit(struct fc
        sol->fip.fip_subcode = FIP_SC_SOL;
        sol->fip.fip_dl_len = htons(sizeof(sol->desc) / FIP_BPW);
        sol->fip.fip_flags = htons(FIP_FL_FPMA);
 +      if (fip->spma)
 +              sol->fip.fip_flags |= htons(FIP_FL_SPMA);
  
        sol->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC;
        sol->desc.mac.fd_desc.fip_dlen = sizeof(sol->desc.mac) / FIP_BPW;
        sol->desc.size.fd_size = htons(fcoe_size);
  
        skb_put(skb, sizeof(*sol));
-       skb->protocol = htons(ETH_P_802_3);
+       skb->protocol = htons(ETH_P_FIP);
        skb_reset_mac_header(skb);
        skb_reset_network_header(skb);
        fip->send(fip, skb);
@@@ -352,8 -350,6 +352,8 @@@ static void fcoe_ctlr_send_keep_alive(s
        kal->fip.fip_dl_len = htons((sizeof(kal->mac) +
                                    ports * sizeof(*vn)) / FIP_BPW);
        kal->fip.fip_flags = htons(FIP_FL_FPMA);
 +      if (fip->spma)
 +              kal->fip.fip_flags |= htons(FIP_FL_SPMA);
  
        kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
        kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
        }
  
        skb_put(skb, len);
-       skb->protocol = htons(ETH_P_802_3);
+       skb->protocol = htons(ETH_P_FIP);
        skb_reset_mac_header(skb);
        skb_reset_network_header(skb);
        fip->send(fip, skb);
@@@ -417,8 -413,6 +417,8 @@@ static int fcoe_ctlr_encaps(struct fcoe
        cap->fip.fip_subcode = FIP_SC_REQ;
        cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW);
        cap->fip.fip_flags = htons(FIP_FL_FPMA);
 +      if (fip->spma)
 +              cap->fip.fip_flags |= htons(FIP_FL_SPMA);
  
        cap->encaps.fd_desc.fip_dtype = dtype;
        cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;
        memset(mac, 0, sizeof(mac));
        mac->fd_desc.fip_dtype = FIP_DT_MAC;
        mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
 -      if (dtype != ELS_FLOGI)
 +      if (dtype != FIP_DT_FLOGI)
                memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
 +      else if (fip->spma)
 +              memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
  
-       skb->protocol = htons(ETH_P_802_3);
+       skb->protocol = htons(ETH_P_FIP);
        skb_reset_mac_header(skb);
        skb_reset_network_header(skb);
        return 0;
@@@ -455,14 -447,10 +455,10 @@@ int fcoe_ctlr_els_send(struct fcoe_ctl
        u16 old_xid;
        u8 op;
  
-       if (fip->state == FIP_ST_NON_FIP)
-               return 0;
        fh = (struct fc_frame_header *)skb->data;
        op = *(u8 *)(fh + 1);
  
-       switch (op) {
-       case ELS_FLOGI:
+       if (op == ELS_FLOGI) {
                old_xid = fip->flogi_oxid;
                fip->flogi_oxid = ntohs(fh->fh_ox_id);
                if (fip->state == FIP_ST_AUTO) {
                        fip->map_dest = 1;
                        return 0;
                }
+               if (fip->state == FIP_ST_NON_FIP)
+                       fip->map_dest = 1;
+       }
+       if (fip->state == FIP_ST_NON_FIP)
+               return 0;
+       switch (op) {
+       case ELS_FLOGI:
                op = FIP_DT_FLOGI;
                break;
        case ELS_FDISC:
diff --combined include/linux/Kbuild
index 7e09c5c1ed027cc4f49740d6b706a49a95af1ee4,b3afd2219ad2e61baa8cc5ad607cd207192d442b..a2df7030d49d2fa11067bb4ad8d714937644e54d
@@@ -135,6 -135,7 +135,7 @@@ header-y += posix_types.
  header-y += ppdev.h
  header-y += prctl.h
  header-y += qnxtypes.h
+ header-y += qnx4_fs.h
  header-y += radeonfb.h
  header-y += raw.h
  header-y += resource.h
@@@ -308,10 -309,8 +309,9 @@@ unifdef-y += poll.
  unifdef-y += ppp_defs.h
  unifdef-y += ppp-comp.h
  unifdef-y += ptrace.h
- unifdef-y += qnx4_fs.h
  unifdef-y += quota.h
  unifdef-y += random.h
 +unifdef-y += rfkill.h
  unifdef-y += irqnr.h
  unifdef-y += reboot.h
  unifdef-y += reiserfs_fs.h
diff --combined include/linux/if_ether.h
index 11a60e4f0a665962f3057d7a73e98f66bd733bab,60e8934d10b5e070ab2289a19c787935026722b1..ae3a1871413dd031b41edcd9e4159f92a1363081
@@@ -79,6 -79,7 +79,7 @@@
  #define ETH_P_AOE     0x88A2          /* ATA over Ethernet            */
  #define ETH_P_TIPC    0x88CA          /* TIPC                         */
  #define ETH_P_FCOE    0x8906          /* Fibre Channel over Ethernet  */
+ #define ETH_P_FIP     0x8914          /* FCoE Initialization Protocol */
  #define ETH_P_EDSA    0xDADA          /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
  
  /*
  #define ETH_P_DSA     0x001B          /* Distributed Switch Arch.     */
  #define ETH_P_TRAILER 0x001C          /* Trailer switch tagging       */
  #define ETH_P_PHONET  0x00F5          /* Nokia Phonet frames          */
 +#define ETH_P_IEEE802154 0x00F6               /* IEEE802.15.4 frame           */
  
  /*
   *    This is an Ethernet frame header.
index e8a8b5c50ed0d0862254017f86454c9fb53d909c,0e2e100c44a275f719377d7c0e2ad113743d404d..3ceb0cc1bc787382dd00d3ea27292422f161881b
@@@ -1,21 -1,14 +1,22 @@@
  #ifndef __NET_DROPMON_H
  #define __NET_DROPMON_H
  
+ #include <linux/types.h>
  #include <linux/netlink.h>
 +#include <linux/types.h>
  
  struct net_dm_drop_point {
        __u8 pc[8];
        __u32 count;
  };
  
 +#define is_drop_point_hw(x) do {\
 +      int ____i, ____j;\
 +      for (____i = 0; ____i < 8; i ____i++)\
 +              ____j |= x[____i];\
 +      ____j;\
 +} while (0)
 +
  #define NET_DM_CFG_VERSION  0
  #define NET_DM_CFG_ALERT_COUNT  1
  #define NET_DM_CFG_ALERT_DELAY 2
diff --combined include/linux/pci_ids.h
index b87c51aea14ce6ce0aa79f113e089673fef20a29,9f36e1cdbf01c4016b1e21ba4d40a83fe5b43cc6..3435c1f3effa3450de05c7eab57a7896d9586497
  #define PCI_DEVICE_ID_PLX_PCI200SYN   0x3196
  #define PCI_DEVICE_ID_PLX_9030          0x9030
  #define PCI_DEVICE_ID_PLX_9050                0x9050
+ #define PCI_DEVICE_ID_PLX_9056                0x9056
  #define PCI_DEVICE_ID_PLX_9080                0x9080
  #define PCI_DEVICE_ID_PLX_GTEK_SERIAL2        0xa001
  
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS       0x0034
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA        0x0036
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_10                0x0037
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_11                0x0038
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2       0x003e
  #define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA 0x0040
  #define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800       0x0041
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE 0x0053
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA        0x0054
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2       0x0055
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_8         0x0056
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_9         0x0057
  #define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO      0x0059
  #define PCI_DEVICE_ID_NVIDIA_CK804_PCIE               0x005d
  #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS    0x0064
  #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE      0x0065
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_2         0x0066
  #define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM               0x0069
  #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO               0x006a
  #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS   0x0084
  #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE     0x0085
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_4         0x0086
  #define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM      0x0089
  #define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO                0x008a
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_5         0x008c
  #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA    0x008e
  #define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT   0x0090
  #define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX 0x0091
  #define PCI_DEVICE_ID_NVIDIA_NFORCE3          0x00d1
  #define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS    0x00d4
  #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE      0x00d5
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_3         0x00d6
  #define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM               0x00d9
  #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO               0x00da
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_7         0x00df
  #define PCI_DEVICE_ID_NVIDIA_NFORCE3S         0x00e1
  #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA    0x00e3
  #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS   0x00e4
  #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE     0x00e5
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_6         0x00e6
  #define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO               0x00ea
  #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2   0x00ee
  #define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1 0x00f0
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS     0x01b4
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE               0x01bc
  #define PCI_DEVICE_ID_NVIDIA_MCP1_MODEM               0x01c1
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_1         0x01c3
  #define PCI_DEVICE_ID_NVIDIA_NFORCE2          0x01e0
  #define PCI_DEVICE_ID_NVIDIA_GEFORCE3         0x0200
  #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1               0x0201
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA        0x037E
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2       0x037F
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_12                0x0268
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_13                0x0269
  #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280
  #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X    0x0281
  #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE     0x0282
  #define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2    0x0348
  #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000       0x034C
  #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100         0x034E
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_14              0x0372
  #define PCI_DEVICE_ID_NVIDIA_NVENET_15              0x0373
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_16              0x03E5
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_17              0x03E6
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA      0x03E7
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS           0x03EB
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE       0x03EC
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_18              0x03EE
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_19              0x03EF
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2     0x03F6
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3     0x03F7
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS           0x0446
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE     0x0448
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_20              0x0450
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_21              0x0451
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_22              0x0452
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_23              0x0453
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS     0x0542
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_24              0x054C
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_25              0x054D
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_26              0x054E
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_27              0x054F
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_28              0x07DC
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_29              0x07DD
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_30              0x07DE
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_31              0x07DF
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE       0x0560
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE       0x056C
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS    0x0752
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE       0x0759
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_32              0x0760
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_33              0x0761
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_34              0x0762
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_35              0x0763
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS     0x07D8
  #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS     0x0AA2
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_36              0x0AB0
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_37              0x0AB1
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_38              0x0AB2
 -#define PCI_DEVICE_ID_NVIDIA_NVENET_39              0x0AB3
  
  #define PCI_VENDOR_ID_IMS             0x10e0
  #define PCI_DEVICE_ID_IMS_TT128               0x9128
  
  #define PCI_VENDOR_ID_CREATIVE                0x1102 /* duplicate: ECTIVA */
  #define PCI_DEVICE_ID_CREATIVE_EMU10K1        0x0002
+ #define PCI_DEVICE_ID_CREATIVE_20K1   0x0005
+ #define PCI_DEVICE_ID_CREATIVE_20K2   0x000b
+ #define PCI_SUBDEVICE_ID_CREATIVE_SB0760      0x0024
+ #define PCI_SUBDEVICE_ID_CREATIVE_SB08801     0x0041
+ #define PCI_SUBDEVICE_ID_CREATIVE_SB08802     0x0042
+ #define PCI_SUBDEVICE_ID_CREATIVE_SB08803     0x0043
+ #define PCI_SUBDEVICE_ID_CREATIVE_HENDRIX     0x6000
  
  #define PCI_VENDOR_ID_ECTIVA          0x1102 /* duplicate: CREATIVE */
  #define PCI_DEVICE_ID_ECTIVA_EV1938   0x8938
  #define PCI_DEVICE_ID_VIA_82C598_1    0x8598
  #define PCI_DEVICE_ID_VIA_838X_1      0xB188
  #define PCI_DEVICE_ID_VIA_83_87XX_1   0xB198
- #define PCI_DEVICE_ID_VIA_C409_IDE    0XC409
+ #define PCI_DEVICE_ID_VIA_VX855_IDE   0xC409
  #define PCI_DEVICE_ID_VIA_ANON                0xFFFF
  
  #define PCI_VENDOR_ID_SIEMENS           0x110A
  #define PCI_SUBDEVICE_ID_HYPERCOPE_METRO      0x0107
  #define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2     0x0108
  
+ #define PCI_VENDOR_ID_DIGIGRAM                0x1369
+ #define PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM   0xc001
+ #define PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_CAE_SERIAL_SUBSYSTEM       0xc002
  #define PCI_VENDOR_ID_KAWASAKI                0x136b
  #define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01
  
  #define PCI_SUBDEVICE_ID_CCD_SWYX4S   0xB540
  #define PCI_SUBDEVICE_ID_CCD_JH4S20   0xB550
  #define PCI_SUBDEVICE_ID_CCD_IOB8ST_1 0xB552
 +#define PCI_SUBDEVICE_ID_CCD_JHSE1    0xB553
 +#define PCI_SUBDEVICE_ID_CCD_JH8S     0xB55B
  #define PCI_SUBDEVICE_ID_CCD_BN4S     0xB560
  #define PCI_SUBDEVICE_ID_CCD_BN8S     0xB562
  #define PCI_SUBDEVICE_ID_CCD_BNE1     0xB563
  #define PCI_DEVICE_ID_OXSEMI_PCIe952_1_U      0xC118
  #define PCI_DEVICE_ID_OXSEMI_PCIe952_1_GU     0xC11C
  #define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
+ #define PCI_DEVICE_ID_OXSEMI_C950     0x950B
  #define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511
  #define PCI_DEVICE_ID_OXSEMI_16PCI954PP       0x9513
  #define PCI_DEVICE_ID_OXSEMI_16PCI952 0x9521
  #define PCI_DEVICE_ID_OXSEMI_16PCI952PP       0x9523
+ #define PCI_SUBDEVICE_ID_OXSEMI_C950  0x0001
  
  #define PCI_VENDOR_ID_CHELSIO         0x1425
  
  #define PCI_VENDOR_ID_MAINPINE                0x1522
  #define PCI_DEVICE_ID_MAINPINE_PBRIDGE        0x0100
  #define PCI_VENDOR_ID_ENE             0x1524
+ #define PCI_DEVICE_ID_ENE_CB710_FLASH 0x0510
  #define PCI_DEVICE_ID_ENE_CB712_SD    0x0550
  #define PCI_DEVICE_ID_ENE_CB712_SD_2  0x0551
  #define PCI_DEVICE_ID_ENE_CB714_SD    0x0750
  
  #define PCI_VENDOR_ID_QMI             0x1a32
  
 +#define PCI_VENDOR_ID_AZWAVE          0x1a3b
 +
  #define PCI_VENDOR_ID_TEKRAM          0x1de1
  #define PCI_DEVICE_ID_TEKRAM_DC290    0xdc29
  
diff --combined include/linux/sched.h
index d853f6bb0baf4c4b72ad0800be09e3d4fbc31210,4896fdfec91383902df140dd05723d64dd2bc769..fea9d188dbfff7ad1002e541143ab2866f5dcc52
@@@ -77,6 -77,7 +77,7 @@@ struct sched_param 
  #include <linux/proportions.h>
  #include <linux/seccomp.h>
  #include <linux/rcupdate.h>
+ #include <linux/rculist.h>
  #include <linux/rtmutex.h>
  
  #include <linux/time.h>
@@@ -96,8 -97,9 +97,9 @@@ struct exec_domain
  struct futex_pi_state;
  struct robust_list_head;
  struct bio;
- struct bts_tracer;
  struct fs_struct;
+ struct bts_context;
+ struct perf_counter_context;
  
  /*
   * List of flags we want to share for kernel threads,
   *    11 bit fractions.
   */
  extern unsigned long avenrun[];               /* Load averages */
+ extern void get_avenrun(unsigned long *loads, unsigned long offset, int shift);
  
  #define FSHIFT                11              /* nr of bits of precision */
  #define FIXED_1               (1<<FSHIFT)     /* 1.0 as fixed-point */
@@@ -135,8 -138,9 +138,9 @@@ DECLARE_PER_CPU(unsigned long, process_
  extern int nr_processes(void);
  extern unsigned long nr_running(void);
  extern unsigned long nr_uninterruptible(void);
- extern unsigned long nr_active(void);
  extern unsigned long nr_iowait(void);
+ extern void calc_global_load(void);
+ extern u64 cpu_nr_migrations(int cpu);
  
  extern unsigned long get_parent_ip(unsigned long addr);
  
@@@ -672,6 -676,10 +676,10 @@@ struct user_struct 
        struct work_struct work;
  #endif
  #endif
+ #ifdef CONFIG_PERF_COUNTERS
+       atomic_long_t locked_vm;
+ #endif
  };
  
  extern int uids_sysfs_init(void);
@@@ -838,7 -846,17 +846,17 @@@ struct sched_group 
         */
        u32 reciprocal_cpu_power;
  
-       unsigned long cpumask[];
+       /*
+        * The CPUs this group covers.
+        *
+        * NOTE: this field is variable length. (Allocated dynamically
+        * by attaching extra space to the end of the structure,
+        * depending on how many CPUs the kernel has booted up with)
+        *
+        * It is also be embedded into static data structures at build
+        * time. (See 'struct static_sched_group' in kernel/sched.c)
+        */
+       unsigned long cpumask[0];
  };
  
  static inline struct cpumask *sched_group_cpus(struct sched_group *sg)
@@@ -924,8 -942,17 +942,17 @@@ struct sched_domain 
        char *name;
  #endif
  
-       /* span of all CPUs in this domain */
-       unsigned long span[];
+       /*
+        * Span of all CPUs in this domain.
+        *
+        * NOTE: this field is variable length. (Allocated dynamically
+        * by attaching extra space to the end of the structure,
+        * depending on how many CPUs the kernel has booted up with)
+        *
+        * It is also be embedded into static data structures at build
+        * time. (See 'struct static_sched_domain' in kernel/sched.c)
+        */
+       unsigned long span[0];
  };
  
  static inline struct cpumask *sched_domain_span(struct sched_domain *sd)
@@@ -1052,9 -1079,10 +1079,10 @@@ struct sched_entity 
        u64                     last_wakeup;
        u64                     avg_overlap;
  
+       u64                     nr_migrations;
        u64                     start_runtime;
        u64                     avg_wakeup;
-       u64                     nr_migrations;
  
  #ifdef CONFIG_SCHEDSTATS
        u64                     wait_start;
@@@ -1209,18 -1237,11 +1237,11 @@@ struct task_struct 
        struct list_head ptraced;
        struct list_head ptrace_entry;
  
- #ifdef CONFIG_X86_PTRACE_BTS
        /*
         * This is the tracer handle for the ptrace BTS extension.
         * This field actually belongs to the ptracer task.
         */
-       struct bts_tracer *bts;
-       /*
-        * The buffer to hold the BTS data.
-        */
-       void *bts_buffer;
-       size_t bts_size;
- #endif /* CONFIG_X86_PTRACE_BTS */
+       struct bts_context *bts;
  
        /* PID/PID hash table linkage. */
        struct pid_link pids[PIDTYPE_MAX];
                                         * credentials (COW) */
        const struct cred *cred;        /* effective (overridable) subjective task
                                         * credentials (COW) */
-       struct mutex cred_exec_mutex;   /* execve vs ptrace cred calculation mutex */
+       struct mutex cred_guard_mutex;  /* guard against foreign influences on
+                                        * credential calculations
+                                        * (notably. ptrace) */
  
        char comm[TASK_COMM_LEN]; /* executable name excluding path
                                     - access with [gs]et_task_comm (which lock
        struct list_head pi_state_list;
        struct futex_pi_state *pi_state_cache;
  #endif
+ #ifdef CONFIG_PERF_COUNTERS
+       struct perf_counter_context *perf_counter_ctxp;
+       struct mutex perf_counter_mutex;
+       struct list_head perf_counter_list;
+ #endif
  #ifdef CONFIG_NUMA
        struct mempolicy *mempolicy;
        short il_next;
  #ifdef CONFIG_TRACING
        /* state flags for use by tracers */
        unsigned long trace;
- #endif
+       /* bitmask of trace recursion */
+       unsigned long trace_recursion;
+ #endif /* CONFIG_TRACING */
  };
  
  /* Future-safe accessor for struct task_struct's cpus_allowed. */
@@@ -1885,6 -1915,7 +1915,7 @@@ extern void sched_dead(struct task_stru
  
  extern void proc_caches_init(void);
  extern void flush_signals(struct task_struct *);
+ extern void __flush_signals(struct task_struct *);
  extern void ignore_signals(struct task_struct *);
  extern void flush_signal_handlers(struct task_struct *, int force_default);
  extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info);
@@@ -2001,8 -2032,10 +2032,10 @@@ extern void set_task_comm(struct task_s
  extern char *get_task_comm(char *to, struct task_struct *tsk);
  
  #ifdef CONFIG_SMP
+ extern void wait_task_context_switch(struct task_struct *p);
  extern unsigned long wait_task_inactive(struct task_struct *, long match_state);
  #else
+ static inline void wait_task_context_switch(struct task_struct *p) {}
  static inline unsigned long wait_task_inactive(struct task_struct *p,
                                               long match_state)
  {
  }
  #endif
  
- #define next_task(p)  list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks)
+ #define next_task(p) \
+       list_entry_rcu((p)->tasks.next, struct task_struct, tasks)
  
  #define for_each_process(p) \
        for (p = &init_task ; (p = next_task(p)) != &init_task ; )
@@@ -2049,8 -2083,8 +2083,8 @@@ int same_thread_group(struct task_struc
  
  static inline struct task_struct *next_thread(const struct task_struct *p)
  {
-       return list_entry(rcu_dereference(p->thread_group.next),
-                         struct task_struct, thread_group);
+       return list_entry_rcu(p->thread_group.next,
+                             struct task_struct, thread_group);
  }
  
  static inline int thread_group_empty(struct task_struct *p)
@@@ -2178,12 -2212,6 +2212,12 @@@ static inline int test_tsk_need_resched
        return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED));
  }
  
 +static inline int restart_syscall(void)
 +{
 +      set_tsk_thread_flag(current, TIF_SIGPENDING);
 +      return -ERESTARTNOINTR;
 +}
 +
  static inline int signal_pending(struct task_struct *p)
  {
        return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING));
@@@ -2394,6 -2422,13 +2428,13 @@@ static inline void inc_syscw(struct tas
  #define TASK_SIZE_OF(tsk)     TASK_SIZE
  #endif
  
+ /*
+  * Call the function if the target task is executing on a CPU right now:
+  */
+ extern void task_oncpu_function_call(struct task_struct *p,
+                                    void (*func) (void *info), void *info);
  #ifdef CONFIG_MM_OWNER
  extern void mm_update_next_owner(struct mm_struct *mm);
  extern void mm_init_owner(struct mm_struct *mm, struct task_struct *p);
index a8989c4547e7e7b790140957dcaaa3c7917952cd,0000000000000000000000000000000000000000..a8989c4547e7e7b790140957dcaaa3c7917952cd
mode 100644,000000..100644
--- /dev/null
@@@ -1,11 -1,0 +1,11 @@@
 +#ifndef _TRACE_NAPI_H_
 +#define _TRACE_NAPI_H_
 +
 +#include <linux/netdevice.h>
 +#include <linux/tracepoint.h>
 +
 +DECLARE_TRACE(napi_poll,
 +      TP_PROTO(struct napi_struct *napi),
 +      TP_ARGS(napi));
 +
 +#endif
diff --combined net/core/dev.c
index ea00e36f48e175c51c30c0b94f253f16f5be0989,e2e9e4af3ace6c2975ebab961f20c5bbf3aa0157..576a61574a936fcab9a7608d2d83c677127aebb6
  #include <linux/in.h>
  #include <linux/jhash.h>
  #include <linux/random.h>
- #include <trace/napi.h>
++#include <trace/events/napi.h>
  
  #include "net-sysfs.h"
  
@@@ -269,8 -268,7 +269,8 @@@ 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_VOID, ARPHRD_NONE};
 +       ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY,
 +       ARPHRD_VOID, ARPHRD_NONE};
  
  static const char *netdev_lock_name[] =
        {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25",
         "_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_VOID", "_xmit_NONE"};
 +       "_xmit_PHONET_PIPE", "_xmit_IEEE802154", "_xmit_IEEE802154_PHY",
 +       "_xmit_VOID", "_xmit_NONE"};
  
  static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)];
  static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)];
@@@ -1050,7 -1047,7 +1050,7 @@@ void dev_load(struct net *net, const ch
  int dev_open(struct net_device *dev)
  {
        const struct net_device_ops *ops = dev->netdev_ops;
 -      int ret = 0;
 +      int ret;
  
        ASSERT_RTNL();
  
        if (!netif_device_present(dev))
                return -ENODEV;
  
 +      ret = call_netdevice_notifiers(NETDEV_PRE_UP, dev);
 +      ret = notifier_to_errno(ret);
 +      if (ret)
 +              return ret;
 +
        /*
         *      Call device private open method
         */
@@@ -1696,16 -1688,7 +1696,16 @@@ int dev_hard_start_xmit(struct sk_buff 
                                goto gso;
                }
  
 +              /*
 +               * If device doesnt need skb->dst, release it right now while
 +               * its hot in this cpu cache
 +               */
 +              if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
 +                      skb_dst_drop(skb);
 +
                rc = ops->ndo_start_xmit(skb, dev);
 +              if (rc == 0)
 +                      txq_trans_update(txq);
                /*
                 * TODO: if skb_orphan() was called by
                 * dev->hard_start_xmit() (for example, the unmodified
@@@ -1735,7 -1718,6 +1735,7 @@@ gso
                        skb->next = nskb;
                        return rc;
                }
 +              txq_trans_update(txq);
                if (unlikely(netif_tx_queue_stopped(txq) && skb->next))
                        return NETDEV_TX_BUSY;
        } while (skb->next);
@@@ -1753,12 -1735,8 +1753,12 @@@ u16 skb_tx_hash(const struct net_devic
  {
        u32 hash;
  
 -      if (skb_rx_queue_recorded(skb))
 -              return skb_get_rx_queue(skb) % dev->real_num_tx_queues;
 +      if (skb_rx_queue_recorded(skb)) {
 +              hash = skb_get_rx_queue(skb);
 +              while (unlikely (hash >= dev->real_num_tx_queues))
 +                      hash -= dev->real_num_tx_queues;
 +              return hash;
 +      }
  
        if (skb->sk && skb->sk->sk_hash)
                hash = skb->sk->sk_hash;
@@@ -1822,7 -1800,7 +1822,7 @@@ int dev_queue_xmit(struct sk_buff *skb
        if (netif_needs_gso(dev, skb))
                goto gso;
  
 -      if (skb_shinfo(skb)->frag_list &&
 +      if (skb_has_frags(skb) &&
            !(dev->features & NETIF_F_FRAGLIST) &&
            __skb_linearize(skb))
                goto out_kfree_skb;
@@@ -2071,13 -2049,11 +2071,13 @@@ static inline int deliver_skb(struct sk
  }
  
  #if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE)
 -/* These hooks defined here for ATM */
 -struct net_bridge;
 -struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
 -                                              unsigned char *addr);
 -void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent) __read_mostly;
 +
 +#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
 +/* 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);
 +#endif
  
  /*
   * If bridge module is loaded call bridging hook.
   */
  struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
                                        struct sk_buff *skb) __read_mostly;
 +EXPORT_SYMBOL(br_handle_frame_hook);
 +
  static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
                                            struct packet_type **pt_prev, int *ret,
                                            struct net_device *orig_dev)
@@@ -2400,6 -2374,26 +2400,6 @@@ void napi_gro_flush(struct napi_struct 
  }
  EXPORT_SYMBOL(napi_gro_flush);
  
 -void *skb_gro_header(struct sk_buff *skb, unsigned int hlen)
 -{
 -      unsigned int offset = skb_gro_offset(skb);
 -
 -      hlen += offset;
 -      if (hlen <= skb_headlen(skb))
 -              return skb->data + offset;
 -
 -      if (unlikely(!skb_shinfo(skb)->nr_frags ||
 -                   skb_shinfo(skb)->frags[0].size <=
 -                   hlen - skb_headlen(skb) ||
 -                   PageHighMem(skb_shinfo(skb)->frags[0].page)))
 -              return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
 -
 -      return page_address(skb_shinfo(skb)->frags[0].page) +
 -             skb_shinfo(skb)->frags[0].page_offset +
 -             offset - skb_headlen(skb);
 -}
 -EXPORT_SYMBOL(skb_gro_header);
 -
  int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
  {
        struct sk_buff **pp = NULL;
        if (!(skb->dev->features & NETIF_F_GRO))
                goto normal;
  
 -      if (skb_is_gso(skb) || skb_shinfo(skb)->frag_list)
 +      if (skb_is_gso(skb) || skb_has_frags(skb))
                goto normal;
  
        rcu_read_lock();
        ret = GRO_HELD;
  
  pull:
 -      if (unlikely(!pskb_may_pull(skb, skb_gro_offset(skb)))) {
 -              if (napi->gro_list == skb)
 -                      napi->gro_list = skb->next;
 -              ret = GRO_DROP;
 +      if (skb_headlen(skb) < skb_gro_offset(skb)) {
 +              int grow = skb_gro_offset(skb) - skb_headlen(skb);
 +
 +              BUG_ON(skb->end - skb->tail < grow);
 +
 +              memcpy(skb_tail_pointer(skb), NAPI_GRO_CB(skb)->frag0, grow);
 +
 +              skb->tail += grow;
 +              skb->data_len -= grow;
 +
 +              skb_shinfo(skb)->frags[0].page_offset += grow;
 +              skb_shinfo(skb)->frags[0].size -= grow;
 +
 +              if (unlikely(!skb_shinfo(skb)->frags[0].size)) {
 +                      put_page(skb_shinfo(skb)->frags[0].page);
 +                      memmove(skb_shinfo(skb)->frags,
 +                              skb_shinfo(skb)->frags + 1,
 +                              --skb_shinfo(skb)->nr_frags);
 +              }
        }
  
  ok:
@@@ -2530,22 -2509,6 +2530,22 @@@ int napi_skb_finish(int ret, struct sk_
  }
  EXPORT_SYMBOL(napi_skb_finish);
  
 +void skb_gro_reset_offset(struct sk_buff *skb)
 +{
 +      NAPI_GRO_CB(skb)->data_offset = 0;
 +      NAPI_GRO_CB(skb)->frag0 = NULL;
 +      NAPI_GRO_CB(skb)->frag0_len = 0;
 +
 +      if (skb->mac_header == skb->tail &&
 +          !PageHighMem(skb_shinfo(skb)->frags[0].page)) {
 +              NAPI_GRO_CB(skb)->frag0 =
 +                      page_address(skb_shinfo(skb)->frags[0].page) +
 +                      skb_shinfo(skb)->frags[0].page_offset;
 +              NAPI_GRO_CB(skb)->frag0_len = skb_shinfo(skb)->frags[0].size;
 +      }
 +}
 +EXPORT_SYMBOL(skb_gro_reset_offset);
 +
  int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
  {
        skb_gro_reset_offset(skb);
@@@ -2563,10 -2526,16 +2563,10 @@@ void napi_reuse_skb(struct napi_struct 
  }
  EXPORT_SYMBOL(napi_reuse_skb);
  
 -struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi,
 -                                struct napi_gro_fraginfo *info)
 +struct sk_buff *napi_get_frags(struct napi_struct *napi)
  {
        struct net_device *dev = napi->dev;
        struct sk_buff *skb = napi->skb;
 -      struct ethhdr *eth;
 -      skb_frag_t *frag;
 -      int i;
 -
 -      napi->skb = NULL;
  
        if (!skb) {
                skb = netdev_alloc_skb(dev, GRO_MAX_HEAD + NET_IP_ALIGN);
                        goto out;
  
                skb_reserve(skb, NET_IP_ALIGN);
 -      }
  
 -      BUG_ON(info->nr_frags > MAX_SKB_FRAGS);
 -      frag = info->frags;
 -
 -      for (i = 0; i < info->nr_frags; i++) {
 -              skb_fill_page_desc(skb, i, frag->page, frag->page_offset,
 -                                 frag->size);
 -              frag++;
 -      }
 -      skb_shinfo(skb)->nr_frags = info->nr_frags;
 -
 -      skb->data_len = info->len;
 -      skb->len += info->len;
 -      skb->truesize += info->len;
 -
 -      skb_reset_mac_header(skb);
 -      skb_gro_reset_offset(skb);
 -
 -      eth = skb_gro_header(skb, sizeof(*eth));
 -      if (!eth) {
 -              napi_reuse_skb(napi, skb);
 -              skb = NULL;
 -              goto out;
 +              napi->skb = skb;
        }
  
 -      skb_gro_pull(skb, sizeof(*eth));
 -
 -      /*
 -       * This works because the only protocols we care about don't require
 -       * special handling.  We'll fix it up properly at the end.
 -       */
 -      skb->protocol = eth->h_proto;
 -
 -      skb->ip_summed = info->ip_summed;
 -      skb->csum = info->csum;
 -
  out:
        return skb;
  }
 -EXPORT_SYMBOL(napi_fraginfo_skb);
 +EXPORT_SYMBOL(napi_get_frags);
  
  int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret)
  {
  }
  EXPORT_SYMBOL(napi_frags_finish);
  
 -int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info)
 +struct sk_buff *napi_frags_skb(struct napi_struct *napi)
  {
 -      struct sk_buff *skb = napi_fraginfo_skb(napi, info);
 +      struct sk_buff *skb = napi->skb;
 +      struct ethhdr *eth;
 +      unsigned int hlen;
 +      unsigned int off;
 +
 +      napi->skb = NULL;
 +
 +      skb_reset_mac_header(skb);
 +      skb_gro_reset_offset(skb);
 +
 +      off = skb_gro_offset(skb);
 +      hlen = off + sizeof(*eth);
 +      eth = skb_gro_header_fast(skb, off);
 +      if (skb_gro_header_hard(skb, hlen)) {
 +              eth = skb_gro_header_slow(skb, hlen, off);
 +              if (unlikely(!eth)) {
 +                      napi_reuse_skb(napi, skb);
 +                      skb = NULL;
 +                      goto out;
 +              }
 +      }
 +
 +      skb_gro_pull(skb, sizeof(*eth));
 +
 +      /*
 +       * This works because the only protocols we care about don't require
 +       * special handling.  We'll fix it up properly at the end.
 +       */
 +      skb->protocol = eth->h_proto;
 +
 +out:
 +      return skb;
 +}
 +EXPORT_SYMBOL(napi_frags_skb);
 +
 +int napi_gro_frags(struct napi_struct *napi)
 +{
 +      struct sk_buff *skb = napi_frags_skb(napi);
  
        if (!skb)
                return NET_RX_DROP;
@@@ -2754,7 -2719,7 +2754,7 @@@ void netif_napi_del(struct napi_struct 
        struct sk_buff *skb, *next;
  
        list_del_init(&napi->dev_list);
 -      kfree_skb(napi->skb);
 +      napi_free_frags(napi);
  
        for (skb = napi->gro_list; skb; skb = next) {
                next = skb->next;
@@@ -2808,10 -2773,8 +2808,10 @@@ static void net_rx_action(struct softir
                 * accidently calling ->poll() when NAPI is not scheduled.
                 */
                work = 0;
 -              if (test_bit(NAPI_STATE_SCHED, &n->state))
 +              if (test_bit(NAPI_STATE_SCHED, &n->state)) {
                        work = n->poll(n, weight);
 +                      trace_napi_poll(n);
 +              }
  
                WARN_ON_ONCE(work > weight);
  
@@@ -3481,319 -3444,6 +3481,319 @@@ void dev_set_rx_mode(struct net_device 
        netif_addr_unlock_bh(dev);
  }
  
 +/* hw addresses list handling functions */
 +
 +static int __hw_addr_add(struct list_head *list, int *delta,
 +                       unsigned char *addr, int addr_len,
 +                       unsigned char addr_type)
 +{
 +      struct netdev_hw_addr *ha;
 +      int alloc_size;
 +
 +      if (addr_len > MAX_ADDR_LEN)
 +              return -EINVAL;
 +
 +      list_for_each_entry(ha, list, list) {
 +              if (!memcmp(ha->addr, addr, addr_len) &&
 +                  ha->type == addr_type) {
 +                      ha->refcount++;
 +                      return 0;
 +              }
 +      }
 +
 +
 +      alloc_size = sizeof(*ha);
 +      if (alloc_size < L1_CACHE_BYTES)
 +              alloc_size = L1_CACHE_BYTES;
 +      ha = kmalloc(alloc_size, GFP_ATOMIC);
 +      if (!ha)
 +              return -ENOMEM;
 +      memcpy(ha->addr, addr, addr_len);
 +      ha->type = addr_type;
 +      ha->refcount = 1;
 +      ha->synced = false;
 +      list_add_tail_rcu(&ha->list, list);
 +      if (delta)
 +              (*delta)++;
 +      return 0;
 +}
 +
 +static void ha_rcu_free(struct rcu_head *head)
 +{
 +      struct netdev_hw_addr *ha;
 +
 +      ha = container_of(head, struct netdev_hw_addr, rcu_head);
 +      kfree(ha);
 +}
 +
 +static int __hw_addr_del(struct list_head *list, int *delta,
 +                       unsigned char *addr, int addr_len,
 +                       unsigned char addr_type)
 +{
 +      struct netdev_hw_addr *ha;
 +
 +      list_for_each_entry(ha, list, list) {
 +              if (!memcmp(ha->addr, addr, addr_len) &&
 +                  (ha->type == addr_type || !addr_type)) {
 +                      if (--ha->refcount)
 +                              return 0;
 +                      list_del_rcu(&ha->list);
 +                      call_rcu(&ha->rcu_head, ha_rcu_free);
 +                      if (delta)
 +                              (*delta)--;
 +                      return 0;
 +              }
 +      }
 +      return -ENOENT;
 +}
 +
 +static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta,
 +                                struct list_head *from_list, int addr_len,
 +                                unsigned char addr_type)
 +{
 +      int err;
 +      struct netdev_hw_addr *ha, *ha2;
 +      unsigned char type;
 +
 +      list_for_each_entry(ha, from_list, list) {
 +              type = addr_type ? addr_type : ha->type;
 +              err = __hw_addr_add(to_list, to_delta, ha->addr,
 +                                  addr_len, type);
 +              if (err)
 +                      goto unroll;
 +      }
 +      return 0;
 +
 +unroll:
 +      list_for_each_entry(ha2, from_list, list) {
 +              if (ha2 == ha)
 +                      break;
 +              type = addr_type ? addr_type : ha2->type;
 +              __hw_addr_del(to_list, to_delta, ha2->addr,
 +                            addr_len, type);
 +      }
 +      return err;
 +}
 +
 +static void __hw_addr_del_multiple(struct list_head *to_list, int *to_delta,
 +                                 struct list_head *from_list, int addr_len,
 +                                 unsigned char addr_type)
 +{
 +      struct netdev_hw_addr *ha;
 +      unsigned char type;
 +
 +      list_for_each_entry(ha, from_list, list) {
 +              type = addr_type ? addr_type : ha->type;
 +              __hw_addr_del(to_list, to_delta, ha->addr,
 +                            addr_len, addr_type);
 +      }
 +}
 +
 +static int __hw_addr_sync(struct list_head *to_list, int *to_delta,
 +                        struct list_head *from_list, int *from_delta,
 +                        int addr_len)
 +{
 +      int err = 0;
 +      struct netdev_hw_addr *ha, *tmp;
 +
 +      list_for_each_entry_safe(ha, tmp, from_list, list) {
 +              if (!ha->synced) {
 +                      err = __hw_addr_add(to_list, to_delta, ha->addr,
 +                                          addr_len, ha->type);
 +                      if (err)
 +                              break;
 +                      ha->synced = true;
 +                      ha->refcount++;
 +              } else if (ha->refcount == 1) {
 +                      __hw_addr_del(to_list, to_delta, ha->addr,
 +                                    addr_len, ha->type);
 +                      __hw_addr_del(from_list, from_delta, ha->addr,
 +                                    addr_len, ha->type);
 +              }
 +      }
 +      return err;
 +}
 +
 +static void __hw_addr_unsync(struct list_head *to_list, int *to_delta,
 +                           struct list_head *from_list, int *from_delta,
 +                           int addr_len)
 +{
 +      struct netdev_hw_addr *ha, *tmp;
 +
 +      list_for_each_entry_safe(ha, tmp, from_list, list) {
 +              if (ha->synced) {
 +                      __hw_addr_del(to_list, to_delta, ha->addr,
 +                                    addr_len, ha->type);
 +                      ha->synced = false;
 +                      __hw_addr_del(from_list, from_delta, ha->addr,
 +                                    addr_len, ha->type);
 +              }
 +      }
 +}
 +
 +
 +static void __hw_addr_flush(struct list_head *list)
 +{
 +      struct netdev_hw_addr *ha, *tmp;
 +
 +      list_for_each_entry_safe(ha, tmp, list, list) {
 +              list_del_rcu(&ha->list);
 +              call_rcu(&ha->rcu_head, ha_rcu_free);
 +      }
 +}
 +
 +/* Device addresses handling functions */
 +
 +static void dev_addr_flush(struct net_device *dev)
 +{
 +      /* rtnl_mutex must be held here */
 +
 +      __hw_addr_flush(&dev->dev_addr_list);
 +      dev->dev_addr = NULL;
 +}
 +
 +static int dev_addr_init(struct net_device *dev)
 +{
 +      unsigned char addr[MAX_ADDR_LEN];
 +      struct netdev_hw_addr *ha;
 +      int err;
 +
 +      /* rtnl_mutex must be held here */
 +
 +      INIT_LIST_HEAD(&dev->dev_addr_list);
 +      memset(addr, 0, sizeof(addr));
 +      err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(addr),
 +                          NETDEV_HW_ADDR_T_LAN);
 +      if (!err) {
 +              /*
 +               * Get the first (previously created) address from the list
 +               * and set dev_addr pointer to this location.
 +               */
 +              ha = list_first_entry(&dev->dev_addr_list,
 +                                    struct netdev_hw_addr, list);
 +              dev->dev_addr = ha->addr;
 +      }
 +      return err;
 +}
 +
 +/**
 + *    dev_addr_add    - Add a device address
 + *    @dev: device
 + *    @addr: address to add
 + *    @addr_type: address type
 + *
 + *    Add a device address to the device or increase the reference count if
 + *    it already exists.
 + *
 + *    The caller must hold the rtnl_mutex.
 + */
 +int dev_addr_add(struct net_device *dev, unsigned char *addr,
 +               unsigned char addr_type)
 +{
 +      int err;
 +
 +      ASSERT_RTNL();
 +
 +      err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, dev->addr_len,
 +                          addr_type);
 +      if (!err)
 +              call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
 +      return err;
 +}
 +EXPORT_SYMBOL(dev_addr_add);
 +
 +/**
 + *    dev_addr_del    - Release a device address.
 + *    @dev: device
 + *    @addr: address to delete
 + *    @addr_type: address type
 + *
 + *    Release reference to a device address and remove it from the device
 + *    if the reference count drops to zero.
 + *
 + *    The caller must hold the rtnl_mutex.
 + */
 +int dev_addr_del(struct net_device *dev, unsigned char *addr,
 +               unsigned char addr_type)
 +{
 +      int err;
 +      struct netdev_hw_addr *ha;
 +
 +      ASSERT_RTNL();
 +
 +      /*
 +       * We can not remove the first address from the list because
 +       * dev->dev_addr points to that.
 +       */
 +      ha = list_first_entry(&dev->dev_addr_list, struct netdev_hw_addr, list);
 +      if (ha->addr == dev->dev_addr && ha->refcount == 1)
 +              return -ENOENT;
 +
 +      err = __hw_addr_del(&dev->dev_addr_list, NULL, addr, dev->addr_len,
 +                          addr_type);
 +      if (!err)
 +              call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
 +      return err;
 +}
 +EXPORT_SYMBOL(dev_addr_del);
 +
 +/**
 + *    dev_addr_add_multiple   - Add device addresses from another device
 + *    @to_dev: device to which addresses will be added
 + *    @from_dev: device from which addresses will be added
 + *    @addr_type: address type - 0 means type will be used from from_dev
 + *
 + *    Add device addresses of the one device to another.
 + **
 + *    The caller must hold the rtnl_mutex.
 + */
 +int dev_addr_add_multiple(struct net_device *to_dev,
 +                        struct net_device *from_dev,
 +                        unsigned char addr_type)
 +{
 +      int err;
 +
 +      ASSERT_RTNL();
 +
 +      if (from_dev->addr_len != to_dev->addr_len)
 +              return -EINVAL;
 +      err = __hw_addr_add_multiple(&to_dev->dev_addr_list, NULL,
 +                                   &from_dev->dev_addr_list,
 +                                   to_dev->addr_len, addr_type);
 +      if (!err)
 +              call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev);
 +      return err;
 +}
 +EXPORT_SYMBOL(dev_addr_add_multiple);
 +
 +/**
 + *    dev_addr_del_multiple   - Delete device addresses by another device
 + *    @to_dev: device where the addresses will be deleted
 + *    @from_dev: device by which addresses the addresses will be deleted
 + *    @addr_type: address type - 0 means type will used from from_dev
 + *
 + *    Deletes addresses in to device by the list of addresses in from device.
 + *
 + *    The caller must hold the rtnl_mutex.
 + */
 +int dev_addr_del_multiple(struct net_device *to_dev,
 +                        struct net_device *from_dev,
 +                        unsigned char addr_type)
 +{
 +      ASSERT_RTNL();
 +
 +      if (from_dev->addr_len != to_dev->addr_len)
 +              return -EINVAL;
 +      __hw_addr_del_multiple(&to_dev->dev_addr_list, NULL,
 +                             &from_dev->dev_addr_list,
 +                             to_dev->addr_len, addr_type);
 +      call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev);
 +      return 0;
 +}
 +EXPORT_SYMBOL(dev_addr_del_multiple);
 +
 +/* unicast and multicast addresses handling functions */
 +
  int __dev_addr_delete(struct dev_addr_list **list, int *count,
                      void *addr, int alen, int glbl)
  {
@@@ -3856,22 -3506,24 +3856,22 @@@ int __dev_addr_add(struct dev_addr_lis
   *    dev_unicast_delete      - Release secondary unicast address.
   *    @dev: device
   *    @addr: address to delete
 - *    @alen: length of @addr
   *
   *    Release reference to a secondary unicast address and remove it
   *    from the device if the reference count drops to zero.
   *
   *    The caller must hold the rtnl_mutex.
   */
 -int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
 +int dev_unicast_delete(struct net_device *dev, void *addr)
  {
        int err;
  
        ASSERT_RTNL();
  
 -      netif_addr_lock_bh(dev);
 -      err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
 +      err = __hw_addr_del(&dev->uc_list, &dev->uc_count, addr,
 +                          dev->addr_len, NETDEV_HW_ADDR_T_UNICAST);
        if (!err)
                __dev_set_rx_mode(dev);
 -      netif_addr_unlock_bh(dev);
        return err;
  }
  EXPORT_SYMBOL(dev_unicast_delete);
   *    dev_unicast_add         - add a secondary unicast address
   *    @dev: device
   *    @addr: address to add
 - *    @alen: length of @addr
   *
   *    Add a secondary unicast address to the device or increase
   *    the reference count if it already exists.
   *
   *    The caller must hold the rtnl_mutex.
   */
 -int dev_unicast_add(struct net_device *dev, void *addr, int alen)
 +int dev_unicast_add(struct net_device *dev, void *addr)
  {
        int err;
  
        ASSERT_RTNL();
  
 -      netif_addr_lock_bh(dev);
 -      err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
 +      err = __hw_addr_add(&dev->uc_list, &dev->uc_count, addr,
 +                          dev->addr_len, NETDEV_HW_ADDR_T_UNICAST);
        if (!err)
                __dev_set_rx_mode(dev);
 -      netif_addr_unlock_bh(dev);
        return err;
  }
  EXPORT_SYMBOL(dev_unicast_add);
@@@ -3952,7 -3606,8 +3952,7 @@@ void __dev_addr_unsync(struct dev_addr_
   *    @from: source device
   *
   *    Add newly added addresses to the destination device and release
 - *    addresses that have no users left. The source device must be
 - *    locked by netif_tx_lock_bh.
 + *    addresses that have no users left.
   *
   *    This function is intended to be called from the dev->set_rx_mode
   *    function of layered software devices.
@@@ -3961,15 -3616,12 +3961,15 @@@ int dev_unicast_sync(struct net_device 
  {
        int err = 0;
  
 -      netif_addr_lock_bh(to);
 -      err = __dev_addr_sync(&to->uc_list, &to->uc_count,
 -                            &from->uc_list, &from->uc_count);
 +      ASSERT_RTNL();
 +
 +      if (to->addr_len != from->addr_len)
 +              return -EINVAL;
 +
 +      err = __hw_addr_sync(&to->uc_list, &to->uc_count,
 +                           &from->uc_list, &from->uc_count, to->addr_len);
        if (!err)
                __dev_set_rx_mode(to);
 -      netif_addr_unlock_bh(to);
        return err;
  }
  EXPORT_SYMBOL(dev_unicast_sync);
   */
  void dev_unicast_unsync(struct net_device *to, struct net_device *from)
  {
 -      netif_addr_lock_bh(from);
 -      netif_addr_lock(to);
 +      ASSERT_RTNL();
  
 -      __dev_addr_unsync(&to->uc_list, &to->uc_count,
 -                        &from->uc_list, &from->uc_count);
 -      __dev_set_rx_mode(to);
 +      if (to->addr_len != from->addr_len)
 +              return;
  
 -      netif_addr_unlock(to);
 -      netif_addr_unlock_bh(from);
 +      __hw_addr_unsync(&to->uc_list, &to->uc_count,
 +                       &from->uc_list, &from->uc_count, to->addr_len);
 +      __dev_set_rx_mode(to);
  }
  EXPORT_SYMBOL(dev_unicast_unsync);
  
 +static void dev_unicast_flush(struct net_device *dev)
 +{
 +      /* rtnl_mutex must be held here */
 +
 +      __hw_addr_flush(&dev->uc_list);
 +      dev->uc_count = 0;
 +}
 +
 +static void dev_unicast_init(struct net_device *dev)
 +{
 +      /* rtnl_mutex must be held here */
 +
 +      INIT_LIST_HEAD(&dev->uc_list);
 +}
 +
 +
  static void __dev_addr_discard(struct dev_addr_list **list)
  {
        struct dev_addr_list *tmp;
@@@ -4030,6 -3667,9 +4030,6 @@@ static void dev_addr_discard(struct net
  {
        netif_addr_lock_bh(dev);
  
 -      __dev_addr_discard(&dev->uc_list);
 -      dev->uc_count = 0;
 -
        __dev_addr_discard(&dev->mc_list);
        dev->mc_count = 0;
  
@@@ -4213,7 -3853,7 +4213,7 @@@ static int dev_ifsioc_locked(struct ne
  
        switch (cmd) {
                case SIOCGIFFLAGS:      /* Get interface flags */
 -                      ifr->ifr_flags = dev_get_flags(dev);
 +                      ifr->ifr_flags = (short) dev_get_flags(dev);
                        return 0;
  
                case SIOCGIFMETRIC:     /* Get the metric on the interface
@@@ -4622,7 -4262,6 +4622,7 @@@ static void rollback_registered(struct 
        /*
         *      Flush the unicast and multicast chains
         */
 +      dev_unicast_flush(dev);
        dev_addr_discard(dev);
  
        if (dev->netdev_ops->ndo_uninit)
@@@ -4694,6 -4333,39 +4694,6 @@@ unsigned long netdev_fix_features(unsig
  }
  EXPORT_SYMBOL(netdev_fix_features);
  
 -/* Some devices need to (re-)set their netdev_ops inside
 - * ->init() or similar.  If that happens, we have to setup
 - * the compat pointers again.
 - */
 -void netdev_resync_ops(struct net_device *dev)
 -{
 -#ifdef CONFIG_COMPAT_NET_DEV_OPS
 -      const struct net_device_ops *ops = dev->netdev_ops;
 -
 -      dev->init = ops->ndo_init;
 -      dev->uninit = ops->ndo_uninit;
 -      dev->open = ops->ndo_open;
 -      dev->change_rx_flags = ops->ndo_change_rx_flags;
 -      dev->set_rx_mode = ops->ndo_set_rx_mode;
 -      dev->set_multicast_list = ops->ndo_set_multicast_list;
 -      dev->set_mac_address = ops->ndo_set_mac_address;
 -      dev->validate_addr = ops->ndo_validate_addr;
 -      dev->do_ioctl = ops->ndo_do_ioctl;
 -      dev->set_config = ops->ndo_set_config;
 -      dev->change_mtu = ops->ndo_change_mtu;
 -      dev->neigh_setup = ops->ndo_neigh_setup;
 -      dev->tx_timeout = ops->ndo_tx_timeout;
 -      dev->get_stats = ops->ndo_get_stats;
 -      dev->vlan_rx_register = ops->ndo_vlan_rx_register;
 -      dev->vlan_rx_add_vid = ops->ndo_vlan_rx_add_vid;
 -      dev->vlan_rx_kill_vid = ops->ndo_vlan_rx_kill_vid;
 -#ifdef CONFIG_NET_POLL_CONTROLLER
 -      dev->poll_controller = ops->ndo_poll_controller;
 -#endif
 -#endif
 -}
 -EXPORT_SYMBOL(netdev_resync_ops);
 -
  /**
   *    register_netdevice      - register a network device
   *    @dev: device to register
@@@ -4733,6 -4405,23 +4733,6 @@@ int register_netdevice(struct net_devic
  
        dev->iflink = -1;
  
 -#ifdef CONFIG_COMPAT_NET_DEV_OPS
 -      /* Netdevice_ops API compatibility support.
 -       * This is temporary until all network devices are converted.
 -       */
 -      if (dev->netdev_ops) {
 -              netdev_resync_ops(dev);
 -      } else {
 -              char drivername[64];
 -              pr_info("%s (%s): not using net_device_ops yet\n",
 -                      dev->name, netdev_drivername(dev, drivername, 64));
 -
 -              /* This works only because net_device_ops and the
 -                 compatibility structure are the same. */
 -              dev->netdev_ops = (void *) &(dev->init);
 -      }
 -#endif
 -
        /* Init, if this function is available */
        if (dev->netdev_ops->ndo_init) {
                ret = dev->netdev_ops->ndo_init(dev);
@@@ -5018,30 -4707,13 +5018,30 @@@ void netdev_run_todo(void
   *    the internal statistics structure is used.
   */
  const struct net_device_stats *dev_get_stats(struct net_device *dev)
 - {
 +{
        const struct net_device_ops *ops = dev->netdev_ops;
  
        if (ops->ndo_get_stats)
                return ops->ndo_get_stats(dev);
 -      else
 -              return &dev->stats;
 +      else {
 +              unsigned long tx_bytes = 0, tx_packets = 0, tx_dropped = 0;
 +              struct net_device_stats *stats = &dev->stats;
 +              unsigned int i;
 +              struct netdev_queue *txq;
 +
 +              for (i = 0; i < dev->num_tx_queues; i++) {
 +                      txq = netdev_get_tx_queue(dev, i);
 +                      tx_bytes   += txq->tx_bytes;
 +                      tx_packets += txq->tx_packets;
 +                      tx_dropped += txq->tx_dropped;
 +              }
 +              if (tx_bytes || tx_packets || tx_dropped) {
 +                      stats->tx_bytes   = tx_bytes;
 +                      stats->tx_packets = tx_packets;
 +                      stats->tx_dropped = tx_dropped;
 +              }
 +              return stats;
 +      }
  }
  EXPORT_SYMBOL(dev_get_stats);
  
@@@ -5076,18 -4748,18 +5076,18 @@@ struct net_device *alloc_netdev_mq(int 
        struct netdev_queue *tx;
        struct net_device *dev;
        size_t alloc_size;
 -      void *p;
 +      struct net_device *p;
  
        BUG_ON(strlen(name) >= sizeof(dev->name));
  
        alloc_size = sizeof(struct net_device);
        if (sizeof_priv) {
                /* ensure 32-byte alignment of private area */
 -              alloc_size = (alloc_size + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST;
 +              alloc_size = ALIGN(alloc_size, NETDEV_ALIGN);
                alloc_size += sizeof_priv;
        }
        /* ensure 32-byte alignment of whole construct */
 -      alloc_size += NETDEV_ALIGN_CONST;
 +      alloc_size += NETDEV_ALIGN - 1;
  
        p = kzalloc(alloc_size, GFP_KERNEL);
        if (!p) {
        if (!tx) {
                printk(KERN_ERR "alloc_netdev: Unable to allocate "
                       "tx qdiscs.\n");
 -              kfree(p);
 -              return NULL;
 +              goto free_p;
        }
  
 -      dev = (struct net_device *)
 -              (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
 +      dev = PTR_ALIGN(p, NETDEV_ALIGN);
        dev->padded = (char *)dev - (char *)p;
 +
 +      if (dev_addr_init(dev))
 +              goto free_tx;
 +
 +      dev_unicast_init(dev);
 +
        dev_net_set(dev, &init_net);
  
        dev->_tx = tx;
        netdev_init_queues(dev);
  
        INIT_LIST_HEAD(&dev->napi_list);
 +      dev->priv_flags = IFF_XMIT_DST_RELEASE;
        setup(dev);
        strcpy(dev->name, name);
        return dev;
 +
 +free_tx:
 +      kfree(tx);
 +
 +free_p:
 +      kfree(p);
 +      return NULL;
  }
  EXPORT_SYMBOL(alloc_netdev_mq);
  
@@@ -5151,9 -4811,6 +5151,9 @@@ void free_netdev(struct net_device *dev
  
        kfree(dev->_tx);
  
 +      /* Flush device addresses */
 +      dev_addr_flush(dev);
 +
        list_for_each_entry_safe(p, n, &dev->napi_list, dev_list)
                netif_napi_del(p);
  
@@@ -5313,7 -4970,6 +5313,7 @@@ int dev_change_net_namespace(struct net
        /*
         *      Flush the unicast and multicast chains
         */
 +      dev_unicast_flush(dev);
        dev_addr_discard(dev);
  
        netdev_unregister_kobject(dev);
@@@ -5669,6 -5325,12 +5669,6 @@@ EXPORT_SYMBOL(net_enable_timestamp)
  EXPORT_SYMBOL(net_disable_timestamp);
  EXPORT_SYMBOL(dev_get_flags);
  
 -#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 -EXPORT_SYMBOL(br_handle_frame_hook);
 -EXPORT_SYMBOL(br_fdb_get_hook);
 -EXPORT_SYMBOL(br_fdb_put_hook);
 -#endif
 -
  EXPORT_SYMBOL(dev_load);
  
  EXPORT_PER_CPU_SYMBOL(softnet_data);
diff --combined net/core/drop_monitor.c
index a6c2ac2828fb22269594621a1892c7d631dd2fee,b75b6cea49dab47cbca9098a259ac44e4e51b4c8..9d66fa953ab7bdbb160090e3544e038dff658eae
  #include <linux/timer.h>
  #include <linux/bitops.h>
  #include <net/genetlink.h>
 +#include <net/netevent.h>
  
- #include <trace/skb.h>
- #include <trace/napi.h>
+ #include <trace/events/skb.h>
++#include <trace/events/napi.h>
  
  #include <asm/unaligned.h>
  
@@@ -40,8 -38,7 +40,8 @@@ static void send_dm_alert(struct work_s
   * and the work handle that will send up
   * netlink alerts
   */
 -struct sock *dm_sock;
 +static int trace_state = TRACE_OFF;
 +static spinlock_t trace_state_lock = SPIN_LOCK_UNLOCKED;
  
  struct per_cpu_dm_data {
        struct work_struct dm_alert_work;
        struct timer_list send_timer;
  };
  
 +struct dm_hw_stat_delta {
 +      struct net_device *dev;
 +      struct list_head list;
 +      struct rcu_head rcu;
 +      unsigned long last_drop_val;
 +};
 +
  static struct genl_family net_drop_monitor_family = {
        .id             = GENL_ID_GENERATE,
        .hdrsize        = 0,
        .name           = "NET_DM",
 -      .version        = 1,
 +      .version        = 2,
        .maxattr        = NET_DM_CMD_MAX,
  };
  
@@@ -69,24 -59,19 +69,24 @@@ static DEFINE_PER_CPU(struct per_cpu_dm
  
  static int dm_hit_limit = 64;
  static int dm_delay = 1;
 -
 +static unsigned long dm_hw_check_delta = 2*HZ;
 +static LIST_HEAD(hw_stats_list);
  
  static void reset_per_cpu_data(struct per_cpu_dm_data *data)
  {
        size_t al;
        struct net_dm_alert_msg *msg;
 +      struct nlattr *nla;
  
        al = sizeof(struct net_dm_alert_msg);
        al += dm_hit_limit * sizeof(struct net_dm_drop_point);
 +      al += sizeof(struct nlattr);
 +
        data->skb = genlmsg_new(al, GFP_KERNEL);
        genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family,
                        0, NET_DM_CMD_ALERT);
 -      msg = __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_alert_msg));
 +      nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg));
 +      msg = nla_data(nla);
        memset(msg, 0, al);
        atomic_set(&data->dm_hit_count, dm_hit_limit);
  }
@@@ -126,11 -111,10 +126,11 @@@ static void sched_send_work(unsigned lo
        schedule_work(&data->dm_alert_work);
  }
  
 -static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
 +static void trace_drop_common(struct sk_buff *skb, void *location)
  {
        struct net_dm_alert_msg *msg;
        struct nlmsghdr *nlh;
 +      struct nlattr *nla;
        int i;
        struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
  
        }
  
        nlh = (struct nlmsghdr *)data->skb->data;
 -      msg = genlmsg_data(nlmsg_data(nlh));
 +      nla = genlmsg_data(nlmsg_data(nlh));
 +      msg = nla_data(nla);
        for (i = 0; i < msg->entries; i++) {
                if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) {
                        msg->points[i].count++;
         * We need to create a new entry
         */
        __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point));
 +      nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point));
        memcpy(msg->points[msg->entries].pc, &location, sizeof(void *));
        msg->points[msg->entries].count = 1;
        msg->entries++;
@@@ -170,80 -152,24 +170,80 @@@ out
        return;
  }
  
 +static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
 +{
 +      trace_drop_common(skb, location);
 +}
 +
 +static void trace_napi_poll_hit(struct napi_struct *napi)
 +{
 +      struct dm_hw_stat_delta *new_stat;
 +
 +      /*
 +       * Ratelimit our check time to dm_hw_check_delta jiffies
 +       */
 +      if (!time_after(jiffies, napi->dev->last_rx + dm_hw_check_delta))
 +              return;
 +
 +      rcu_read_lock();
 +      list_for_each_entry_rcu(new_stat, &hw_stats_list, list) {
 +              if ((new_stat->dev == napi->dev)  &&
 +                  (napi->dev->stats.rx_dropped != new_stat->last_drop_val)) {
 +                      trace_drop_common(NULL, NULL);
 +                      new_stat->last_drop_val = napi->dev->stats.rx_dropped;
 +                      break;
 +              }
 +      }
 +      rcu_read_unlock();
 +}
 +
 +
 +static void free_dm_hw_stat(struct rcu_head *head)
 +{
 +      struct dm_hw_stat_delta *n;
 +      n = container_of(head, struct dm_hw_stat_delta, rcu);
 +      kfree(n);
 +}
 +
  static int set_all_monitor_traces(int state)
  {
        int rc = 0;
 +      struct dm_hw_stat_delta *new_stat = NULL;
 +      struct dm_hw_stat_delta *temp;
 +
 +      spin_lock(&trace_state_lock);
  
        switch (state) {
        case TRACE_ON:
                rc |= register_trace_kfree_skb(trace_kfree_skb_hit);
 +              rc |= register_trace_napi_poll(trace_napi_poll_hit);
                break;
        case TRACE_OFF:
                rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit);
 +              rc |= unregister_trace_napi_poll(trace_napi_poll_hit);
  
                tracepoint_synchronize_unregister();
 +
 +              /*
 +               * Clean the device list
 +               */
 +              list_for_each_entry_safe(new_stat, temp, &hw_stats_list, list) {
 +                      if (new_stat->dev == NULL) {
 +                              list_del_rcu(&new_stat->list);
 +                              call_rcu(&new_stat->rcu, free_dm_hw_stat);
 +                      }
 +              }
                break;
        default:
                rc = 1;
                break;
        }
  
 +      if (!rc)
 +              trace_state = state;
 +
 +      spin_unlock(&trace_state_lock);
 +
        if (rc)
                return -EINPROGRESS;
        return rc;
@@@ -271,44 -197,6 +271,44 @@@ static int net_dm_cmd_trace(struct sk_b
        return -ENOTSUPP;
  }
  
 +static int dropmon_net_event(struct notifier_block *ev_block,
 +                      unsigned long event, void *ptr)
 +{
 +      struct net_device *dev = ptr;
 +      struct dm_hw_stat_delta *new_stat = NULL;
 +      struct dm_hw_stat_delta *tmp;
 +
 +      switch (event) {
 +      case NETDEV_REGISTER:
 +              new_stat = kzalloc(sizeof(struct dm_hw_stat_delta), GFP_KERNEL);
 +
 +              if (!new_stat)
 +                      goto out;
 +
 +              new_stat->dev = dev;
 +              INIT_RCU_HEAD(&new_stat->rcu);
 +              spin_lock(&trace_state_lock);
 +              list_add_rcu(&new_stat->list, &hw_stats_list);
 +              spin_unlock(&trace_state_lock);
 +              break;
 +      case NETDEV_UNREGISTER:
 +              spin_lock(&trace_state_lock);
 +              list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) {
 +                      if (new_stat->dev == dev) {
 +                              new_stat->dev = NULL;
 +                              if (trace_state == TRACE_OFF) {
 +                                      list_del_rcu(&new_stat->list);
 +                                      call_rcu(&new_stat->rcu, free_dm_hw_stat);
 +                                      break;
 +                              }
 +                      }
 +              }
 +              spin_unlock(&trace_state_lock);
 +              break;
 +      }
 +out:
 +      return NOTIFY_DONE;
 +}
  
  static struct genl_ops dropmon_ops[] = {
        {
        },
  };
  
 +static struct notifier_block dropmon_net_notifier = {
 +      .notifier_call = dropmon_net_event
 +};
 +
  static int __init init_net_drop_monitor(void)
  {
        int cpu;
                ret = genl_register_ops(&net_drop_monitor_family,
                                        &dropmon_ops[i]);
                if (ret) {
 -                      printk(KERN_CRIT "failed to register operation %d\n",
 +                      printk(KERN_CRIT "Failed to register operation %d\n",
                                dropmon_ops[i].cmd);
                        goto out_unreg;
                }
        }
  
 +      rc = register_netdevice_notifier(&dropmon_net_notifier);
 +      if (rc < 0) {
 +              printk(KERN_CRIT "Failed to register netdevice notifier\n");
 +              goto out_unreg;
 +      }
 +
        rc = 0;
  
        for_each_present_cpu(cpu) {
                data->send_timer.data = cpu;
                data->send_timer.function = sched_send_work;
        }
 +
        goto out;
  
  out_unreg:
diff --combined net/core/net-traces.c
index b07b25bd2cde44315313a24d9c8d9a10ef54fb71,499a67eaf3ae201262c4a2e53f20870721b8f184..f1e982c508bb16df812024014d953c184e777247
  #include <linux/workqueue.h>
  #include <linux/netlink.h>
  #include <linux/net_dropmon.h>
- #include <trace/skb.h>
- #include <trace/napi.h>
  
  #include <asm/unaligned.h>
  #include <asm/bitops.h>
  
+ #define CREATE_TRACE_POINTS
+ #include <trace/events/skb.h>
++#include <trace/events/napi.h>
  
- DEFINE_TRACE(kfree_skb);
  EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb);
- DEFINE_TRACE(napi_poll);
 +
 +EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll);
diff --combined net/core/netpoll.c
index 7ab31a7576a17c3a7fe7560d11e78007d2bc6218,64f51eec6576290e3b2df361316ee5448396642d..9675f312830dd762bcd530eee90569de5a89b320
@@@ -24,7 -24,6 +24,7 @@@
  #include <net/tcp.h>
  #include <net/udp.h>
  #include <asm/unaligned.h>
- #include <trace/napi.h>
++#include <trace/events/napi.h>
  
  /*
   * We maintain a small pool of fully-sized skbs, to make sure the
@@@ -138,7 -137,6 +138,7 @@@ static int poll_one_napi(struct netpoll
        set_bit(NAPI_STATE_NPSVC, &napi->state);
  
        work = napi->poll(napi, budget);
 +      trace_napi_poll(napi);
  
        clear_bit(NAPI_STATE_NPSVC, &napi->state);
        atomic_dec(&trapped);
@@@ -302,11 -300,8 +302,11 @@@ static void netpoll_send_skb(struct net
                for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
                     tries > 0; --tries) {
                        if (__netif_tx_trylock(txq)) {
 -                              if (!netif_tx_queue_stopped(txq))
 +                              if (!netif_tx_queue_stopped(txq)) {
                                        status = ops->ndo_start_xmit(skb, dev);
 +                                      if (status == NETDEV_TX_OK)
 +                                              txq_trans_update(txq);
 +                              }
                                __netif_tx_unlock(txq);
  
                                if (status == NETDEV_TX_OK)
diff --combined net/core/skbuff.c
index b94d777e3eb4d9a5560bf7b5de0ee94801f59e8e,c2e4fb8f3546c06a39b22b8c8538ecdf7187c3e7..1a94a3037370a4c70ee3862fb9676a4975eddeb1
@@@ -65,7 -65,7 +65,7 @@@
  
  #include <asm/uaccess.h>
  #include <asm/system.h>
- #include <trace/skb.h>
+ #include <trace/events/skb.h>
  
  #include "kmap_skb.h"
  
@@@ -210,7 -210,7 +210,7 @@@ struct sk_buff *__alloc_skb(unsigned in
        shinfo->gso_type = 0;
        shinfo->ip6_frag_id = 0;
        shinfo->tx_flags.flags = 0;
 -      shinfo->frag_list = NULL;
 +      skb_frag_list_init(skb);
        memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps));
  
        if (fclone) {
@@@ -323,7 -323,7 +323,7 @@@ static void skb_clone_fraglist(struct s
  {
        struct sk_buff *list;
  
 -      for (list = skb_shinfo(skb)->frag_list; list; list = list->next)
 +      skb_walk_frags(skb, list)
                skb_get(list);
  }
  
@@@ -338,7 -338,7 +338,7 @@@ static void skb_release_data(struct sk_
                                put_page(skb_shinfo(skb)->frags[i].page);
                }
  
 -              if (skb_shinfo(skb)->frag_list)
 +              if (skb_has_frags(skb))
                        skb_drop_fraglist(skb);
  
                kfree(skb->head);
@@@ -381,7 -381,7 +381,7 @@@ static void kfree_skbmem(struct sk_buf
  
  static void skb_release_head_state(struct sk_buff *skb)
  {
 -      dst_release(skb->dst);
 +      skb_dst_drop(skb);
  #ifdef CONFIG_XFRM
        secpath_put(skb->sp);
  #endif
@@@ -503,7 -503,7 +503,7 @@@ int skb_recycle_check(struct sk_buff *s
        shinfo->gso_type = 0;
        shinfo->ip6_frag_id = 0;
        shinfo->tx_flags.flags = 0;
 -      shinfo->frag_list = NULL;
 +      skb_frag_list_init(skb);
        memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps));
  
        memset(skb, 0, offsetof(struct sk_buff, tail));
@@@ -521,12 -521,13 +521,12 @@@ static void __copy_skb_header(struct sk
        new->transport_header   = old->transport_header;
        new->network_header     = old->network_header;
        new->mac_header         = old->mac_header;
 -      new->dst                = dst_clone(old->dst);
 +      skb_dst_set(new, dst_clone(skb_dst(old)));
  #ifdef CONFIG_XFRM
        new->sp                 = secpath_get(old->sp);
  #endif
        memcpy(new->cb, old->cb, sizeof(old->cb));
 -      new->csum_start         = old->csum_start;
 -      new->csum_offset        = old->csum_offset;
 +      new->csum               = old->csum;
        new->local_df           = old->local_df;
        new->pkt_type           = old->pkt_type;
        new->ip_summed          = old->ip_summed;
  #endif
        new->protocol           = old->protocol;
        new->mark               = old->mark;
 +      new->iif                = old->iif;
        __nf_copy(new, old);
  #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
      defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
  #endif
  #endif
        new->vlan_tci           = old->vlan_tci;
 +#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
 +      new->do_not_encrypt     = old->do_not_encrypt;
 +#endif
  
        skb_copy_secmark(new, old);
  }
  
 +/*
 + * You should not add any new code to this function.  Add it to
 + * __copy_skb_header above instead.
 + */
  static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
  {
  #define C(x) n->x = skb->x
        n->cloned = 1;
        n->nohdr = 0;
        n->destructor = NULL;
 -      C(iif);
        C(tail);
        C(end);
        C(head);
        C(data);
        C(truesize);
 -#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
 -      C(do_not_encrypt);
 -      C(requeue);
 -#endif
        atomic_set(&n->users, 1);
  
        atomic_inc(&(skb_shinfo(skb)->dataref));
@@@ -757,7 -755,7 +757,7 @@@ struct sk_buff *pskb_copy(struct sk_buf
                skb_shinfo(n)->nr_frags = i;
        }
  
 -      if (skb_shinfo(skb)->frag_list) {
 +      if (skb_has_frags(skb)) {
                skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list;
                skb_clone_fraglist(n);
        }
@@@ -820,7 -818,7 +820,7 @@@ int pskb_expand_head(struct sk_buff *sk
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
                get_page(skb_shinfo(skb)->frags[i].page);
  
 -      if (skb_shinfo(skb)->frag_list)
 +      if (skb_has_frags(skb))
                skb_clone_fraglist(skb);
  
        skb_release_data(skb);
@@@ -1092,7 -1090,7 +1092,7 @@@ drop_pages
                for (; i < nfrags; i++)
                        put_page(skb_shinfo(skb)->frags[i].page);
  
 -              if (skb_shinfo(skb)->frag_list)
 +              if (skb_has_frags(skb))
                        skb_drop_fraglist(skb);
                goto done;
        }
@@@ -1187,7 -1185,7 +1187,7 @@@ unsigned char *__pskb_pull_tail(struct 
        /* Optimization: no fragments, no reasons to preestimate
         * size of pulled pages. Superb.
         */
 -      if (!skb_shinfo(skb)->frag_list)
 +      if (!skb_has_frags(skb))
                goto pull_pages;
  
        /* Estimate size of pulled pages. */
@@@ -1284,9 -1282,8 +1284,9 @@@ EXPORT_SYMBOL(__pskb_pull_tail)
  
  int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
  {
 -      int i, copy;
        int start = skb_headlen(skb);
 +      struct sk_buff *frag_iter;
 +      int i, copy;
  
        if (offset > (int)skb->len - len)
                goto fault;
                start = end;
        }
  
 -      if (skb_shinfo(skb)->frag_list) {
 -              struct sk_buff *list = skb_shinfo(skb)->frag_list;
 +      skb_walk_frags(skb, frag_iter) {
 +              int end;
  
 -              for (; list; list = list->next) {
 -                      int end;
 -
 -                      WARN_ON(start > offset + len);
 -
 -                      end = start + list->len;
 -                      if ((copy = end - offset) > 0) {
 -                              if (copy > len)
 -                                      copy = len;
 -                              if (skb_copy_bits(list, offset - start,
 -                                                to, copy))
 -                                      goto fault;
 -                              if ((len -= copy) == 0)
 -                                      return 0;
 -                              offset += copy;
 -                              to     += copy;
 -                      }
 -                      start = end;
 +              WARN_ON(start > offset + len);
 +
 +              end = start + frag_iter->len;
 +              if ((copy = end - offset) > 0) {
 +                      if (copy > len)
 +                              copy = len;
 +                      if (skb_copy_bits(frag_iter, offset - start, to, copy))
 +                              goto fault;
 +                      if ((len -= copy) == 0)
 +                              return 0;
 +                      offset += copy;
 +                      to     += copy;
                }
 +              start = end;
        }
        if (!len)
                return 0;
@@@ -1529,7 -1531,6 +1529,7 @@@ int skb_splice_bits(struct sk_buff *skb
                .ops = &sock_pipe_buf_ops,
                .spd_release = sock_spd_release,
        };
 +      struct sk_buff *frag_iter;
        struct sock *sk = skb->sk;
  
        /*
        /*
         * now see if we have a frag_list to map
         */
 -      if (skb_shinfo(skb)->frag_list) {
 -              struct sk_buff *list = skb_shinfo(skb)->frag_list;
 -
 -              for (; list && tlen; list = list->next) {
 -                      if (__skb_splice_bits(list, &offset, &tlen, &spd, sk))
 -                              break;
 -              }
 +      skb_walk_frags(skb, frag_iter) {
 +              if (!tlen)
 +                      break;
 +              if (__skb_splice_bits(frag_iter, &offset, &tlen, &spd, sk))
 +                      break;
        }
  
  done:
  
  int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len)
  {
 -      int i, copy;
        int start = skb_headlen(skb);
 +      struct sk_buff *frag_iter;
 +      int i, copy;
  
        if (offset > (int)skb->len - len)
                goto fault;
                start = end;
        }
  
 -      if (skb_shinfo(skb)->frag_list) {
 -              struct sk_buff *list = skb_shinfo(skb)->frag_list;
 +      skb_walk_frags(skb, frag_iter) {
 +              int end;
  
 -              for (; list; list = list->next) {
 -                      int end;
 -
 -                      WARN_ON(start > offset + len);
 -
 -                      end = start + list->len;
 -                      if ((copy = end - offset) > 0) {
 -                              if (copy > len)
 -                                      copy = len;
 -                              if (skb_store_bits(list, offset - start,
 -                                                 from, copy))
 -                                      goto fault;
 -                              if ((len -= copy) == 0)
 -                                      return 0;
 -                              offset += copy;
 -                              from += copy;
 -                      }
 -                      start = end;
 +              WARN_ON(start > offset + len);
 +
 +              end = start + frag_iter->len;
 +              if ((copy = end - offset) > 0) {
 +                      if (copy > len)
 +                              copy = len;
 +                      if (skb_store_bits(frag_iter, offset - start,
 +                                         from, copy))
 +                              goto fault;
 +                      if ((len -= copy) == 0)
 +                              return 0;
 +                      offset += copy;
 +                      from += copy;
                }
 +              start = end;
        }
        if (!len)
                return 0;
@@@ -1664,7 -1670,6 +1664,7 @@@ __wsum skb_checksum(const struct sk_buf
  {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
 +      struct sk_buff *frag_iter;
        int pos = 0;
  
        /* Checksum header. */
                start = end;
        }
  
 -      if (skb_shinfo(skb)->frag_list) {
 -              struct sk_buff *list = skb_shinfo(skb)->frag_list;
 +      skb_walk_frags(skb, frag_iter) {
 +              int end;
  
 -              for (; list; list = list->next) {
 -                      int end;
 -
 -                      WARN_ON(start > offset + len);
 -
 -                      end = start + list->len;
 -                      if ((copy = end - offset) > 0) {
 -                              __wsum csum2;
 -                              if (copy > len)
 -                                      copy = len;
 -                              csum2 = skb_checksum(list, offset - start,
 -                                                   copy, 0);
 -                              csum = csum_block_add(csum, csum2, pos);
 -                              if ((len -= copy) == 0)
 -                                      return csum;
 -                              offset += copy;
 -                              pos    += copy;
 -                      }
 -                      start = end;
 +              WARN_ON(start > offset + len);
 +
 +              end = start + frag_iter->len;
 +              if ((copy = end - offset) > 0) {
 +                      __wsum csum2;
 +                      if (copy > len)
 +                              copy = len;
 +                      csum2 = skb_checksum(frag_iter, offset - start,
 +                                           copy, 0);
 +                      csum = csum_block_add(csum, csum2, pos);
 +                      if ((len -= copy) == 0)
 +                              return csum;
 +                      offset += copy;
 +                      pos    += copy;
                }
 +              start = end;
        }
        BUG_ON(len);
  
@@@ -1737,7 -1746,6 +1737,7 @@@ __wsum skb_copy_and_csum_bits(const str
  {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
 +      struct sk_buff *frag_iter;
        int pos = 0;
  
        /* Copy header. */
                start = end;
        }
  
 -      if (skb_shinfo(skb)->frag_list) {
 -              struct sk_buff *list = skb_shinfo(skb)->frag_list;
 +      skb_walk_frags(skb, frag_iter) {
 +              __wsum csum2;
 +              int end;
  
 -              for (; list; list = list->next) {
 -                      __wsum csum2;
 -                      int end;
 -
 -                      WARN_ON(start > offset + len);
 -
 -                      end = start + list->len;
 -                      if ((copy = end - offset) > 0) {
 -                              if (copy > len)
 -                                      copy = len;
 -                              csum2 = skb_copy_and_csum_bits(list,
 -                                                             offset - start,
 -                                                             to, copy, 0);
 -                              csum = csum_block_add(csum, csum2, pos);
 -                              if ((len -= copy) == 0)
 -                                      return csum;
 -                              offset += copy;
 -                              to     += copy;
 -                              pos    += copy;
 -                      }
 -                      start = end;
 +              WARN_ON(start > offset + len);
 +
 +              end = start + frag_iter->len;
 +              if ((copy = end - offset) > 0) {
 +                      if (copy > len)
 +                              copy = len;
 +                      csum2 = skb_copy_and_csum_bits(frag_iter,
 +                                                     offset - start,
 +                                                     to, copy, 0);
 +                      csum = csum_block_add(csum, csum2, pos);
 +                      if ((len -= copy) == 0)
 +                              return csum;
 +                      offset += copy;
 +                      to     += copy;
 +                      pos    += copy;
                }
 +              start = end;
        }
        BUG_ON(len);
        return csum;
@@@ -2312,7 -2324,8 +2312,7 @@@ next_skb
                st->frag_data = NULL;
        }
  
 -      if (st->root_skb == st->cur_skb &&
 -          skb_shinfo(st->root_skb)->frag_list) {
 +      if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) {
                st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
                st->frag_idx = 0;
                goto next_skb;
@@@ -2623,7 -2636,7 +2623,7 @@@ struct sk_buff *skb_segment(struct sk_b
                        } else
                                skb_get(fskb2);
  
 -                      BUG_ON(skb_shinfo(nskb)->frag_list);
 +                      SKB_FRAG_ASSERT(nskb);
                        skb_shinfo(nskb)->frag_list = fskb2;
                }
  
@@@ -2648,40 -2661,30 +2648,40 @@@ int skb_gro_receive(struct sk_buff **he
  {
        struct sk_buff *p = *head;
        struct sk_buff *nskb;
 +      struct skb_shared_info *skbinfo = skb_shinfo(skb);
 +      struct skb_shared_info *pinfo = skb_shinfo(p);
        unsigned int headroom;
        unsigned int len = skb_gro_len(skb);
 +      unsigned int offset = skb_gro_offset(skb);
 +      unsigned int headlen = skb_headlen(skb);
  
        if (p->len + len >= 65536)
                return -E2BIG;
  
 -      if (skb_shinfo(p)->frag_list)
 +      if (pinfo->frag_list)
                goto merge;
 -      else if (skb_headlen(skb) <= skb_gro_offset(skb)) {
 -              if (skb_shinfo(p)->nr_frags + skb_shinfo(skb)->nr_frags >
 -                  MAX_SKB_FRAGS)
 +      else if (headlen <= offset) {
 +              skb_frag_t *frag;
 +              skb_frag_t *frag2;
 +              int i = skbinfo->nr_frags;
 +              int nr_frags = pinfo->nr_frags + i;
 +
 +              offset -= headlen;
 +
 +              if (nr_frags > MAX_SKB_FRAGS)
                        return -E2BIG;
  
 -              skb_shinfo(skb)->frags[0].page_offset +=
 -                      skb_gro_offset(skb) - skb_headlen(skb);
 -              skb_shinfo(skb)->frags[0].size -=
 -                      skb_gro_offset(skb) - skb_headlen(skb);
 +              pinfo->nr_frags = nr_frags;
 +              skbinfo->nr_frags = 0;
  
 -              memcpy(skb_shinfo(p)->frags + skb_shinfo(p)->nr_frags,
 -                     skb_shinfo(skb)->frags,
 -                     skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t));
 +              frag = pinfo->frags + nr_frags;
 +              frag2 = skbinfo->frags + i;
 +              do {
 +                      *--frag = *--frag2;
 +              } while (--i);
  
 -              skb_shinfo(p)->nr_frags += skb_shinfo(skb)->nr_frags;
 -              skb_shinfo(skb)->nr_frags = 0;
 +              frag->page_offset += offset;
 +              frag->size -= offset;
  
                skb->truesize -= skb->data_len;
                skb->len -= skb->data_len;
  
        *NAPI_GRO_CB(nskb) = *NAPI_GRO_CB(p);
        skb_shinfo(nskb)->frag_list = p;
 -      skb_shinfo(nskb)->gso_size = skb_shinfo(p)->gso_size;
 +      skb_shinfo(nskb)->gso_size = pinfo->gso_size;
        skb_header_release(p);
        nskb->prev = p;
  
        p = nskb;
  
  merge:
 -      if (skb_gro_offset(skb) > skb_headlen(skb)) {
 -              skb_shinfo(skb)->frags[0].page_offset +=
 -                      skb_gro_offset(skb) - skb_headlen(skb);
 -              skb_shinfo(skb)->frags[0].size -=
 -                      skb_gro_offset(skb) - skb_headlen(skb);
 -              skb_gro_reset_offset(skb);
 -              skb_gro_pull(skb, skb_headlen(skb));
 +      if (offset > headlen) {
 +              skbinfo->frags[0].page_offset += offset - headlen;
 +              skbinfo->frags[0].size -= offset - headlen;
 +              offset = headlen;
        }
  
 -      __skb_pull(skb, skb_gro_offset(skb));
 +      __skb_pull(skb, offset);
  
        p->prev->next = skb;
        p->prev = skb;
@@@ -2780,7 -2786,6 +2780,7 @@@ __skb_to_sgvec(struct sk_buff *skb, str
  {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
 +      struct sk_buff *frag_iter;
        int elt = 0;
  
        if (copy > 0) {
                start = end;
        }
  
 -      if (skb_shinfo(skb)->frag_list) {
 -              struct sk_buff *list = skb_shinfo(skb)->frag_list;
 -
 -              for (; list; list = list->next) {
 -                      int end;
 +      skb_walk_frags(skb, frag_iter) {
 +              int end;
  
 -                      WARN_ON(start > offset + len);
 +              WARN_ON(start > offset + len);
  
 -                      end = start + list->len;
 -                      if ((copy = end - offset) > 0) {
 -                              if (copy > len)
 -                                      copy = len;
 -                              elt += __skb_to_sgvec(list, sg+elt, offset - start,
 -                                                    copy);
 -                              if ((len -= copy) == 0)
 -                                      return elt;
 -                              offset += copy;
 -                      }
 -                      start = end;
 +              end = start + frag_iter->len;
 +              if ((copy = end - offset) > 0) {
 +                      if (copy > len)
 +                              copy = len;
 +                      elt += __skb_to_sgvec(frag_iter, sg+elt, offset - start,
 +                                            copy);
 +                      if ((len -= copy) == 0)
 +                              return elt;
 +                      offset += copy;
                }
 +              start = end;
        }
        BUG_ON(len);
        return elt;
@@@ -2877,7 -2886,7 +2877,7 @@@ int skb_cow_data(struct sk_buff *skb, i
                return -ENOMEM;
  
        /* Easy case. Most of packets will go this way. */
 -      if (!skb_shinfo(skb)->frag_list) {
 +      if (!skb_has_frags(skb)) {
                /* A little of trouble, not enough of space for trailer.
                 * This should not happen, when stack is tuned to generate
                 * good frames. OK, on miss we reallocate and reserve even more
  
                if (skb1->next == NULL && tailbits) {
                        if (skb_shinfo(skb1)->nr_frags ||
 -                          skb_shinfo(skb1)->frag_list ||
 +                          skb_has_frags(skb1) ||
                            skb_tailroom(skb1) < tailbits)
                                ntail = tailbits + 128;
                }
                    skb_cloned(skb1) ||
                    ntail ||
                    skb_shinfo(skb1)->nr_frags ||
 -                  skb_shinfo(skb1)->frag_list) {
 +                  skb_has_frags(skb1)) {
                        struct sk_buff *skb2;
  
                        /* Fuck, we are miserable poor guys... */
@@@ -3007,12 -3016,12 +3007,12 @@@ EXPORT_SYMBOL_GPL(skb_tstamp_tx)
   */
  bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off)
  {
 -      if (unlikely(start > skb->len - 2) ||
 -          unlikely((int)start + off > skb->len - 2)) {
 +      if (unlikely(start > skb_headlen(skb)) ||
 +          unlikely((int)start + off > skb_headlen(skb) - 2)) {
                if (net_ratelimit())
                        printk(KERN_WARNING
                               "bad partial csum: csum=%u/%u len=%u\n",
 -                             start, off, skb->len);
 +                             start, off, skb_headlen(skb));
                return false;
        }
        skb->ip_summed = CHECKSUM_PARTIAL;
diff --combined net/ipv6/addrconf.c
index c3488372f12d3d74d5da86871998411e03d7ecfd,597487ae6ce8fbe7a0d34ae5eb4a169d30506d19..8c1e86afbbf5208c4eeadee48ce407dbf3b0016f
@@@ -503,7 -503,7 +503,7 @@@ static int addrconf_fixup_forwarding(st
                return 0;
  
        if (!rtnl_trylock())
 -              return -ERESTARTSYS;
 +              return restart_syscall();
  
        if (p == &net->ipv6.devconf_all->forwarding) {
                __s32 newf = net->ipv6.devconf_all->forwarding;
@@@ -591,6 -591,7 +591,6 @@@ ipv6_add_addr(struct inet6_dev *idev, c
  {
        struct inet6_ifaddr *ifa = NULL;
        struct rt6_info *rt;
 -      struct net *net = dev_net(idev->dev);
        int hash;
        int err = 0;
        int addr_type = ipv6_addr_type(addr);
                goto out2;
        }
  
 -      if (idev->cnf.disable_ipv6 || net->ipv6.devconf_all->disable_ipv6) {
 +      if (idev->cnf.disable_ipv6) {
                err = -EACCES;
                goto out2;
        }
@@@ -1519,8 -1520,6 +1519,8 @@@ static int addrconf_ifid_infiniband(u8 
  
  int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
  {
 +      if (addr == 0)
 +              return -1;
        eui[0] = (ipv4_is_zeronet(addr) || ipv4_is_private_10(addr) ||
                  ipv4_is_loopback(addr) || ipv4_is_linklocal_169(addr) ||
                  ipv4_is_private_172(addr) || ipv4_is_test_192(addr) ||
@@@ -1751,7 -1750,6 +1751,7 @@@ void addrconf_prefix_rcv(struct net_dev
        __u32 prefered_lft;
        int addr_type;
        struct inet6_dev *in6_dev;
 +      struct net *net = dev_net(dev);
  
        pinfo = (struct prefix_info *) opt;
  
                if (addrconf_finite_timeout(rt_expires))
                        rt_expires *= HZ;
  
 -              rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL,
 +              rt = rt6_lookup(net, &pinfo->prefix, NULL,
                                dev->ifindex, 1);
  
                if (rt && addrconf_is_prefix_route(rt)) {
                struct inet6_ifaddr * ifp;
                struct in6_addr addr;
                int create = 0, update_lft = 0;
 -              struct net *net = dev_net(dev);
  
                if (pinfo->prefix_len == 64) {
                        memcpy(&addr, &pinfo->prefix, 8);
@@@ -2766,7 -2765,7 +2766,7 @@@ static void addrconf_dad_start(struct i
                spin_unlock_bh(&ifp->lock);
                read_unlock_bh(&idev->lock);
                /*
-                * If the defice is not ready:
+                * If the device is not ready:
                 * - keep it tentative if it is a permanent address.
                 * - otherwise, kill it.
                 */
@@@ -3987,75 -3986,6 +3987,75 @@@ static int addrconf_sysctl_forward_stra
        return addrconf_fixup_forwarding(table, valp, val);
  }
  
 +static void dev_disable_change(struct inet6_dev *idev)
 +{
 +      if (!idev || !idev->dev)
 +              return;
 +
 +      if (idev->cnf.disable_ipv6)
 +              addrconf_notify(NULL, NETDEV_DOWN, idev->dev);
 +      else
 +              addrconf_notify(NULL, NETDEV_UP, idev->dev);
 +}
 +
 +static void addrconf_disable_change(struct net *net, __s32 newf)
 +{
 +      struct net_device *dev;
 +      struct inet6_dev *idev;
 +
 +      read_lock(&dev_base_lock);
 +      for_each_netdev(net, dev) {
 +              rcu_read_lock();
 +              idev = __in6_dev_get(dev);
 +              if (idev) {
 +                      int changed = (!idev->cnf.disable_ipv6) ^ (!newf);
 +                      idev->cnf.disable_ipv6 = newf;
 +                      if (changed)
 +                              dev_disable_change(idev);
 +              }
 +              rcu_read_unlock();
 +      }
 +      read_unlock(&dev_base_lock);
 +}
 +
 +static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
 +{
 +      struct net *net;
 +
 +      net = (struct net *)table->extra2;
 +
 +      if (p == &net->ipv6.devconf_dflt->disable_ipv6)
 +              return 0;
 +
 +      if (!rtnl_trylock())
 +              return restart_syscall();
 +
 +      if (p == &net->ipv6.devconf_all->disable_ipv6) {
 +              __s32 newf = net->ipv6.devconf_all->disable_ipv6;
 +              net->ipv6.devconf_dflt->disable_ipv6 = newf;
 +              addrconf_disable_change(net, newf);
 +      } else if ((!*p) ^ (!old))
 +              dev_disable_change((struct inet6_dev *)table->extra1);
 +
 +      rtnl_unlock();
 +      return 0;
 +}
 +
 +static
 +int addrconf_sysctl_disable(ctl_table *ctl, int write, struct file * filp,
 +                          void __user *buffer, size_t *lenp, loff_t *ppos)
 +{
 +      int *valp = ctl->data;
 +      int val = *valp;
 +      int ret;
 +
 +      ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
 +
 +      if (write)
 +              ret = addrconf_disable_ipv6(ctl, valp, val);
 +      return ret;
 +}
 +
  static struct addrconf_sysctl_table
  {
        struct ctl_table_header *sysctl_header;
                        .data           =       &ipv6_devconf.disable_ipv6,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
 -                      .proc_handler   =       proc_dointvec,
 +                      .proc_handler   =       addrconf_sysctl_disable,
 +                      .strategy       =       sysctl_intvec,
                },
                {
                        .ctl_name       =       CTL_UNNUMBERED,
@@@ -4415,10 -4344,6 +4415,10 @@@ static int addrconf_init_net(struct ne
                dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
                if (dflt == NULL)
                        goto err_alloc_dflt;
 +      } else {
 +              /* these will be inherited by all namespaces */
 +              dflt->autoconf = ipv6_defaults.autoconf;
 +              dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
        }
  
        net->ipv6.devconf_all = all;
diff --combined net/netfilter/Kconfig
index 79ba47f042c0f40614c5f7302fd997c7de70ff7b,c26a20c58dde1bbf256fc074a5bfb80c1ad7f2d9..634d14affc8d03684405b5b979952aa4d57c7f5d
@@@ -327,7 -327,7 +327,7 @@@ config NETFILTER_XT_TARGET_CONNMAR
  
          If you want to compile it as a module, say M here and read
          <file:Documentation/kbuild/modules.txt>.  The module will be called
-         ipt_CONNMARK.ko.  If unsure, say `N'.
+         ipt_CONNMARK.  If unsure, say `N'.
  
  config NETFILTER_XT_TARGET_CONNSECMARK
        tristate '"CONNSECMARK" target support'
@@@ -584,7 -584,7 +584,7 @@@ config NETFILTER_XT_MATCH_CONNMAR
  
          If you want to compile it as a module, say M here and read
          <file:Documentation/kbuild/modules.txt>.  The module will be called
-         ipt_connmark.ko.  If unsure, say `N'.
+         ipt_connmark.  If unsure, say `N'.
  
  config NETFILTER_XT_MATCH_CONNTRACK
        tristate '"conntrack" connection tracking match support'
@@@ -917,19 -917,6 +917,19 @@@ config NETFILTER_XT_MATCH_U3
  
          Details and examples are in the kernel module source.
  
 +config NETFILTER_XT_MATCH_OSF
 +      tristate '"osf" Passive OS fingerprint match'
 +      depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
 +      help
 +        This option selects the Passive OS Fingerprinting match module
 +        that allows to passively match the remote operating system by
 +        analyzing incoming TCP SYN packets.
 +
 +        Rules and loading software can be downloaded from
 +        http://www.ioremap.net/projects/osf
 +
 +        To compile it as a module, choose M here.  If unsure, say N.
 +
  endif # NETFILTER_XTABLES
  
  endmenu
diff --combined net/sched/cls_cgroup.c
index 0f815cc6a3dba491b0caee43abb44af613bc890e,e5becb92b3e7b0f17d43b3342a4621e51e162b4f..e4877ca6727c4b098ef1b6f08163fd7702d3eea2
@@@ -62,7 -62,13 +62,7 @@@ static u64 read_classid(struct cgroup *
  
  static int write_classid(struct cgroup *cgrp, struct cftype *cft, u64 value)
  {
 -      if (!cgroup_lock_live_group(cgrp))
 -              return -ENODEV;
 -
        cgrp_cls_state(cgrp)->classid = (u32) value;
 -
 -      cgroup_unlock();
 -
        return 0;
  }
  
@@@ -161,6 -167,9 +161,9 @@@ static int cls_cgroup_change(struct tcf
        struct tcf_exts e;
        int err;
  
+       if (!tca[TCA_OPTIONS])
+               return -EINVAL;
        if (head == NULL) {
                if (!handle)
                        return -EINVAL;
diff --combined security/selinux/hooks.c
index 4bfc6153ad4f8a49f4a4d7fef443d9dab808e814,195906bce2663f09e4fb65c4e39edb2cd20d0d33..15c2a08a66f1217e92028a38e861ad4981ab3fdd
@@@ -1980,10 -1980,6 +1980,6 @@@ static int selinux_sysctl(ctl_table *ta
        u32 tsid, sid;
        int rc;
  
-       rc = secondary_ops->sysctl(table, op);
-       if (rc)
-               return rc;
        sid = current_sid();
  
        rc = selinux_sysctl_get_sid(table, (op == 0001) ?
@@@ -2375,10 -2371,8 +2371,8 @@@ static void selinux_bprm_committed_cred
  {
        const struct task_security_struct *tsec = current_security();
        struct itimerval itimer;
-       struct sighand_struct *psig;
        u32 osid, sid;
        int rc, i;
-       unsigned long flags;
  
        osid = tsec->osid;
        sid = tsec->sid;
                memset(&itimer, 0, sizeof itimer);
                for (i = 0; i < 3; i++)
                        do_setitimer(i, &itimer, NULL);
-               flush_signals(current);
                spin_lock_irq(&current->sighand->siglock);
-               flush_signal_handlers(current, 1);
-               sigemptyset(&current->blocked);
-               recalc_sigpending();
+               if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
+                       __flush_signals(current);
+                       flush_signal_handlers(current, 1);
+                       sigemptyset(&current->blocked);
+               }
                spin_unlock_irq(&current->sighand->siglock);
        }
  
        /* Wake up the parent if it is waiting so that it can recheck
         * wait permission to the new task SID. */
-       read_lock_irq(&tasklist_lock);
-       psig = current->parent->sighand;
-       spin_lock_irqsave(&psig->siglock, flags);
-       wake_up_interruptible(&current->parent->signal->wait_chldexit);
-       spin_unlock_irqrestore(&psig->siglock, flags);
-       read_unlock_irq(&tasklist_lock);
+       read_lock(&tasklist_lock);
+       wake_up_interruptible(&current->real_parent->signal->wait_chldexit);
+       read_unlock(&tasklist_lock);
  }
  
  /* superblock security operations */
@@@ -4503,7 -4495,7 +4495,7 @@@ static unsigned int selinux_ip_postrout
         * when the packet is on it's final way out.
         * NOTE: there appear to be some IPv6 multicast cases where skb->dst
         *       is NULL, in this case go ahead and apply access control. */
 -      if (skb->dst != NULL && skb->dst->xfrm != NULL)
 +      if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL)
                return NF_ACCEPT;
  #endif
        secmark_active = selinux_secmark_enabled();