]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorDavid S. Miller <davem@davemloft.net>
Thu, 19 Nov 2009 06:19:03 +0000 (22:19 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 19 Nov 2009 06:19:03 +0000 (22:19 -0800)
Conflicts:
drivers/net/sfc/sfe4001.c
drivers/net/wireless/libertas/cmd.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/rtl8187se/Kconfig
drivers/staging/rtl8192e/Kconfig

47 files changed:
1  2 
Documentation/kernel-parameters.txt
MAINTAINERS
arch/blackfin/mach-common/entry.S
arch/mips/kernel/scall64-o32.S
arch/x86/ia32/ia32entry.S
drivers/net/bonding/bond_sysfs.c
drivers/net/cxgb3/sge.c
drivers/net/e100.c
drivers/net/ethoc.c
drivers/net/hamachi.c
drivers/net/hamradio/baycom_epp.c
drivers/net/igb/igb_ethtool.c
drivers/net/sfc/falcon_boards.c
drivers/net/skge.c
drivers/net/slip.c
drivers/net/sungem.c
drivers/net/typhoon.c
drivers/net/virtio_net.c
drivers/net/wan/cosa.c
drivers/net/wan/dscc4.c
drivers/net/wireless/b43/pio.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-hcmd.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwmc3200wifi/cfg80211.c
drivers/net/wireless/iwmc3200wifi/commands.c
drivers/net/wireless/iwmc3200wifi/main.c
drivers/net/wireless/iwmc3200wifi/rx.c
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/prism54/islpci_dev.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/rt2x00/rt2x00debug.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/rtl8187se/Kconfig
drivers/staging/rtl8192e/Kconfig
fs/compat_ioctl.c
net/8021q/vlan.c
net/core/skbuff.c
net/wireless/core.c

index 02df20be7764e0bf076f5fff1d532e27126bdf49,9107b387e91fce095ee320dbeed53d5dfe5cb332..52c34b4f567ea4b3bcacbd20fdbb2730206fccce
@@@ -671,6 -671,7 +671,7 @@@ and is between 256 and 4096 characters
        earlyprintk=    [X86,SH,BLACKFIN]
                        earlyprintk=vga
                        earlyprintk=serial[,ttySn[,baudrate]]
+                       earlyprintk=ttySn[,baudrate]
                        earlyprintk=dbgp[debugController#]
  
                        Append ",keep" to not disable it when the real console
        uart6850=       [HW,OSS]
                        Format: <io>,<irq>
  
 +      uhash_entries=  [KNL,NET]
 +                      Set number of hash buckets for UDP/UDP-Lite connections
 +
        uhci-hcd.ignore_oc=
                        [USB] Ignore overcurrent events (default N).
                        Some badly-designed motherboards generate lots of
diff --combined MAINTAINERS
index b2e3f3507ca3042673c831f942876cb008b9cad3,c824b4d62754ddf04e3feae871d43dff77954c28..808e4dfb34be88164e58b63ddd87fc2cd95b28a3
@@@ -65,43 -65,51 +65,51 @@@ trivial patch so apply some common sens
  
  8.    Happy hacking.
  
-               -----------------------------------
- Maintainers List (try to look for most precise areas first)
+ Descriptions of section entries:
+       P: Person (obsolete)
+       M: Mail patches to: FullName <address@domain>
+       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, stgit.
+       S: Status, one of the following:
+          Supported:   Someone is actually paid to look after this.
+          Maintained:  Someone actually looks after it.
+          Odd Fixes:   It has a maintainer but they don't have time to do
+                       much other than throw the odd patch in. See below..
+          Orphan:      No current maintainer [but maybe you could take the
+                       role as you write your new code].
+          Obsolete:    Old code. Something tagged obsolete generally means
+                       it has been replaced by a better system and you
+                       should be using that.
+       F: Files and directories with wildcard patterns.
+          A trailing slash includes all files and subdirectory files.
+          F:   drivers/net/    all files in and below drivers/net
+          F:   drivers/net/*   all files in drivers/net, but not below
+          F:   */net/*         all files in "any top level directory"/net
+          One pattern per line.  Multiple F: lines acceptable.
+       X: Files and directories that are NOT maintained, same rules as F:
+          Files exclusions are tested before file matches.
+          Can be useful for excluding a specific subdirectory, for instance:
+          F:   net/
+          X:   net/ipv6/
+          matches all files in and below net excluding net/ipv6/
+       K: Keyword perl extended regex pattern to match content in a
+          patch or file.  For instance:
+          K: of_get_profile
+             matches patches or files that contain "of_get_profile"
+          K: \b(printk|pr_(info|err))\b
+             matches patches or files that contain one or more of the words
+             printk, pr_info or pr_err
+          One regex pattern per line.  Multiple K: lines acceptable.
  
  Note: For the hard of thinking, this list is meant to remain in alphabetical
  order. If you could add yourselves to it in alphabetical order that would be
  so much easier [Ed]
  
- P: Person (obsolete)
- M: Mail patches to: FullName <address@domain>
- 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, stgit.
- S: Status, one of the following:
-       Supported:      Someone is actually paid to look after this.
-       Maintained:     Someone actually looks after it.
-       Odd Fixes:      It has a maintainer but they don't have time to do
-                       much other than throw the odd patch in. See below..
-       Orphan:         No current maintainer [but maybe you could take the
-                       role as you write your new code].
-       Obsolete:       Old code. Something tagged obsolete generally means
-                       it has been replaced by a better system and you
-                       should be using that.
+ Maintainers List (try to look for most precise areas first)
  
- F: Files and directories with wildcard patterns.
-    A trailing slash includes all files and subdirectory files.
-       F:      drivers/net/    all files in and below drivers/net
-       F:      drivers/net/*   all files in drivers/net, but not below
-       F:      */net/*         all files in "any top level directory"/net
-    One pattern per line.  Multiple F: lines acceptable.
- X: Files and directories that are NOT maintained, same rules as F:
-    Files exclusions are tested before file matches.
-    Can be useful for excluding a specific subdirectory, for instance:
-       F:      net/
-       X:      net/ipv6/
-    matches all files in and below net excluding net/ipv6/
+               -----------------------------------
  
  3C505 NETWORK DRIVER
  M:    Philip Blundell <philb@gnu.org>
@@@ -174,7 -182,7 +182,7 @@@ M: Ron Minnich <rminnich@sandia.gov
  M:    Latchesar Ionkov <lucho@ionkov.net>
  L:    v9fs-developer@lists.sourceforge.net
  W:    http://swik.net/v9fs
- T:    git git://git.kernel.org/pub/scm/linux/kernel/ericvh/v9fs.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git
  S:    Maintained
  F:    Documentation/filesystems/9p.txt
  F:    fs/9p/
@@@ -577,6 -585,11 +585,11 @@@ M:       Mike Rapoport <mike@compulab.co.il
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  
+ ARM/CONTEC MICRO9 MACHINE SUPPORT
+ M:    Hubert Feurstein <hubert.feurstein@contec.at>
+ S:    Maintained
+ F:    arch/arm/mach-ep93xx/micro9.c
  ARM/CORGI MACHINE SUPPORT
  M:    Richard Purdie <rpurdie@rpsys.net>
  S:    Maintained
@@@ -893,7 -906,6 +906,6 @@@ M: Karol Kozimor <sziwan@users.sourcefo
  L:    acpi4asus-user@lists.sourceforge.net
  W:    http://acpi4asus.sf.net
  S:    Maintained
- F:    arch/x86/kernel/acpi/boot.c
  F:    drivers/platform/x86/asus_acpi.c
  
  ASUS ASB100 HARDWARE MONITOR DRIVER
@@@ -987,7 -999,7 +999,7 @@@ F: drivers/net/atlx
  
  ATM
  M:    Chas Williams <chas@cmf.nrl.navy.mil>
- L:    linux-atm-general@lists.sourceforge.net (subscribers-only)
+ L:    linux-atm-general@lists.sourceforge.net (moderated for non-subscribers)
  L:    netdev@vger.kernel.org
  W:    http://linux-atm.sourceforge.net
  S:    Maintained
@@@ -1086,6 -1098,7 +1098,6 @@@ F:      include/net/ax25.
  F:    net/ax25/
  
  B43 WIRELESS DRIVER
 -M:    Michael Buesch <mb@bu3sch.de>
  M:    Stefano Brivio <stefano.brivio@polimi.it>
  L:    linux-wireless@vger.kernel.org
  W:    http://linuxwireless.org/en/users/Drivers/b43
@@@ -1230,6 -1243,12 +1242,12 @@@ L:    netdev@vger.kernel.or
  S:    Supported
  F:    drivers/net/tg3.*
  
+ BROCADE BFA FC SCSI DRIVER
+ M:    Jing Huang <huangj@brocade.com>
+ L:    linux-scsi@vger.kernel.org
+ S:    Supported
+ F:    drivers/scsi/bfa/
  BSG (block layer generic sg v4 driver)
  M:    FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
  L:    linux-scsi@vger.kernel.org
@@@ -1467,6 -1486,7 +1485,7 @@@ F:      mm/*cgroup
  
  CORETEMP HARDWARE MONITORING DRIVER
  M:    Rudolf Marek <r.marek@assembler.cz>
+ M:    Huaxu Wan <huaxu.wan@intel.com>
  L:    lm-sensors@lm-sensors.org
  S:    Maintained
  F:    Documentation/hwmon/coretemp
@@@ -2057,7 -2077,7 +2076,7 @@@ S:      Maintaine
  F:    fs/*
  
  FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER
- M:    Riku Voipio <riku.vipio@iki.fi>
+ M:    Riku Voipio <riku.voipio@iki.fi>
  L:    lm-sensors@lm-sensors.org
  S:    Maintained
  F:    drivers/hwmon/f75375s.c
@@@ -2138,7 -2158,7 +2157,7 @@@ S:      Supporte
  F:    arch/powerpc/sysdev/qe_lib/
  F:    arch/powerpc/include/asm/*qe.h
  
- FREESCALE USB PERIPHERIAL DRIVERS
+ FREESCALE USB PERIPHERAL DRIVERS
  M:    Li Yang <leoli@freescale.com>
  L:    linux-usb@vger.kernel.org
  L:    linuxppc-dev@ozlabs.org
@@@ -2189,18 -2209,6 +2208,6 @@@ F:     Documentation/filesystems/caching
  F:    fs/fscache/
  F:    include/linux/fscache*.h
  
- TRACING
- M:    Steven Rostedt <rostedt@goodmis.org>
- M:    Frederic Weisbecker <fweisbec@gmail.com>
- M:    Ingo Molnar <mingo@redhat.com>
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git tracing/core
- S:    Maintained
- F:    Documentation/trace/ftrace.txt
- F:    arch/*/*/*/ftrace.h
- F:    arch/*/kernel/ftrace.c
- F:    include/*/ftrace.h include/trace/ include/linux/trace*.h
- F:    kernel/trace/
  FUJITSU FR-V (FRV) PORT
  M:    David Howells <dhowells@redhat.com>
  S:    Maintained
@@@ -2259,9 -2267,8 +2266,8 @@@ S:      Maintaine
  F:    include/asm-generic
  
  GENERIC UIO DRIVER FOR PCI DEVICES
- M:    Michael S. Tsirkin <mst@redhat.com>
+ M:    "Michael S. Tsirkin" <mst@redhat.com>
  L:    kvm@vger.kernel.org
- L:    linux-kernel@vger.kernel.org
  S:    Supported
  F:    drivers/uio/uio_pci_generic.c
  
@@@ -2602,6 -2609,7 +2608,7 @@@ L:      linux1394-devel@lists.sourceforge.ne
  W:    http://www.linux1394.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
  S:    Maintained
+ F:    Documentation/debugging-via-ohci1394.txt
  F:    drivers/ieee1394/
  
  IEEE 1394 RAW I/O DRIVER
@@@ -2815,7 -2823,7 +2822,7 @@@ F:      drivers/infiniband/hw/ipath
  
  IPMI SUBSYSTEM
  M:    Corey Minyard <minyard@acm.org>
- L:    openipmi-developer@lists.sourceforge.net
+ L:    openipmi-developer@lists.sourceforge.net (moderated for non-subscribers)
  W:    http://openipmi.sourceforge.net/
  S:    Supported
  F:    Documentation/IPMI.txt
@@@ -2990,8 -2998,8 +2997,8 @@@ F:      scripts/Makefile.
  
  KERNEL JANITORS
  L:    kernel-janitors@vger.kernel.org
- W:    http://www.kerneljanitors.org/
- S:    Maintained
+ W:    http://janitor.kernelnewbies.org/
+ S:    Odd Fixes
  
  KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
  M:    "J. Bruce Fields" <bfields@fieldses.org>
@@@ -3076,9 -3084,13 +3083,13 @@@ F:    kernel/kgdb.
  
  KMEMCHECK
  M:    Vegard Nossum <vegardno@ifi.uio.no>
- P     Pekka Enberg
- M:    penberg@cs.helsinki.fi
+ M:    Pekka Enberg <penberg@cs.helsinki.fi>
  S:    Maintained
+ F:    Documentation/kmemcheck.txt
+ F:    arch/x86/include/asm/kmemcheck.h
+ F:    arch/x86/mm/kmemcheck/
+ F:    include/linux/kmemcheck.h
+ F:    mm/kmemcheck.c
  
  KMEMLEAK
  M:    Catalin Marinas <catalin.marinas@arm.com>
@@@ -3608,7 -3620,7 +3619,7 @@@ L:      netfilter@vger.kernel.or
  L:    coreteam@netfilter.org
  W:    http://www.netfilter.org/
  W:    http://www.iptables.org/
- T:    git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git
  S:    Supported
  F:    include/linux/netfilter*
  F:    include/linux/netfilter/
@@@ -3704,9 -3716,9 +3715,9 @@@ F:      include/linux/if_
  F:    include/linux/*device.h
  
  NETXEN (1/10) GbE SUPPORT
 -M:    Dhananjay Phadke <dhananjay@netxen.com>
 +M:    Amit Kumar Salecha <amit.salecha@qlogic.com>
  L:    netdev@vger.kernel.org
 -W:    http://www.netxen.com
 +W:    http://www.qlogic.com
  S:    Supported
  F:    drivers/net/netxen/
  
@@@ -3772,7 -3784,7 +3783,7 @@@ F:      drivers/video/riva
  F:    drivers/video/nvidia/
  
  OMAP SUPPORT
- M:    "Tony Lindgren <tony@atomide.com>" <tony@atomide.com>
+ M:    Tony Lindgren <tony@atomide.com>
  L:    linux-omap@vger.kernel.org
  W:    http://www.muru.com/linux/omap/
  W:    http://linux.omap.com/
@@@ -3877,6 -3889,15 +3888,15 @@@ S:    Maintaine
  F:    Documentation/i2c/busses/i2c-ocores
  F:    drivers/i2c/busses/i2c-ocores.c
  
+ OPEN FIRMWARE AND FLATTENED DEVICE TREE
+ M:    Grant Likely <grant.likely@secretlab.ca>
+ L:    devicetree-discuss@lists.ozlabs.org
+ W:    http://fdt.secretlab.ca
+ S:    Maintained
+ F:    drivers/of
+ F:    include/linux/of*.h
+ K:    of_get_property
  OPROFILE
  M:    Robert Richter <robert.richter@amd.com>
  L:    oprofile-list@lists.sf.net
@@@ -3981,6 -4002,7 +4001,7 @@@ F:      drivers/block/paride
  PARISC ARCHITECTURE
  M:    Kyle McMartin <kyle@mcmartin.ca>
  M:    Helge Deller <deller@gmx.de>
+ M:    "James E.J. Bottomley" <jejb@parisc-linux.org>
  L:    linux-parisc@vger.kernel.org
  W:    http://www.parisc-linux.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
@@@ -4064,6 -4086,13 +4085,13 @@@ M:    Peter Zijlstra <a.p.zijlstra@chello.
  M:    Paul Mackerras <paulus@samba.org>
  M:    Ingo Molnar <mingo@elte.hu>
  S:    Supported
+ F:    kernel/perf_event.c
+ F:    include/linux/perf_event.h
+ F:    arch/*/*/kernel/perf_event.c
+ F:    arch/*/include/asm/perf_event.h
+ F:    arch/*/lib/perf_event.c
+ F:    arch/*/kernel/perf_callchain.c
+ F:    tools/perf/
  
  PERSONALITY HANDLING
  M:    Christoph Hellwig <hch@infradead.org>
@@@ -4515,12 -4544,11 +4543,11 @@@ F:   kernel/sched
  F:    include/linux/sched.h
  
  SCORE ARCHITECTURE
- P:    Chen Liqin
- M:    liqin.chen@sunplusct.com
- P:    Lennox Wu
- M:    lennox.wu@gmail.com
+ M:    Chen Liqin <liqin.chen@sunplusct.com>
+ M:    Lennox Wu <lennox.wu@gmail.com>
  W:    http://www.sunplusct.com
  S:    Supported
+ F:    arch/score/
  
  SCSI CDROM DRIVER
  M:    Jens Axboe <axboe@kernel.dk>
@@@ -4593,27 -4621,27 +4620,27 @@@ S:   Maintaine
  F:    drivers/mmc/host/sdricoh_cs.c
  
  SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
- S:     Orphan
- L:     linux-mmc@vger.kernel.org
- F:     drivers/mmc/host/sdhci.*
+ S:    Orphan
+ L:    linux-mmc@vger.kernel.org
+ F:    drivers/mmc/host/sdhci.*
  
  SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
  M:    Anton Vorontsov <avorontsov@ru.mvista.com>
  L:    linuxppc-dev@ozlabs.org
- L:     linux-mmc@vger.kernel.org
+ L:    linux-mmc@vger.kernel.org
  S:    Maintained
- F:     drivers/mmc/host/sdhci-of.*
+ F:    drivers/mmc/host/sdhci-of.*
  
  SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER
  M:    Ben Dooks <ben-linux@fluff.org>
- L:     linux-mmc@vger.kernel.org
+ L:    linux-mmc@vger.kernel.org
  S:    Maintained
  F:    drivers/mmc/host/sdhci-s3c.c
  
  SECURITY SUBSYSTEM
  M:    James Morris <jmorris@namei.org>
  L:    linux-security-module@vger.kernel.org (suggested Cc:)
- T:    git git://www.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
  W:    http://security.wiki.kernel.org/
  S:    Supported
  F:    security/
@@@ -4648,6 -4676,13 +4675,13 @@@ F:    drivers/ata
  F:    include/linux/ata.h
  F:    include/linux/libata.h
  
+ SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER
+ M:    Jayamohan Kallickal <jayamohank@serverengines.com>
+ L:    linux-scsi@vger.kernel.org
+ W:    http://www.serverengines.com
+ S:    Supported
+ F:    drivers/scsi/be2iscsi/
  SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER
  M:    Sathya Perla <sathyap@serverengines.com>
  M:    Subbu Seetharaman <subbus@serverengines.com>
@@@ -4701,8 -4736,7 +4735,7 @@@ F:      drivers/usb/gadget/lh7a40
  F:    drivers/usb/host/ohci-lh7a40*
  
  SIMPLE FIRMWARE INTERFACE (SFI)
- P:    Len Brown
- M:    lenb@kernel.org
+ M:    Len Brown <lenb@kernel.org>
  L:    sfi-devel@simplefirmware.org
  W:    http://simplefirmware.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-sfi-2.6.git
@@@ -5150,6 -5184,20 +5183,20 @@@ L:    tpmdd-devel@lists.sourceforge.net (m
  S:    Maintained
  F:    drivers/char/tpm/
  
+ TRACING
+ M:    Steven Rostedt <rostedt@goodmis.org>
+ M:    Frederic Weisbecker <fweisbec@gmail.com>
+ M:    Ingo Molnar <mingo@redhat.com>
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git tracing/core
+ S:    Maintained
+ F:    Documentation/trace/ftrace.txt
+ F:    arch/*/*/*/ftrace.h
+ F:    arch/*/kernel/ftrace.c
+ F:    include/*/ftrace.h
+ F:    include/linux/trace*.h
+ F:    include/trace/
+ F:    kernel/trace/
  TRIVIAL PATCHES
  M:    Jiri Kosina <trivial@kernel.org>
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git
@@@ -5639,11 -5687,11 +5686,11 @@@ F:   drivers/vlynq/vlynq.
  F:    include/linux/vlynq.h
  
  VMWARE VMXNET3 ETHERNET DRIVER
- M:     Shreyas Bhatewara <sbhatewara@vmware.com>
- M:     VMware, Inc. <pv-drivers@vmware.com>
- L:     netdev@vger.kernel.org
- S:     Maintained
- F:     drivers/net/vmxnet3/
+ M:    Shreyas Bhatewara <sbhatewara@vmware.com>
+ M:    "VMware, Inc." <pv-drivers@vmware.com>
+ L:    netdev@vger.kernel.org
+ S:    Maintained
+ F:    drivers/net/vmxnet3/
  
  VOLTAGE AND CURRENT REGULATOR FRAMEWORK
  M:    Liam Girdwood <lrg@slimlogic.co.uk>
@@@ -5716,8 -5764,7 +5763,7 @@@ S:      Maintaine
  F:    drivers/scsi/wd7000.c
  
  WINBOND CIR DRIVER
- P:    David Härdeman
- M:    david@hardeman.nu
+ M:    David Härdeman <david@hardeman.nu>
  S:    Maintained
  F:    drivers/input/misc/winbond-cir.c
  
@@@ -5774,9 -5821,7 +5820,7 @@@ F:      drivers/input/touchscreen/*wm97
  F:    include/linux/wm97xx.h
  
  WOLFSON MICROELECTRONICS PMIC DRIVERS
- P:    Mark Brown
- M:    broonie@opensource.wolfsonmicro.com
- L:    linux-kernel@vger.kernel.org
+ M:    Mark Brown <broonie@opensource.wolfsonmicro.com>
  T:    git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
  W:    http://opensource.wolfsonmicro.com/node/8
  S:    Supported
index 48692724b74c2a43e56321cfa8a2996a42f6be40,94a0375cbdcf6afd5833e38389fe75fbcb0bc089..a50637a8b9bddb9c468c5615b2a0586f2224e03b
@@@ -1,32 -1,11 +1,11 @@@
  /*
-  * File:         arch/blackfin/mach-common/entry.S
-  * Based on:
-  * Author:       Linus Torvalds
+  * Contains the system-call and fault low-level handling routines.
+  * This also contains the timer-interrupt handler, as well as all
+  * interrupts and faults that can result in a task-switch.
   *
-  * Created:      ?
-  * Description:  contains the system-call and fault low-level handling routines.
-  *               This also contains the timer-interrupt handler, as well as all
-  *               interrupts and faults that can result in a task-switch.
+  * Copyright 2005-2009 Analog Devices Inc.
   *
-  * Modified:
-  *               Copyright 2004-2006 Analog Devices Inc.
-  *
-  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-  * the Free Software Foundation; either version 2 of the License, or
-  * (at your option) any later version.
-  *
-  * This program is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  * GNU General Public License for more details.
-  *
-  * You should have received a copy of the GNU General Public License
-  * along with this program; if not, see the file COPYING, or write
-  * to the Free Software Foundation, Inc.,
-  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+  * Licensed under the GPL-2 or later.
   */
  
  /* NOTE: This code handles signal-recognition, which happens every time
@@@ -1621,7 -1600,6 +1600,7 @@@ ENTRY(_sys_call_table
        .long _sys_pwritev
        .long _sys_rt_tgsigqueueinfo
        .long _sys_perf_event_open
 +      .long _sys_recvmmsg             /* 370 */
  
        .rept NR_syscalls-(.-_sys_call_table)/4
        .long _sys_ni_syscall
index d0eff53d7cb917dc1ea2f9dfa590849f2f9f7ab4,14dde4ca932e287a9ef312f910c68fd87f3efd6d..23b842be83ea0e394fd6ce77fb239d3739e10f6f
@@@ -450,7 -450,7 +450,7 @@@ sys_call_table
        PTR     sys_io_submit
        PTR     sys_io_cancel                   /* 4245 */
        PTR     sys_exit_group
-       PTR     sys_lookup_dcookie
+       PTR     sys32_lookup_dcookie
        PTR     sys_epoll_create
        PTR     sys_epoll_ctl
        PTR     sys_epoll_wait                  /* 4250 */
        PTR     sys_fchmodat
        PTR     sys_faccessat                   /* 4300 */
        PTR     compat_sys_pselect6
-       PTR     sys_ppoll
+       PTR     compat_sys_ppoll
        PTR     sys_unshare
        PTR     sys_splice
        PTR     sys32_sync_file_range           /* 4305 */
        PTR     compat_sys_rt_tgsigqueueinfo
        PTR     sys_perf_event_open
        PTR     sys_accept4
 +      PTR     compat_sys_recvmmsg
        .size   sys_call_table,.-sys_call_table
index 11a6c79d5f46b6b194306ed57b7c4a0f278cc3f2,581b0568fe1941e9cf18c730138b9dbf0ff8c815..d23b987826535185c2abbab1c614b59b6611ec0a
@@@ -21,8 -21,8 +21,8 @@@
  #define __AUDIT_ARCH_LE          0x40000000
  
  #ifndef CONFIG_AUDITSYSCALL
- #define sysexit_audit int_ret_from_sys_call
- #define sysretl_audit int_ret_from_sys_call
+ #define sysexit_audit ia32_ret_from_sys_call
+ #define sysretl_audit ia32_ret_from_sys_call
  #endif
  
  #define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8)
        .endm 
  
        /* clobbers %eax */     
-       .macro  CLEAR_RREGS _r9=rax
+       .macro  CLEAR_RREGS offset=0, _r9=rax
        xorl    %eax,%eax
-       movq    %rax,R11(%rsp)
-       movq    %rax,R10(%rsp)
-       movq    %\_r9,R9(%rsp)
-       movq    %rax,R8(%rsp)
+       movq    %rax,\offset+R11(%rsp)
+       movq    %rax,\offset+R10(%rsp)
+       movq    %\_r9,\offset+R9(%rsp)
+       movq    %rax,\offset+R8(%rsp)
        .endm
  
        /*
@@@ -172,6 -172,10 +172,10 @@@ sysexit_from_sys_call
        movl    RIP-R11(%rsp),%edx              /* User %eip */
        CFI_REGISTER rip,rdx
        RESTORE_ARGS 1,24,1,1,1,1
+       xorq    %r8,%r8
+       xorq    %r9,%r9
+       xorq    %r10,%r10
+       xorq    %r11,%r11
        popfq
        CFI_ADJUST_CFA_OFFSET -8
        /*CFI_RESTORE rflags*/
        movl RDI-ARGOFFSET(%rsp),%r8d   /* reload 5th syscall arg */
        .endm
  
-       .macro auditsys_exit exit,ebpsave=RBP
+       .macro auditsys_exit exit
        testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10)
-       jnz int_ret_from_sys_call
+       jnz ia32_ret_from_sys_call
        TRACE_IRQS_ON
        sti
        movl %eax,%esi          /* second arg, syscall return value */
        call audit_syscall_exit
        GET_THREAD_INFO(%r10)
        movl RAX-ARGOFFSET(%rsp),%eax   /* reload syscall return value */
-       movl \ebpsave-ARGOFFSET(%rsp),%ebp /* reload user register value */
        movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi
        cli
        TRACE_IRQS_OFF
        testl %edi,TI_flags(%r10)
-       jnz int_with_check
-       jmp \exit
+       jz \exit
+       CLEAR_RREGS -ARGOFFSET
+       jmp int_with_check
        .endm
  
  sysenter_auditsys:
@@@ -329,6 -333,9 +333,9 @@@ sysretl_from_sys_call
        CFI_REGISTER rip,rcx
        movl EFLAGS-ARGOFFSET(%rsp),%r11d       
        /*CFI_REGISTER rflags,r11*/
+       xorq    %r10,%r10
+       xorq    %r9,%r9
+       xorq    %r8,%r8
        TRACE_IRQS_ON
        movl RSP-ARGOFFSET(%rsp),%esp
        CFI_RESTORE rsp
@@@ -343,7 -350,7 +350,7 @@@ cstar_auditsys
        jmp cstar_dispatch
  
  sysretl_audit:
-       auditsys_exit sysretl_from_sys_call, RCX /* user %ebp in RCX slot */
+       auditsys_exit sysretl_from_sys_call
  #endif
  
  cstar_tracesys:
  #endif
        xchgl %r9d,%ebp
        SAVE_REST
-       CLEAR_RREGS r9
+       CLEAR_RREGS 0, r9
        movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */
        movq %rsp,%rdi        /* &pt_regs -> arg1 */
        call syscall_trace_enter
@@@ -425,6 -432,8 +432,8 @@@ ia32_do_call
        call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
  ia32_sysret:
        movq %rax,RAX-ARGOFFSET(%rsp)
+ ia32_ret_from_sys_call:
+       CLEAR_RREGS -ARGOFFSET
        jmp int_ret_from_sys_call 
  
  ia32_tracesys:                         
@@@ -442,8 -451,8 +451,8 @@@ END(ia32_syscall
  
  ia32_badsys:
        movq $0,ORIG_RAX-ARGOFFSET(%rsp)
-       movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
-       jmp int_ret_from_sys_call
+       movq $-ENOSYS,%rax
+       jmp ia32_sysret
  
  quiet_ni_syscall:
        movq $-ENOSYS,%rax
@@@ -832,5 -841,4 +841,5 @@@ ia32_sys_call_table
        .quad compat_sys_pwritev
        .quad compat_sys_rt_tgsigqueueinfo      /* 335 */
        .quad sys_perf_event_open
 +      .quad compat_sys_recvmmsg
  ia32_syscall_end:
index a59094f8bb6b501a4b977df0fa799886ad67d45f,8762a27a2a185dd37d47db0263fcc019f471b1da..4e00b4f836411eabb4fcc41959c5415bc9bcb13d
@@@ -22,6 -22,7 +22,7 @@@
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/device.h>
+ #include <linux/sched.h>
  #include <linux/sysdev.h>
  #include <linux/fs.h>
  #include <linux/types.h>
@@@ -35,8 -36,6 +36,8 @@@
  #include <linux/rtnetlink.h>
  #include <linux/etherdevice.h>
  #include <net/net_namespace.h>
 +#include <net/netns/generic.h>
 +#include <linux/nsproxy.h>
  
  #include "bonding.h"
  
   */
  static ssize_t bonding_show_bonds(struct class *cls, char *buf)
  {
 +      struct net *net = current->nsproxy->net_ns;
 +      struct bond_net *bn = net_generic(net, bond_net_id);
        int res = 0;
        struct bonding *bond;
  
        rtnl_lock();
  
 -      list_for_each_entry(bond, &bond_dev_list, bond_list) {
 +      list_for_each_entry(bond, &bn->dev_list, bond_list) {
                if (res > (PAGE_SIZE - IFNAMSIZ)) {
                        /* not enough space for another interface name */
                        if ((PAGE_SIZE - res) > 10)
        return res;
  }
  
 -static struct net_device *bond_get_by_name(const char *ifname)
 +static struct net_device *bond_get_by_name(struct net *net, const char *ifname)
  {
 +      struct bond_net *bn = net_generic(net, bond_net_id);
        struct bonding *bond;
  
 -      list_for_each_entry(bond, &bond_dev_list, bond_list) {
 +      list_for_each_entry(bond, &bn->dev_list, bond_list) {
                if (strncmp(bond->dev->name, ifname, IFNAMSIZ) == 0)
                        return bond->dev;
        }
@@@ -96,7 -92,6 +97,7 @@@
  static ssize_t bonding_store_bonds(struct class *cls,
                                   const char *buffer, size_t count)
  {
 +      struct net *net = current->nsproxy->net_ns;
        char command[IFNAMSIZ + 1] = {0, };
        char *ifname;
        int rv, res = count;
        if (command[0] == '+') {
                pr_info(DRV_NAME
                        ": %s is being created...\n", ifname);
 -              rv = bond_create(ifname);
 +              rv = bond_create(net, ifname);
                if (rv) {
                        pr_info(DRV_NAME ": Bond creation failed.\n");
                        res = rv;
                struct net_device *bond_dev;
  
                rtnl_lock();
 -              bond_dev = bond_get_by_name(ifname);
 +              bond_dev = bond_get_by_name(net, ifname);
                if (bond_dev) {
                        pr_info(DRV_NAME ": %s is being deleted...\n",
                                ifname);
@@@ -244,7 -239,8 +245,7 @@@ static ssize_t bonding_store_slaves(str
                /* Got a slave name in ifname.  Is it already in the list? */
                found = 0;
  
 -              /* FIXME: get netns from sysfs object */
 -              dev = __dev_get_by_name(&init_net, ifname);
 +              dev = __dev_get_by_name(dev_net(bond->dev), ifname);
                if (!dev) {
                        pr_info(DRV_NAME
                               ": %s: Interface %s does not exist!\n",
  static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
                   bonding_show_primary, bonding_store_primary);
  
 +/*
 + * Show and set the primary_reselect flag.
 + */
 +static ssize_t bonding_show_primary_reselect(struct device *d,
 +                                           struct device_attribute *attr,
 +                                           char *buf)
 +{
 +      struct bonding *bond = to_bond(d);
 +
 +      return sprintf(buf, "%s %d\n",
 +                     pri_reselect_tbl[bond->params.primary_reselect].modename,
 +                     bond->params.primary_reselect);
 +}
 +
 +static ssize_t bonding_store_primary_reselect(struct device *d,
 +                                            struct device_attribute *attr,
 +                                            const char *buf, size_t count)
 +{
 +      int new_value, ret = count;
 +      struct bonding *bond = to_bond(d);
 +
 +      if (!rtnl_trylock())
 +              return restart_syscall();
 +
 +      new_value = bond_parse_parm(buf, pri_reselect_tbl);
 +      if (new_value < 0)  {
 +              pr_err(DRV_NAME
 +                     ": %s: Ignoring invalid primary_reselect value %.*s.\n",
 +                     bond->dev->name,
 +                     (int) strlen(buf) - 1, buf);
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      bond->params.primary_reselect = new_value;
 +      pr_info(DRV_NAME ": %s: setting primary_reselect to %s (%d).\n",
 +              bond->dev->name, pri_reselect_tbl[new_value].modename,
 +              new_value);
 +
 +      read_lock(&bond->lock);
 +      write_lock_bh(&bond->curr_slave_lock);
 +      bond_select_active_slave(bond);
 +      write_unlock_bh(&bond->curr_slave_lock);
 +      read_unlock(&bond->lock);
 +out:
 +      rtnl_unlock();
 +      return ret;
 +}
 +static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR,
 +                 bonding_show_primary_reselect,
 +                 bonding_store_primary_reselect);
 +
  /*
   * Show and set the use_carrier flag.
   */
@@@ -1558,7 -1502,6 +1559,7 @@@ static struct attribute *per_bond_attrs
        &dev_attr_num_unsol_na.attr,
        &dev_attr_miimon.attr,
        &dev_attr_primary.attr,
 +      &dev_attr_primary_reselect.attr,
        &dev_attr_use_carrier.attr,
        &dev_attr_active_slave.attr,
        &dev_attr_mii_status.attr,
@@@ -1621,8 -1564,24 +1622,8 @@@ void bond_destroy_sysfs(void
   * Initialize sysfs for each bond.  This sets up and registers
   * the 'bondctl' directory for each individual bond under /sys/class/net.
   */
 -int bond_create_sysfs_entry(struct bonding *bond)
 +void bond_prepare_sysfs_group(struct bonding *bond)
  {
 -      struct net_device *dev = bond->dev;
 -      int err;
 -
 -      err = sysfs_create_group(&(dev->dev.kobj), &bonding_group);
 -      if (err)
 -              pr_emerg("eek! didn't create group!\n");
 -
 -      return err;
 -}
 -/*
 - * Remove sysfs entries for each bond.
 - */
 -void bond_destroy_sysfs_entry(struct bonding *bond)
 -{
 -      struct net_device *dev = bond->dev;
 -
 -      sysfs_remove_group(&(dev->dev.kobj), &bonding_group);
 +      bond->dev->sysfs_groups[0] = &bonding_group;
  }
  
diff --combined drivers/net/cxgb3/sge.c
index cf2e1d3c0d8d0abe96afaf0c99a1032cffc2e2ae,6366061712f447c198b31e5c5307ede58de51c06..49f3de79118ce397ddb37025e156791ca4e3b8bb
@@@ -879,7 -879,7 +879,7 @@@ recycle
        pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len,
                                    PCI_DMA_FROMDEVICE);
        (*sd->pg_chunk.p_cnt)--;
-       if (!*sd->pg_chunk.p_cnt)
+       if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
                pci_unmap_page(adap->pdev,
                               sd->pg_chunk.mapping,
                               fl->alloc_size,
@@@ -1260,7 -1260,7 +1260,7 @@@ netdev_tx_t t3_eth_xmit(struct sk_buff 
                if (should_restart_tx(q) &&
                    test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
                        q->restarts++;
 -                      netif_tx_wake_queue(txq);
 +                      netif_tx_start_queue(txq);
                }
        }
  
@@@ -1946,9 -1946,10 +1946,9 @@@ static void restart_tx(struct sge_qset 
   *    Check if the ARP request is probing the private IP address
   *    dedicated to iSCSI, generate an ARP reply if so.
   */
 -static void cxgb3_arp_process(struct adapter *adapter, struct sk_buff *skb)
 +static void cxgb3_arp_process(struct port_info *pi, struct sk_buff *skb)
  {
        struct net_device *dev = skb->dev;
 -      struct port_info *pi;
        struct arphdr *arp;
        unsigned char *arp_ptr;
        unsigned char *sha;
        arp_ptr += dev->addr_len;
        memcpy(&tip, arp_ptr, sizeof(tip));
  
 -      pi = netdev_priv(dev);
        if (tip != pi->iscsi_ipv4addr)
                return;
  
        arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
 -               dev->dev_addr, sha);
 +               pi->iscsic.mac_addr, sha);
  
  }
  
@@@ -1984,19 -1986,6 +1984,19 @@@ static inline int is_arp(struct sk_buf
        return skb->protocol == htons(ETH_P_ARP);
  }
  
 +static void cxgb3_process_iscsi_prov_pack(struct port_info *pi,
 +                                      struct sk_buff *skb)
 +{
 +      if (is_arp(skb)) {
 +              cxgb3_arp_process(pi, skb);
 +              return;
 +      }
 +
 +      if (pi->iscsic.recv)
 +              pi->iscsic.recv(pi, skb);
 +
 +}
 +
  /**
   *    rx_eth - process an ingress ethernet packet
   *    @adap: the adapter
@@@ -2035,12 -2024,13 +2035,12 @@@ static void rx_eth(struct adapter *adap
                                vlan_gro_receive(&qs->napi, grp,
                                                 ntohs(p->vlan), skb);
                        else {
 -                              if (unlikely(pi->iscsi_ipv4addr &&
 -                                  is_arp(skb))) {
 +                              if (unlikely(pi->iscsic.flags)) {
                                        unsigned short vtag = ntohs(p->vlan) &
                                                                VLAN_VID_MASK;
                                        skb->dev = vlan_group_get_device(grp,
                                                                         vtag);
 -                                      cxgb3_arp_process(adap, skb);
 +                                      cxgb3_process_iscsi_prov_pack(pi, skb);
                                }
                                __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
                                                  rq->polling);
                if (lro)
                        napi_gro_receive(&qs->napi, skb);
                else {
 -                      if (unlikely(pi->iscsi_ipv4addr && is_arp(skb)))
 -                              cxgb3_arp_process(adap, skb);
 +                      if (unlikely(pi->iscsic.flags))
 +                              cxgb3_process_iscsi_prov_pack(pi, skb);
                        netif_receive_skb(skb);
                }
        } else
@@@ -2098,7 -2088,7 +2098,7 @@@ static void lro_add_page(struct adapte
                                    PCI_DMA_FROMDEVICE);
  
        (*sd->pg_chunk.p_cnt)--;
-       if (!*sd->pg_chunk.p_cnt)
+       if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
                pci_unmap_page(adap->pdev,
                               sd->pg_chunk.mapping,
                               fl->alloc_size,
        if (!complete)
                return;
  
 +      skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
        skb->ip_summed = CHECKSUM_UNNECESSARY;
        cpl = qs->lro_va;
  
diff --combined drivers/net/e100.c
index 7462fdfd7f922c5a4dfabef66454a231e89efc4e,3c29a20b751e831fd4d338ec316535cc7e43c093..a81c7b0c41b0f811b955c3a68d356c66b6d2331e
  #include <linux/moduleparam.h>
  #include <linux/kernel.h>
  #include <linux/types.h>
+ #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/delay.h>
  #include <linux/init.h>
@@@ -621,7 -622,6 +622,7 @@@ struct nic 
        u16 eeprom_wc;
        __le16 eeprom[256];
        spinlock_t mdio_lock;
 +      const struct firmware *fw;
  };
  
  static inline void e100_write_flush(struct nic *nic)
@@@ -1223,9 -1223,9 +1224,9 @@@ static void e100_configure(struct nic *
  static const struct firmware *e100_request_firmware(struct nic *nic)
  {
        const char *fw_name;
 -      const struct firmware *fw;
 +      const struct firmware *fw = nic->fw;
        u8 timer, bundle, min_size;
 -      int err;
 +      int err = 0;
  
        /* do not load u-code for ICH devices */
        if (nic->flags & ich)
        else /* No ucode on other devices */
                return NULL;
  
 -      err = request_firmware(&fw, fw_name, &nic->pdev->dev);
 +      /* If the firmware has not previously been loaded, request a pointer
 +       * to it. If it was previously loaded, we are reinitializing the
 +       * adapter, possibly in a resume from hibernate, in which case
 +       * request_firmware() cannot be used.
 +       */
 +      if (!fw)
 +              err = request_firmware(&fw, fw_name, &nic->pdev->dev);
 +
        if (err) {
                DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n",
                        fw_name, err);
                return ERR_PTR(err);
        }
 +
        /* Firmware should be precisely UCODE_SIZE (words) plus three bytes
           indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */
        if (fw->size != UCODE_SIZE * 4 + 3) {
                release_firmware(fw);
                return ERR_PTR(-EINVAL);
        }
 -      /* OK, firmware is validated and ready to use... */
 +
 +      /* OK, firmware is validated and ready to use. Save a pointer
 +       * to it in the nic */
 +      nic->fw = fw;
        return fw;
  }
  
@@@ -1863,10 -1852,11 +1864,10 @@@ static inline void e100_start_receiver(
  #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN)
  static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
  {
 -      if (!(rx->skb = netdev_alloc_skb(nic->netdev, RFD_BUF_LEN + NET_IP_ALIGN)))
 +      if (!(rx->skb = netdev_alloc_skb_ip_align(nic->netdev, RFD_BUF_LEN)))
                return -ENOMEM;
  
 -      /* Align, init, and map the RFD. */
 -      skb_reserve(rx->skb, NET_IP_ALIGN);
 +      /* Init, and map the RFD. */
        skb_copy_to_linear_data(rx->skb, &nic->blank_rfd, sizeof(struct rfd));
        rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data,
                RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
diff --combined drivers/net/ethoc.c
index 96b6dc42fc740518541de09356b79db019303dfb,f7d9ac8324cb986a58e80947657bc216aad39088..bd1db92aec1beaa801463446fb425e1582fd9968
@@@ -17,6 -17,7 +17,7 @@@
  #include <linux/mii.h>
  #include <linux/phy.h>
  #include <linux/platform_device.h>
+ #include <linux/sched.h>
  #include <net/ethoc.h>
  
  static int buffer_size = 0x8000; /* 32 KBytes */
@@@ -405,10 -406,10 +406,10 @@@ static int ethoc_rx(struct net_device *
  
                if (ethoc_update_rx_stats(priv, &bd) == 0) {
                        int size = bd.stat >> 16;
 -                      struct sk_buff *skb = netdev_alloc_skb(dev, size);
 +                      struct sk_buff *skb;
  
                        size -= 4; /* strip the CRC */
 -                      skb_reserve(skb, 2); /* align TCP/IP header */
 +                      skb = netdev_alloc_skb_ip_align(dev, size);
  
                        if (likely(skb)) {
                                void *src = phys_to_virt(bd.addr);
@@@ -640,7 -641,7 +641,7 @@@ static int ethoc_mdio_probe(struct net_
                return -ENXIO;
        }
  
 -      phy = phy_connect(dev, dev_name(&phy->dev), &ethoc_mdio_poll, 0,
 +      phy = phy_connect(dev, dev_name(&phy->dev), ethoc_mdio_poll, 0,
                        PHY_INTERFACE_MODE_GMII);
        if (IS_ERR(phy)) {
                dev_err(&dev->dev, "could not attach to PHY\n");
diff --combined drivers/net/hamachi.c
index 18bd9fe20d7729df04a721531185081365f0e425,f7519a594945e831bee7fcc60fcbec24a3c9ca83..c9ac46118e6fef35eba30e2787908a503819a78f
@@@ -145,6 -145,7 +145,7 @@@ static int tx_params[MAX_UNITS] = {-1, 
  /* Time in jiffies before concluding the transmitter is hung. */
  #define TX_TIMEOUT  (5*HZ)
  
+ #include <linux/capability.h>
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/string.h>
@@@ -406,9 -407,10 +407,9 @@@ that case
  /* A few values that may be tweaked. */
  /* Size of each temporary Rx buffer, calculated as:
   * 1518 bytes (ethernet packet) + 2 bytes (to get 8 byte alignment for
 - * the card) + 8 bytes of status info + 8 bytes for the Rx Checksum +
 - * 2 more because we use skb_reserve.
 + * the card) + 8 bytes of status info + 8 bytes for the Rx Checksum
   */
 -#define PKT_BUF_SZ            1538
 +#define PKT_BUF_SZ            1536
  
  /* For now, this is going to be set to the maximum size of an ethernet
   * packet.  Eventually, we may want to make it a variable that is
@@@ -1150,13 -1152,12 +1151,13 @@@ static void hamachi_tx_timeout(struct n
        }
        /* Fill in the Rx buffers.  Handle allocation failure gracefully. */
        for (i = 0; i < RX_RING_SIZE; i++) {
 -              struct sk_buff *skb = netdev_alloc_skb(dev, hmp->rx_buf_sz);
 +              struct sk_buff *skb;
 +
 +              skb = netdev_alloc_skb_ip_align(dev, hmp->rx_buf_sz);
                hmp->rx_skbuff[i] = skb;
                if (skb == NULL)
                        break;
  
 -              skb_reserve(skb, 2); /* 16 byte align the IP header. */
                  hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
                        skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
                hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
@@@ -1195,7 -1196,7 +1196,7 @@@ static void hamachi_init_ring(struct ne
         * card.  -KDU
         */
        hmp->rx_buf_sz = (dev->mtu <= 1492 ? PKT_BUF_SZ :
 -              (((dev->mtu+26+7) & ~7) + 2 + 16));
 +              (((dev->mtu+26+7) & ~7) + 16));
  
        /* Initialize all Rx descriptors. */
        for (i = 0; i < RX_RING_SIZE; i++) {
index b3cf95d760406bf49343b5177ecfe694142ab317,e344c84c0ef9828efdfcf3b6b7ccf31895763758..a3c0dc9d8b98305ecbeda73f2bf61eb5a2c82b8c
@@@ -44,6 -44,7 +44,7 @@@
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/init.h>
+ #include <linux/sched.h>
  #include <linux/string.h>
  #include <linux/workqueue.h>
  #include <linux/fs.h>
@@@ -595,16 -596,16 +596,16 @@@ static int receive(struct net_device *d
                                        if (!(notbitstream & (0x1fc << j)))
                                                state = 0;
  
 -                                      /* not flag received */
 -                                      else if (!(bitstream & (0x1fe << j)) != (0x0fc << j)) {
 +                                      /* flag received */
 +                                      else if ((bitstream & (0x1fe << j)) == (0x0fc << j)) {
                                                if (state)
                                                        do_rxpacket(dev);
                                                bc->hdlcrx.bufcnt = 0;
                                                bc->hdlcrx.bufptr = bc->hdlcrx.buf;
                                                state = 1;
                                                numbits = 7-j;
 -                                              }
                                        }
 +                              }
  
                                /* stuffed bit */
                                else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) {
index c1cde5b449061d17da5c1551468f5ceb4edf3b80,b243ed3b0c3620de498982636240573138f0217b..88e13f7e566fb79dd65d6dad330bcb096336625d
@@@ -34,6 -34,7 +34,7 @@@
  #include <linux/interrupt.h>
  #include <linux/if_ether.h>
  #include <linux/ethtool.h>
+ #include <linux/sched.h>
  
  #include "igb.h"
  
@@@ -43,94 -44,78 +44,94 @@@ struct igb_stats 
        int stat_offset;
  };
  
 -#define IGB_STAT(m) FIELD_SIZEOF(struct igb_adapter, m), \
 -                    offsetof(struct igb_adapter, m)
 +#define IGB_STAT(_name, _stat) { \
 +      .stat_string = _name, \
 +      .sizeof_stat = FIELD_SIZEOF(struct igb_adapter, _stat), \
 +      .stat_offset = offsetof(struct igb_adapter, _stat) \
 +}
  static const struct igb_stats igb_gstrings_stats[] = {
 -      { "rx_packets", IGB_STAT(stats.gprc) },
 -      { "tx_packets", IGB_STAT(stats.gptc) },
 -      { "rx_bytes", IGB_STAT(stats.gorc) },
 -      { "tx_bytes", IGB_STAT(stats.gotc) },
 -      { "rx_broadcast", IGB_STAT(stats.bprc) },
 -      { "tx_broadcast", IGB_STAT(stats.bptc) },
 -      { "rx_multicast", IGB_STAT(stats.mprc) },
 -      { "tx_multicast", IGB_STAT(stats.mptc) },
 -      { "rx_errors", IGB_STAT(net_stats.rx_errors) },
 -      { "tx_errors", IGB_STAT(net_stats.tx_errors) },
 -      { "tx_dropped", IGB_STAT(net_stats.tx_dropped) },
 -      { "multicast", IGB_STAT(stats.mprc) },
 -      { "collisions", IGB_STAT(stats.colc) },
 -      { "rx_length_errors", IGB_STAT(net_stats.rx_length_errors) },
 -      { "rx_over_errors", IGB_STAT(net_stats.rx_over_errors) },
 -      { "rx_crc_errors", IGB_STAT(stats.crcerrs) },
 -      { "rx_frame_errors", IGB_STAT(net_stats.rx_frame_errors) },
 -      { "rx_no_buffer_count", IGB_STAT(stats.rnbc) },
 -      { "rx_queue_drop_packet_count", IGB_STAT(net_stats.rx_fifo_errors) },
 -      { "rx_missed_errors", IGB_STAT(stats.mpc) },
 -      { "tx_aborted_errors", IGB_STAT(stats.ecol) },
 -      { "tx_carrier_errors", IGB_STAT(stats.tncrs) },
 -      { "tx_fifo_errors", IGB_STAT(net_stats.tx_fifo_errors) },
 -      { "tx_heartbeat_errors", IGB_STAT(net_stats.tx_heartbeat_errors) },
 -      { "tx_window_errors", IGB_STAT(stats.latecol) },
 -      { "tx_abort_late_coll", IGB_STAT(stats.latecol) },
 -      { "tx_deferred_ok", IGB_STAT(stats.dc) },
 -      { "tx_single_coll_ok", IGB_STAT(stats.scc) },
 -      { "tx_multi_coll_ok", IGB_STAT(stats.mcc) },
 -      { "tx_timeout_count", IGB_STAT(tx_timeout_count) },
 -      { "tx_restart_queue", IGB_STAT(restart_queue) },
 -      { "rx_long_length_errors", IGB_STAT(stats.roc) },
 -      { "rx_short_length_errors", IGB_STAT(stats.ruc) },
 -      { "rx_align_errors", IGB_STAT(stats.algnerrc) },
 -      { "tx_tcp_seg_good", IGB_STAT(stats.tsctc) },
 -      { "tx_tcp_seg_failed", IGB_STAT(stats.tsctfc) },
 -      { "rx_flow_control_xon", IGB_STAT(stats.xonrxc) },
 -      { "rx_flow_control_xoff", IGB_STAT(stats.xoffrxc) },
 -      { "tx_flow_control_xon", IGB_STAT(stats.xontxc) },
 -      { "tx_flow_control_xoff", IGB_STAT(stats.xofftxc) },
 -      { "rx_long_byte_count", IGB_STAT(stats.gorc) },
 -      { "rx_csum_offload_good", IGB_STAT(hw_csum_good) },
 -      { "rx_csum_offload_errors", IGB_STAT(hw_csum_err) },
 -      { "tx_dma_out_of_sync", IGB_STAT(stats.doosync) },
 -      { "alloc_rx_buff_failed", IGB_STAT(alloc_rx_buff_failed) },
 -      { "tx_smbus", IGB_STAT(stats.mgptc) },
 -      { "rx_smbus", IGB_STAT(stats.mgprc) },
 -      { "dropped_smbus", IGB_STAT(stats.mgpdc) },
 +      IGB_STAT("rx_packets", stats.gprc),
 +      IGB_STAT("tx_packets", stats.gptc),
 +      IGB_STAT("rx_bytes", stats.gorc),
 +      IGB_STAT("tx_bytes", stats.gotc),
 +      IGB_STAT("rx_broadcast", stats.bprc),
 +      IGB_STAT("tx_broadcast", stats.bptc),
 +      IGB_STAT("rx_multicast", stats.mprc),
 +      IGB_STAT("tx_multicast", stats.mptc),
 +      IGB_STAT("multicast", stats.mprc),
 +      IGB_STAT("collisions", stats.colc),
 +      IGB_STAT("rx_crc_errors", stats.crcerrs),
 +      IGB_STAT("rx_no_buffer_count", stats.rnbc),
 +      IGB_STAT("rx_missed_errors", stats.mpc),
 +      IGB_STAT("tx_aborted_errors", stats.ecol),
 +      IGB_STAT("tx_carrier_errors", stats.tncrs),
 +      IGB_STAT("tx_window_errors", stats.latecol),
 +      IGB_STAT("tx_abort_late_coll", stats.latecol),
 +      IGB_STAT("tx_deferred_ok", stats.dc),
 +      IGB_STAT("tx_single_coll_ok", stats.scc),
 +      IGB_STAT("tx_multi_coll_ok", stats.mcc),
 +      IGB_STAT("tx_timeout_count", tx_timeout_count),
 +      IGB_STAT("rx_long_length_errors", stats.roc),
 +      IGB_STAT("rx_short_length_errors", stats.ruc),
 +      IGB_STAT("rx_align_errors", stats.algnerrc),
 +      IGB_STAT("tx_tcp_seg_good", stats.tsctc),
 +      IGB_STAT("tx_tcp_seg_failed", stats.tsctfc),
 +      IGB_STAT("rx_flow_control_xon", stats.xonrxc),
 +      IGB_STAT("rx_flow_control_xoff", stats.xoffrxc),
 +      IGB_STAT("tx_flow_control_xon", stats.xontxc),
 +      IGB_STAT("tx_flow_control_xoff", stats.xofftxc),
 +      IGB_STAT("rx_long_byte_count", stats.gorc),
 +      IGB_STAT("tx_dma_out_of_sync", stats.doosync),
 +      IGB_STAT("tx_smbus", stats.mgptc),
 +      IGB_STAT("rx_smbus", stats.mgprc),
 +      IGB_STAT("dropped_smbus", stats.mgpdc),
 +};
 +
 +#define IGB_NETDEV_STAT(_net_stat) { \
 +      .stat_string = __stringify(_net_stat), \
 +      .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
 +      .stat_offset = offsetof(struct net_device_stats, _net_stat) \
 +}
 +static const struct igb_stats igb_gstrings_net_stats[] = {
 +      IGB_NETDEV_STAT(rx_errors),
 +      IGB_NETDEV_STAT(tx_errors),
 +      IGB_NETDEV_STAT(tx_dropped),
 +      IGB_NETDEV_STAT(rx_length_errors),
 +      IGB_NETDEV_STAT(rx_over_errors),
 +      IGB_NETDEV_STAT(rx_frame_errors),
 +      IGB_NETDEV_STAT(rx_fifo_errors),
 +      IGB_NETDEV_STAT(tx_fifo_errors),
 +      IGB_NETDEV_STAT(tx_heartbeat_errors)
  };
  
 -#define IGB_QUEUE_STATS_LEN \
 -      (((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues)* \
 -        (sizeof(struct igb_rx_queue_stats) / sizeof(u64))) + \
 -       ((((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues) * \
 -        (sizeof(struct igb_tx_queue_stats) / sizeof(u64))))
  #define IGB_GLOBAL_STATS_LEN  \
 -      sizeof(igb_gstrings_stats) / sizeof(struct igb_stats)
 -#define IGB_STATS_LEN (IGB_GLOBAL_STATS_LEN + IGB_QUEUE_STATS_LEN)
 +      (sizeof(igb_gstrings_stats) / sizeof(struct igb_stats))
 +#define IGB_NETDEV_STATS_LEN  \
 +      (sizeof(igb_gstrings_net_stats) / sizeof(struct igb_stats))
 +#define IGB_RX_QUEUE_STATS_LEN \
 +      (sizeof(struct igb_rx_queue_stats) / sizeof(u64))
 +#define IGB_TX_QUEUE_STATS_LEN \
 +      (sizeof(struct igb_tx_queue_stats) / sizeof(u64))
 +#define IGB_QUEUE_STATS_LEN \
 +      ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \
 +        IGB_RX_QUEUE_STATS_LEN) + \
 +       (((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues * \
 +        IGB_TX_QUEUE_STATS_LEN))
 +#define IGB_STATS_LEN \
 +      (IGB_GLOBAL_STATS_LEN + IGB_NETDEV_STATS_LEN + IGB_QUEUE_STATS_LEN)
 +
  static const char igb_gstrings_test[][ETH_GSTRING_LEN] = {
        "Register test  (offline)", "Eeprom test    (offline)",
        "Interrupt test (offline)", "Loopback test  (offline)",
        "Link test   (on/offline)"
  };
 -#define IGB_TEST_LEN sizeof(igb_gstrings_test) / ETH_GSTRING_LEN
 +#define IGB_TEST_LEN (sizeof(igb_gstrings_test) / ETH_GSTRING_LEN)
  
  static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
  {
        struct igb_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
 +      u32 status;
  
        if (hw->phy.media_type == e1000_media_type_copper) {
  
  
        ecmd->transceiver = XCVR_INTERNAL;
  
 -      if (rd32(E1000_STATUS) & E1000_STATUS_LU) {
 +      status = rd32(E1000_STATUS);
  
 -              adapter->hw.mac.ops.get_speed_and_duplex(hw,
 -                                      &adapter->link_speed,
 -                                      &adapter->link_duplex);
 -              ecmd->speed = adapter->link_speed;
 +      if (status & E1000_STATUS_LU) {
  
 -              /* unfortunately FULL_DUPLEX != DUPLEX_FULL
 -               *          and HALF_DUPLEX != DUPLEX_HALF */
 +              if ((status & E1000_STATUS_SPEED_1000) ||
 +                  hw->phy.media_type != e1000_media_type_copper)
 +                      ecmd->speed = SPEED_1000;
 +              else if (status & E1000_STATUS_SPEED_100)
 +                      ecmd->speed = SPEED_100;
 +              else
 +                      ecmd->speed = SPEED_10;
  
 -              if (adapter->link_duplex == FULL_DUPLEX)
 +              if ((status & E1000_STATUS_FD) ||
 +                  hw->phy.media_type != e1000_media_type_copper)
                        ecmd->duplex = DUPLEX_FULL;
                else
                        ecmd->duplex = DUPLEX_HALF;
@@@ -269,9 -251,8 +270,9 @@@ static int igb_set_pauseparam(struct ne
                if (netif_running(adapter->netdev)) {
                        igb_down(adapter);
                        igb_up(adapter);
 -              } else
 +              } else {
                        igb_reset(adapter);
 +              }
        } else {
                if (pause->rx_pause && pause->tx_pause)
                        hw->fc.requested_mode = e1000_fc_full;
  static u32 igb_get_rx_csum(struct net_device *netdev)
  {
        struct igb_adapter *adapter = netdev_priv(netdev);
 -      return !(adapter->flags & IGB_FLAG_RX_CSUM_DISABLED);
 +      return !!(adapter->rx_ring[0].flags & IGB_RING_FLAG_RX_CSUM);
  }
  
  static int igb_set_rx_csum(struct net_device *netdev, u32 data)
  {
        struct igb_adapter *adapter = netdev_priv(netdev);
 +      int i;
  
 -      if (data)
 -              adapter->flags &= ~IGB_FLAG_RX_CSUM_DISABLED;
 -      else
 -              adapter->flags |= IGB_FLAG_RX_CSUM_DISABLED;
 +      for (i = 0; i < adapter->num_rx_queues; i++) {
 +              if (data)
 +                      adapter->rx_ring[i].flags |= IGB_RING_FLAG_RX_CSUM;
 +              else
 +                      adapter->rx_ring[i].flags &= ~IGB_RING_FLAG_RX_CSUM;
 +      }
  
        return 0;
  }
@@@ -324,7 -302,7 +325,7 @@@ static int igb_set_tx_csum(struct net_d
  
        if (data) {
                netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
 -              if (adapter->hw.mac.type == e1000_82576)
 +              if (adapter->hw.mac.type >= e1000_82576)
                        netdev->features |= NETIF_F_SCTP_CSUM;
        } else {
                netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
@@@ -518,10 -496,19 +519,10 @@@ static void igb_get_regs(struct net_dev
        regs_buff[119] = adapter->stats.scvpc;
        regs_buff[120] = adapter->stats.hrmpc;
  
 -      /* These should probably be added to e1000_regs.h instead */
 -      #define E1000_PSRTYPE_REG(_i) (0x05480 + ((_i) * 4))
 -      #define E1000_IP4AT_REG(_i)   (0x05840 + ((_i) * 8))
 -      #define E1000_IP6AT_REG(_i)   (0x05880 + ((_i) * 4))
 -      #define E1000_WUPM_REG(_i)    (0x05A00 + ((_i) * 4))
 -      #define E1000_FFMT_REG(_i)    (0x09000 + ((_i) * 8))
 -      #define E1000_FFVT_REG(_i)    (0x09800 + ((_i) * 8))
 -      #define E1000_FFLT_REG(_i)    (0x05F00 + ((_i) * 8))
 -
        for (i = 0; i < 4; i++)
                regs_buff[121 + i] = rd32(E1000_SRRCTL(i));
        for (i = 0; i < 4; i++)
 -              regs_buff[125 + i] = rd32(E1000_PSRTYPE_REG(i));
 +              regs_buff[125 + i] = rd32(E1000_PSRTYPE(i));
        for (i = 0; i < 4; i++)
                regs_buff[129 + i] = rd32(E1000_RDBAL(i));
        for (i = 0; i < 4; i++)
@@@ -746,17 -733,17 +747,17 @@@ static int igb_set_ringparam(struct net
        struct igb_adapter *adapter = netdev_priv(netdev);
        struct igb_ring *temp_ring;
        int i, err = 0;
 -      u32 new_rx_count, new_tx_count;
 +      u16 new_rx_count, new_tx_count;
  
        if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
                return -EINVAL;
  
 -      new_rx_count = max(ring->rx_pending, (u32)IGB_MIN_RXD);
 -      new_rx_count = min(new_rx_count, (u32)IGB_MAX_RXD);
 +      new_rx_count = min_t(u32, ring->rx_pending, IGB_MAX_RXD);
 +      new_rx_count = max_t(u16, new_rx_count, IGB_MIN_RXD);
        new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);
  
 -      new_tx_count = max(ring->tx_pending, (u32)IGB_MIN_TXD);
 -      new_tx_count = min(new_tx_count, (u32)IGB_MAX_TXD);
 +      new_tx_count = min_t(u32, ring->tx_pending, IGB_MAX_TXD);
 +      new_tx_count = max_t(u16, new_tx_count, IGB_MIN_TXD);
        new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
  
        if ((new_tx_count == adapter->tx_ring_count) &&
  
                for (i = 0; i < adapter->num_tx_queues; i++) {
                        temp_ring[i].count = new_tx_count;
 -                      err = igb_setup_tx_resources(adapter, &temp_ring[i]);
 +                      err = igb_setup_tx_resources(&temp_ring[i]);
                        if (err) {
                                while (i) {
                                        i--;
  
                for (i = 0; i < adapter->num_rx_queues; i++) {
                        temp_ring[i].count = new_rx_count;
 -                      err = igb_setup_rx_resources(adapter, &temp_ring[i]);
 +                      err = igb_setup_rx_resources(&temp_ring[i]);
                        if (err) {
                                while (i) {
                                        i--;
@@@ -957,7 -944,7 +958,7 @@@ static bool reg_pattern_test(struct igb
  {
        struct e1000_hw *hw = &adapter->hw;
        u32 pat, val;
 -      u32 _test[] =
 +      static const u32 _test[] =
                {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
        for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
                wr32(reg, (_test[pat] & write));
                        return 1;
                }
        }
 +
        return 0;
  }
  
@@@ -988,7 -974,6 +989,7 @@@ static bool reg_set_and_check(struct ig
                *data = reg;
                return 1;
        }
 +
        return 0;
  }
  
@@@ -1011,14 -996,14 +1012,14 @@@ static int igb_reg_test(struct igb_adap
        u32 value, before, after;
        u32 i, toggle;
  
 -      toggle = 0x7FFFF3FF;
 -
        switch (adapter->hw.mac.type) {
        case e1000_82576:
                test = reg_test_82576;
 +              toggle = 0x7FFFF3FF;
                break;
        default:
                test = reg_test_82575;
 +              toggle = 0x7FFFF3FF;
                break;
        }
  
@@@ -1096,7 -1081,8 +1097,7 @@@ static int igb_eeprom_test(struct igb_a
        *data = 0;
        /* Read and add up the contents of the EEPROM */
        for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
 -              if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp))
 -                  < 0) {
 +              if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp)) < 0) {
                        *data = 1;
                        break;
                }
  
  static irqreturn_t igb_test_intr(int irq, void *data)
  {
 -      struct net_device *netdev = (struct net_device *) data;
 -      struct igb_adapter *adapter = netdev_priv(netdev);
 +      struct igb_adapter *adapter = (struct igb_adapter *) data;
        struct e1000_hw *hw = &adapter->hw;
  
        adapter->test_icr |= rd32(E1000_ICR);
@@@ -1130,36 -1117,32 +1131,36 @@@ static int igb_intr_test(struct igb_ada
        *data = 0;
  
        /* Hook up test interrupt handler just for this test */
 -      if (adapter->msix_entries)
 -              /* NOTE: we don't test MSI-X interrupts here, yet */
 -              return 0;
 -
 -      if (adapter->flags & IGB_FLAG_HAS_MSI) {
 +      if (adapter->msix_entries) {
 +              if (request_irq(adapter->msix_entries[0].vector,
 +                              &igb_test_intr, 0, netdev->name, adapter)) {
 +                      *data = 1;
 +                      return -1;
 +              }
 +      } else if (adapter->flags & IGB_FLAG_HAS_MSI) {
                shared_int = false;
 -              if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) {
 +              if (request_irq(irq,
 +                              &igb_test_intr, 0, netdev->name, adapter)) {
                        *data = 1;
                        return -1;
                }
        } else if (!request_irq(irq, &igb_test_intr, IRQF_PROBE_SHARED,
 -                              netdev->name, netdev)) {
 +                              netdev->name, adapter)) {
                shared_int = false;
        } else if (request_irq(irq, &igb_test_intr, IRQF_SHARED,
 -               netdev->name, netdev)) {
 +               netdev->name, adapter)) {
                *data = 1;
                return -1;
        }
        dev_info(&adapter->pdev->dev, "testing %s interrupt\n",
                (shared_int ? "shared" : "unshared"));
 +
        /* Disable all the interrupts */
 -      wr32(E1000_IMC, 0xFFFFFFFF);
 +      wr32(E1000_IMC, ~0);
        msleep(10);
  
        /* Define all writable bits for ICS */
 -      switch(hw->mac.type) {
 +      switch (hw->mac.type) {
        case e1000_82575:
                ics_mask = 0x37F47EDD;
                break;
        msleep(10);
  
        /* Unhook test interrupt handler */
 -      free_irq(irq, netdev);
 +      if (adapter->msix_entries)
 +              free_irq(adapter->msix_entries[0].vector, adapter);
 +      else
 +              free_irq(irq, adapter);
  
        return *data;
  }
  
  static void igb_free_desc_rings(struct igb_adapter *adapter)
  {
 -      struct igb_ring *tx_ring = &adapter->test_tx_ring;
 -      struct igb_ring *rx_ring = &adapter->test_rx_ring;
 -      struct pci_dev *pdev = adapter->pdev;
 -      int i;
 -
 -      if (tx_ring->desc && tx_ring->buffer_info) {
 -              for (i = 0; i < tx_ring->count; i++) {
 -                      struct igb_buffer *buf = &(tx_ring->buffer_info[i]);
 -                      if (buf->dma)
 -                              pci_unmap_single(pdev, buf->dma, buf->length,
 -                                               PCI_DMA_TODEVICE);
 -                      if (buf->skb)
 -                              dev_kfree_skb(buf->skb);
 -              }
 -      }
 -
 -      if (rx_ring->desc && rx_ring->buffer_info) {
 -              for (i = 0; i < rx_ring->count; i++) {
 -                      struct igb_buffer *buf = &(rx_ring->buffer_info[i]);
 -                      if (buf->dma)
 -                              pci_unmap_single(pdev, buf->dma,
 -                                               IGB_RXBUFFER_2048,
 -                                               PCI_DMA_FROMDEVICE);
 -                      if (buf->skb)
 -                              dev_kfree_skb(buf->skb);
 -              }
 -      }
 -
 -      if (tx_ring->desc) {
 -              pci_free_consistent(pdev, tx_ring->size, tx_ring->desc,
 -                                  tx_ring->dma);
 -              tx_ring->desc = NULL;
 -      }
 -      if (rx_ring->desc) {
 -              pci_free_consistent(pdev, rx_ring->size, rx_ring->desc,
 -                                  rx_ring->dma);
 -              rx_ring->desc = NULL;
 -      }
 -
 -      kfree(tx_ring->buffer_info);
 -      tx_ring->buffer_info = NULL;
 -      kfree(rx_ring->buffer_info);
 -      rx_ring->buffer_info = NULL;
 -
 -      return;
 +      igb_free_tx_resources(&adapter->test_tx_ring);
 +      igb_free_rx_resources(&adapter->test_rx_ring);
  }
  
  static int igb_setup_desc_rings(struct igb_adapter *adapter)
  {
 -      struct e1000_hw *hw = &adapter->hw;
        struct igb_ring *tx_ring = &adapter->test_tx_ring;
        struct igb_ring *rx_ring = &adapter->test_rx_ring;
 -      struct pci_dev *pdev = adapter->pdev;
 -      struct igb_buffer *buffer_info;
 -      u32 rctl;
 -      int i, ret_val;
 +      struct e1000_hw *hw = &adapter->hw;
 +      int ret_val;
  
        /* Setup Tx descriptor ring and Tx buffers */
 +      tx_ring->count = IGB_DEFAULT_TXD;
 +      tx_ring->pdev = adapter->pdev;
 +      tx_ring->netdev = adapter->netdev;
 +      tx_ring->reg_idx = adapter->vfs_allocated_count;
  
 -      if (!tx_ring->count)
 -              tx_ring->count = IGB_DEFAULT_TXD;
 -
 -      tx_ring->buffer_info = kcalloc(tx_ring->count,
 -                                     sizeof(struct igb_buffer),
 -                                     GFP_KERNEL);
 -      if (!tx_ring->buffer_info) {
 +      if (igb_setup_tx_resources(tx_ring)) {
                ret_val = 1;
                goto err_nomem;
        }
  
 -      tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
 -      tx_ring->size = ALIGN(tx_ring->size, 4096);
 -      tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
 -                                           &tx_ring->dma);
 -      if (!tx_ring->desc) {
 -              ret_val = 2;
 -              goto err_nomem;
 -      }
 -      tx_ring->next_to_use = tx_ring->next_to_clean = 0;
 -
 -      wr32(E1000_TDBAL(0),
 -                      ((u64) tx_ring->dma & 0x00000000FFFFFFFF));
 -      wr32(E1000_TDBAH(0), ((u64) tx_ring->dma >> 32));
 -      wr32(E1000_TDLEN(0),
 -                      tx_ring->count * sizeof(union e1000_adv_tx_desc));
 -      wr32(E1000_TDH(0), 0);
 -      wr32(E1000_TDT(0), 0);
 -      wr32(E1000_TCTL,
 -                      E1000_TCTL_PSP | E1000_TCTL_EN |
 -                      E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
 -                      E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT);
 -
 -      for (i = 0; i < tx_ring->count; i++) {
 -              union e1000_adv_tx_desc *tx_desc;
 -              struct sk_buff *skb;
 -              unsigned int size = 1024;
 -
 -              tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
 -              skb = alloc_skb(size, GFP_KERNEL);
 -              if (!skb) {
 -                      ret_val = 3;
 -                      goto err_nomem;
 -              }
 -              skb_put(skb, size);
 -              buffer_info = &tx_ring->buffer_info[i];
 -              buffer_info->skb = skb;
 -              buffer_info->length = skb->len;
 -              buffer_info->dma = pci_map_single(pdev, skb->data, skb->len,
 -                                                PCI_DMA_TODEVICE);
 -              tx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
 -              tx_desc->read.olinfo_status = cpu_to_le32(skb->len) <<
 -                                            E1000_ADVTXD_PAYLEN_SHIFT;
 -              tx_desc->read.cmd_type_len = cpu_to_le32(skb->len);
 -              tx_desc->read.cmd_type_len |= cpu_to_le32(E1000_TXD_CMD_EOP |
 -                                                        E1000_TXD_CMD_IFCS |
 -                                                        E1000_TXD_CMD_RS |
 -                                                        E1000_ADVTXD_DTYP_DATA |
 -                                                        E1000_ADVTXD_DCMD_DEXT);
 -      }
 +      igb_setup_tctl(adapter);
 +      igb_configure_tx_ring(adapter, tx_ring);
  
        /* Setup Rx descriptor ring and Rx buffers */
 -
 -      if (!rx_ring->count)
 -              rx_ring->count = IGB_DEFAULT_RXD;
 -
 -      rx_ring->buffer_info = kcalloc(rx_ring->count,
 -                                     sizeof(struct igb_buffer),
 -                                     GFP_KERNEL);
 -      if (!rx_ring->buffer_info) {
 -              ret_val = 4;
 +      rx_ring->count = IGB_DEFAULT_RXD;
 +      rx_ring->pdev = adapter->pdev;
 +      rx_ring->netdev = adapter->netdev;
 +      rx_ring->rx_buffer_len = IGB_RXBUFFER_2048;
 +      rx_ring->reg_idx = adapter->vfs_allocated_count;
 +
 +      if (igb_setup_rx_resources(rx_ring)) {
 +              ret_val = 3;
                goto err_nomem;
        }
  
 -      rx_ring->size = rx_ring->count * sizeof(union e1000_adv_rx_desc);
 -      rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
 -                                           &rx_ring->dma);
 -      if (!rx_ring->desc) {
 -              ret_val = 5;
 -              goto err_nomem;
 -      }
 -      rx_ring->next_to_use = rx_ring->next_to_clean = 0;
 +      /* set the default queue to queue 0 of PF */
 +      wr32(E1000_MRQC, adapter->vfs_allocated_count << 3);
  
 -      rctl = rd32(E1000_RCTL);
 -      wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
 -      wr32(E1000_RDBAL(0),
 -                      ((u64) rx_ring->dma & 0xFFFFFFFF));
 -      wr32(E1000_RDBAH(0),
 -                      ((u64) rx_ring->dma >> 32));
 -      wr32(E1000_RDLEN(0), rx_ring->size);
 -      wr32(E1000_RDH(0), 0);
 -      wr32(E1000_RDT(0), 0);
 -      rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
 -      rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
 -              (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
 -      wr32(E1000_RCTL, rctl);
 -      wr32(E1000_SRRCTL(0), E1000_SRRCTL_DESCTYPE_ADV_ONEBUF);
 -
 -      for (i = 0; i < rx_ring->count; i++) {
 -              union e1000_adv_rx_desc *rx_desc;
 -              struct sk_buff *skb;
 -
 -              buffer_info = &rx_ring->buffer_info[i];
 -              rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
 -              skb = alloc_skb(IGB_RXBUFFER_2048 + NET_IP_ALIGN,
 -                              GFP_KERNEL);
 -              if (!skb) {
 -                      ret_val = 6;
 -                      goto err_nomem;
 -              }
 -              skb_reserve(skb, NET_IP_ALIGN);
 -              buffer_info->skb = skb;
 -              buffer_info->dma = pci_map_single(pdev, skb->data,
 -                                                IGB_RXBUFFER_2048,
 -                                                PCI_DMA_FROMDEVICE);
 -              rx_desc->read.pkt_addr = cpu_to_le64(buffer_info->dma);
 -              memset(skb->data, 0x00, skb->len);
 -      }
 +      /* enable receive ring */
 +      igb_setup_rctl(adapter);
 +      igb_configure_rx_ring(adapter, rx_ring);
 +
 +      igb_alloc_rx_buffers_adv(rx_ring, igb_desc_unused(rx_ring));
  
        return 0;
  
@@@ -1379,10 -1491,7 +1380,10 @@@ static int igb_setup_loopback_test(stru
        struct e1000_hw *hw = &adapter->hw;
        u32 reg;
  
 -      if (hw->phy.media_type == e1000_media_type_internal_serdes) {
 +      reg = rd32(E1000_CTRL_EXT);
 +
 +      /* use CTRL_EXT to identify link type as SGMII can appear as copper */
 +      if (reg & E1000_CTRL_EXT_LINK_MODE_MASK) {
                reg = rd32(E1000_RCTL);
                reg |= E1000_RCTL_LBM_TCVR;
                wr32(E1000_RCTL, reg);
                wr32(E1000_PCS_LCTL, reg);
  
                return 0;
 -      } else if (hw->phy.media_type == e1000_media_type_copper) {
 -              return igb_set_phy_loopback(adapter);
        }
  
 -      return 7;
 +      return igb_set_phy_loopback(adapter);
  }
  
  static void igb_loopback_cleanup(struct igb_adapter *adapter)
@@@ -1441,99 -1552,35 +1442,99 @@@ static void igb_create_lbtest_frame(str
                                    unsigned int frame_size)
  {
        memset(skb->data, 0xFF, frame_size);
 -      frame_size &= ~1;
 -      memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
 -      memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
 -      memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
 +      frame_size /= 2;
 +      memset(&skb->data[frame_size], 0xAA, frame_size - 1);
 +      memset(&skb->data[frame_size + 10], 0xBE, 1);
 +      memset(&skb->data[frame_size + 12], 0xAF, 1);
  }
  
  static int igb_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
  {
 -      frame_size &= ~1;
 -      if (*(skb->data + 3) == 0xFF)
 -              if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
 -                 (*(skb->data + frame_size / 2 + 12) == 0xAF))
 +      frame_size /= 2;
 +      if (*(skb->data + 3) == 0xFF) {
 +              if ((*(skb->data + frame_size + 10) == 0xBE) &&
 +                 (*(skb->data + frame_size + 12) == 0xAF)) {
                        return 0;
 +              }
 +      }
        return 13;
  }
  
 +static int igb_clean_test_rings(struct igb_ring *rx_ring,
 +                                struct igb_ring *tx_ring,
 +                                unsigned int size)
 +{
 +      union e1000_adv_rx_desc *rx_desc;
 +      struct igb_buffer *buffer_info;
 +      int rx_ntc, tx_ntc, count = 0;
 +      u32 staterr;
 +
 +      /* initialize next to clean and descriptor values */
 +      rx_ntc = rx_ring->next_to_clean;
 +      tx_ntc = tx_ring->next_to_clean;
 +      rx_desc = E1000_RX_DESC_ADV(*rx_ring, rx_ntc);
 +      staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
 +
 +      while (staterr & E1000_RXD_STAT_DD) {
 +              /* check rx buffer */
 +              buffer_info = &rx_ring->buffer_info[rx_ntc];
 +
 +              /* unmap rx buffer, will be remapped by alloc_rx_buffers */
 +              pci_unmap_single(rx_ring->pdev,
 +                               buffer_info->dma,
 +                               rx_ring->rx_buffer_len,
 +                               PCI_DMA_FROMDEVICE);
 +              buffer_info->dma = 0;
 +
 +              /* verify contents of skb */
 +              if (!igb_check_lbtest_frame(buffer_info->skb, size))
 +                      count++;
 +
 +              /* unmap buffer on tx side */
 +              buffer_info = &tx_ring->buffer_info[tx_ntc];
 +              igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
 +
 +              /* increment rx/tx next to clean counters */
 +              rx_ntc++;
 +              if (rx_ntc == rx_ring->count)
 +                      rx_ntc = 0;
 +              tx_ntc++;
 +              if (tx_ntc == tx_ring->count)
 +                      tx_ntc = 0;
 +
 +              /* fetch next descriptor */
 +              rx_desc = E1000_RX_DESC_ADV(*rx_ring, rx_ntc);
 +              staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
 +      }
 +
 +      /* re-map buffers to ring, store next to clean values */
 +      igb_alloc_rx_buffers_adv(rx_ring, count);
 +      rx_ring->next_to_clean = rx_ntc;
 +      tx_ring->next_to_clean = tx_ntc;
 +
 +      return count;
 +}
 +
  static int igb_run_loopback_test(struct igb_adapter *adapter)
  {
 -      struct e1000_hw *hw = &adapter->hw;
        struct igb_ring *tx_ring = &adapter->test_tx_ring;
        struct igb_ring *rx_ring = &adapter->test_rx_ring;
 -      struct pci_dev *pdev = adapter->pdev;
 -      int i, j, k, l, lc, good_cnt;
 -      int ret_val = 0;
 -      unsigned long time;
 +      int i, j, lc, good_cnt, ret_val = 0;
 +      unsigned int size = 1024;
 +      netdev_tx_t tx_ret_val;
 +      struct sk_buff *skb;
  
 -      wr32(E1000_RDT(0), rx_ring->count - 1);
 +      /* allocate test skb */
 +      skb = alloc_skb(size, GFP_KERNEL);
 +      if (!skb)
 +              return 11;
  
 -      /* Calculate the loop count based on the largest descriptor ring
 +      /* place data into test skb */
 +      igb_create_lbtest_frame(skb, size);
 +      skb_put(skb, size);
 +
 +      /*
 +       * Calculate the loop count based on the largest descriptor ring
         * The idea is to wrap the largest ring a number of times using 64
         * send/receive pairs during each loop
         */
        else
                lc = ((rx_ring->count / 64) * 2) + 1;
  
 -      k = l = 0;
        for (j = 0; j <= lc; j++) { /* loop count loop */
 -              for (i = 0; i < 64; i++) { /* send the packets */
 -                      igb_create_lbtest_frame(tx_ring->buffer_info[k].skb,
 -                                              1024);
 -                      pci_dma_sync_single_for_device(pdev,
 -                              tx_ring->buffer_info[k].dma,
 -                              tx_ring->buffer_info[k].length,
 -                              PCI_DMA_TODEVICE);
 -                      k++;
 -                      if (k == tx_ring->count)
 -                              k = 0;
 -              }
 -              wr32(E1000_TDT(0), k);
 -              msleep(200);
 -              time = jiffies; /* set the start time for the receive */
 +              /* reset count of good packets */
                good_cnt = 0;
 -              do { /* receive the sent packets */
 -                      pci_dma_sync_single_for_cpu(pdev,
 -                                      rx_ring->buffer_info[l].dma,
 -                                      IGB_RXBUFFER_2048,
 -                                      PCI_DMA_FROMDEVICE);
 -
 -                      ret_val = igb_check_lbtest_frame(
 -                                           rx_ring->buffer_info[l].skb, 1024);
 -                      if (!ret_val)
 +
 +              /* place 64 packets on the transmit queue*/
 +              for (i = 0; i < 64; i++) {
 +                      skb_get(skb);
 +                      tx_ret_val = igb_xmit_frame_ring_adv(skb, tx_ring);
 +                      if (tx_ret_val == NETDEV_TX_OK)
                                good_cnt++;
 -                      l++;
 -                      if (l == rx_ring->count)
 -                              l = 0;
 -                      /* time + 20 msecs (200 msecs on 2.4) is more than
 -                       * enough time to complete the receives, if it's
 -                       * exceeded, break and error off
 -                       */
 -              } while (good_cnt < 64 && jiffies < (time + 20));
 +              }
 +
                if (good_cnt != 64) {
 -                      ret_val = 13; /* ret_val is the same as mis-compare */
 +                      ret_val = 12;
                        break;
                }
 -              if (jiffies >= (time + 20)) {
 -                      ret_val = 14; /* error code for time out error */
 +
 +              /* allow 200 milliseconds for packets to go from tx to rx */
 +              msleep(200);
 +
 +              good_cnt = igb_clean_test_rings(rx_ring, tx_ring, size);
 +              if (good_cnt != 64) {
 +                      ret_val = 13;
                        break;
                }
        } /* end loop count loop */
 +
 +      /* free the original skb */
 +      kfree_skb(skb);
 +
        return ret_val;
  }
  
@@@ -1625,7 -1686,8 +1626,7 @@@ static int igb_link_test(struct igb_ada
                if (hw->mac.autoneg)
                        msleep(4000);
  
 -              if (!(rd32(E1000_STATUS) &
 -                    E1000_STATUS_LU))
 +              if (!(rd32(E1000_STATUS) & E1000_STATUS_LU))
                        *data = 1;
        }
        return *data;
@@@ -1807,6 -1869,7 +1808,6 @@@ static int igb_set_wol(struct net_devic
                adapter->wol |= E1000_WUFC_BC;
        if (wol->wolopts & WAKE_MAGIC)
                adapter->wol |= E1000_WUFC_MAG;
 -
        device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
  
        return 0;
@@@ -1819,19 -1882,12 +1820,19 @@@ static int igb_phys_id(struct net_devic
  {
        struct igb_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
 +      unsigned long timeout;
  
 -      if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
 -              data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
 +      timeout = data * 1000;
 +
 +      /*
 +       *  msleep_interruptable only accepts unsigned int so we are limited
 +       * in how long a duration we can wait
 +       */
 +      if (!timeout || timeout > UINT_MAX)
 +              timeout = UINT_MAX;
  
        igb_blink_led(hw);
 -      msleep_interruptible(data * 1000);
 +      msleep_interruptible(timeout);
  
        igb_led_off(hw);
        clear_bit(IGB_LED_ON, &adapter->led_status);
@@@ -1844,6 -1900,7 +1845,6 @@@ static int igb_set_coalesce(struct net_
                            struct ethtool_coalesce *ec)
  {
        struct igb_adapter *adapter = netdev_priv(netdev);
 -      struct e1000_hw *hw = &adapter->hw;
        int i;
  
        if ((ec->rx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
            (ec->rx_coalesce_usecs == 2))
                return -EINVAL;
  
 +      if ((ec->tx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
 +          ((ec->tx_coalesce_usecs > 3) &&
 +           (ec->tx_coalesce_usecs < IGB_MIN_ITR_USECS)) ||
 +          (ec->tx_coalesce_usecs == 2))
 +              return -EINVAL;
 +
 +      if ((adapter->flags & IGB_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs)
 +              return -EINVAL;
 +
        /* convert to rate of irq's per second */
 -      if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
 -              adapter->itr_setting = ec->rx_coalesce_usecs;
 -              adapter->itr = IGB_START_ITR;
 -      } else {
 -              adapter->itr_setting = ec->rx_coalesce_usecs << 2;
 -              adapter->itr = adapter->itr_setting;
 -      }
 +      if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3)
 +              adapter->rx_itr_setting = ec->rx_coalesce_usecs;
 +      else
 +              adapter->rx_itr_setting = ec->rx_coalesce_usecs << 2;
  
 -      for (i = 0; i < adapter->num_rx_queues; i++)
 -              wr32(adapter->rx_ring[i].itr_register, adapter->itr);
 +      /* convert to rate of irq's per second */
 +      if (adapter->flags & IGB_FLAG_QUEUE_PAIRS)
 +              adapter->tx_itr_setting = adapter->rx_itr_setting;
 +      else if (ec->tx_coalesce_usecs && ec->tx_coalesce_usecs <= 3)
 +              adapter->tx_itr_setting = ec->tx_coalesce_usecs;
 +      else
 +              adapter->tx_itr_setting = ec->tx_coalesce_usecs << 2;
 +
 +      for (i = 0; i < adapter->num_q_vectors; i++) {
 +              struct igb_q_vector *q_vector = adapter->q_vector[i];
 +              if (q_vector->rx_ring)
 +                      q_vector->itr_val = adapter->rx_itr_setting;
 +              else
 +                      q_vector->itr_val = adapter->tx_itr_setting;
 +              if (q_vector->itr_val && q_vector->itr_val <= 3)
 +                      q_vector->itr_val = IGB_START_ITR;
 +              q_vector->set_itr = 1;
 +      }
  
        return 0;
  }
@@@ -1894,21 -1929,15 +1895,21 @@@ static int igb_get_coalesce(struct net_
  {
        struct igb_adapter *adapter = netdev_priv(netdev);
  
 -      if (adapter->itr_setting <= 3)
 -              ec->rx_coalesce_usecs = adapter->itr_setting;
 +      if (adapter->rx_itr_setting <= 3)
 +              ec->rx_coalesce_usecs = adapter->rx_itr_setting;
        else
 -              ec->rx_coalesce_usecs = adapter->itr_setting >> 2;
 +              ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2;
 +
 +      if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS)) {
 +              if (adapter->tx_itr_setting <= 3)
 +                      ec->tx_coalesce_usecs = adapter->tx_itr_setting;
 +              else
 +                      ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2;
 +      }
  
        return 0;
  }
  
 -
  static int igb_nway_reset(struct net_device *netdev)
  {
        struct igb_adapter *adapter = netdev_priv(netdev);
@@@ -1933,32 -1962,31 +1934,32 @@@ static void igb_get_ethtool_stats(struc
                                  struct ethtool_stats *stats, u64 *data)
  {
        struct igb_adapter *adapter = netdev_priv(netdev);
 +      struct net_device_stats *net_stats = &netdev->stats;
        u64 *queue_stat;
 -      int stat_count_tx = sizeof(struct igb_tx_queue_stats) / sizeof(u64);
 -      int stat_count_rx = sizeof(struct igb_rx_queue_stats) / sizeof(u64);
 -      int j;
 -      int i;
 +      int i, j, k;
 +      char *p;
  
        igb_update_stats(adapter);
 +
        for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
 -              char *p = (char *)adapter+igb_gstrings_stats[i].stat_offset;
 +              p = (char *)adapter + igb_gstrings_stats[i].stat_offset;
                data[i] = (igb_gstrings_stats[i].sizeof_stat ==
                        sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
        }
 +      for (j = 0; j < IGB_NETDEV_STATS_LEN; j++, i++) {
 +              p = (char *)net_stats + igb_gstrings_net_stats[j].stat_offset;
 +              data[i] = (igb_gstrings_net_stats[j].sizeof_stat ==
 +                      sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
 +      }
        for (j = 0; j < adapter->num_tx_queues; j++) {
 -              int k;
                queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats;
 -              for (k = 0; k < stat_count_tx; k++)
 -                      data[i + k] = queue_stat[k];
 -              i += k;
 +              for (k = 0; k < IGB_TX_QUEUE_STATS_LEN; k++, i++)
 +                      data[i] = queue_stat[k];
        }
        for (j = 0; j < adapter->num_rx_queues; j++) {
 -              int k;
                queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats;
 -              for (k = 0; k < stat_count_rx; k++)
 -                      data[i + k] = queue_stat[k];
 -              i += k;
 +              for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++)
 +                      data[i] = queue_stat[k];
        }
  }
  
@@@ -1979,18 -2007,11 +1980,18 @@@ static void igb_get_strings(struct net_
                               ETH_GSTRING_LEN);
                        p += ETH_GSTRING_LEN;
                }
 +              for (i = 0; i < IGB_NETDEV_STATS_LEN; i++) {
 +                      memcpy(p, igb_gstrings_net_stats[i].stat_string,
 +                             ETH_GSTRING_LEN);
 +                      p += ETH_GSTRING_LEN;
 +              }
                for (i = 0; i < adapter->num_tx_queues; i++) {
                        sprintf(p, "tx_queue_%u_packets", i);
                        p += ETH_GSTRING_LEN;
                        sprintf(p, "tx_queue_%u_bytes", i);
                        p += ETH_GSTRING_LEN;
 +                      sprintf(p, "tx_queue_%u_restart", i);
 +                      p += ETH_GSTRING_LEN;
                }
                for (i = 0; i < adapter->num_rx_queues; i++) {
                        sprintf(p, "rx_queue_%u_packets", i);
                        p += ETH_GSTRING_LEN;
                        sprintf(p, "rx_queue_%u_drops", i);
                        p += ETH_GSTRING_LEN;
 +                      sprintf(p, "rx_queue_%u_csum_err", i);
 +                      p += ETH_GSTRING_LEN;
 +                      sprintf(p, "rx_queue_%u_alloc_failed", i);
 +                      p += ETH_GSTRING_LEN;
                }
  /*            BUG_ON(p - data != IGB_STATS_LEN * ETH_GSTRING_LEN); */
                break;
index 99f737223b100ea74718c478199d7910969d226e,0000000000000000000000000000000000000000..d31c134981fda6fa69c6c14be0ce87eb42ef0ae3
mode 100644,000000..100644
--- /dev/null
@@@ -1,752 -1,0 +1,752 @@@
-       mutex_lock(&efx->i2c_adap.bus_lock);
 +/****************************************************************************
 + * Driver for Solarflare Solarstorm network controllers and boards
 + * Copyright 2007-2008 Solarflare Communications Inc.
 + *
 + * This program is free software; you can redistribute it and/or modify it
 + * under the terms of the GNU General Public License version 2 as published
 + * by the Free Software Foundation, incorporated herein by reference.
 + */
 +
 +#include <linux/rtnetlink.h>
 +
 +#include "net_driver.h"
 +#include "phy.h"
 +#include "efx.h"
 +#include "falcon.h"
 +#include "regs.h"
 +#include "io.h"
 +#include "workarounds.h"
 +
 +/* Macros for unpacking the board revision */
 +/* The revision info is in host byte order. */
 +#define FALCON_BOARD_TYPE(_rev) (_rev >> 8)
 +#define FALCON_BOARD_MAJOR(_rev) ((_rev >> 4) & 0xf)
 +#define FALCON_BOARD_MINOR(_rev) (_rev & 0xf)
 +
 +/* Board types */
 +#define FALCON_BOARD_SFE4001 0x01
 +#define FALCON_BOARD_SFE4002 0x02
 +#define FALCON_BOARD_SFN4111T 0x51
 +#define FALCON_BOARD_SFN4112F 0x52
 +
 +/* Blink support. If the PHY has no auto-blink mode so we hang it off a timer */
 +#define BLINK_INTERVAL (HZ/2)
 +
 +static void blink_led_timer(unsigned long context)
 +{
 +      struct efx_nic *efx = (struct efx_nic *)context;
 +      struct efx_board *board = &efx->board_info;
 +
 +      board->set_id_led(efx, board->blink_state);
 +      board->blink_state = !board->blink_state;
 +      if (board->blink_resubmit)
 +              mod_timer(&board->blink_timer, jiffies + BLINK_INTERVAL);
 +}
 +
 +static void board_blink(struct efx_nic *efx, bool blink)
 +{
 +      struct efx_board *board = &efx->board_info;
 +
 +      /* The rtnl mutex serialises all ethtool ioctls, so
 +       * nothing special needs doing here. */
 +      if (blink) {
 +              board->blink_resubmit = true;
 +              board->blink_state = false;
 +              setup_timer(&board->blink_timer, blink_led_timer,
 +                          (unsigned long)efx);
 +              mod_timer(&board->blink_timer, jiffies + BLINK_INTERVAL);
 +      } else {
 +              board->blink_resubmit = false;
 +              if (board->blink_timer.function)
 +                      del_timer_sync(&board->blink_timer);
 +              board->init_leds(efx);
 +      }
 +}
 +
 +/*****************************************************************************
 + * Support for LM87 sensor chip used on several boards
 + */
 +#define LM87_REG_ALARMS1              0x41
 +#define LM87_REG_ALARMS2              0x42
 +#define LM87_IN_LIMITS(nr, _min, _max)                        \
 +      0x2B + (nr) * 2, _max, 0x2C + (nr) * 2, _min
 +#define LM87_AIN_LIMITS(nr, _min, _max)                       \
 +      0x3B + (nr), _max, 0x1A + (nr), _min
 +#define LM87_TEMP_INT_LIMITS(_min, _max)              \
 +      0x39, _max, 0x3A, _min
 +#define LM87_TEMP_EXT1_LIMITS(_min, _max)             \
 +      0x37, _max, 0x38, _min
 +
 +#define LM87_ALARM_TEMP_INT           0x10
 +#define LM87_ALARM_TEMP_EXT1          0x20
 +
 +#if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE)
 +
 +static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
 +                       const u8 *reg_values)
 +{
 +      struct i2c_client *client = i2c_new_device(&efx->i2c_adap, info);
 +      int rc;
 +
 +      if (!client)
 +              return -EIO;
 +
 +      while (*reg_values) {
 +              u8 reg = *reg_values++;
 +              u8 value = *reg_values++;
 +              rc = i2c_smbus_write_byte_data(client, reg, value);
 +              if (rc)
 +                      goto err;
 +      }
 +
 +      efx->board_info.hwmon_client = client;
 +      return 0;
 +
 +err:
 +      i2c_unregister_device(client);
 +      return rc;
 +}
 +
 +static void efx_fini_lm87(struct efx_nic *efx)
 +{
 +      i2c_unregister_device(efx->board_info.hwmon_client);
 +}
 +
 +static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
 +{
 +      struct i2c_client *client = efx->board_info.hwmon_client;
 +      s32 alarms1, alarms2;
 +
 +      /* If link is up then do not monitor temperature */
 +      if (EFX_WORKAROUND_7884(efx) && efx->link_up)
 +              return 0;
 +
 +      alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
 +      alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
 +      if (alarms1 < 0)
 +              return alarms1;
 +      if (alarms2 < 0)
 +              return alarms2;
 +      alarms1 &= mask;
 +      alarms2 &= mask >> 8;
 +      if (alarms1 || alarms2) {
 +              EFX_ERR(efx,
 +                      "LM87 detected a hardware failure (status %02x:%02x)"
 +                      "%s%s\n",
 +                      alarms1, alarms2,
 +                      (alarms1 & LM87_ALARM_TEMP_INT) ? " INTERNAL" : "",
 +                      (alarms1 & LM87_ALARM_TEMP_EXT1) ? " EXTERNAL" : "");
 +              return -ERANGE;
 +      }
 +
 +      return 0;
 +}
 +
 +#else /* !CONFIG_SENSORS_LM87 */
 +
 +static inline int
 +efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
 +            const u8 *reg_values)
 +{
 +      return 0;
 +}
 +static inline void efx_fini_lm87(struct efx_nic *efx)
 +{
 +}
 +static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask)
 +{
 +      return 0;
 +}
 +
 +#endif /* CONFIG_SENSORS_LM87 */
 +
 +/*****************************************************************************
 + * Support for the SFE4001 and SFN4111T NICs.
 + *
 + * The SFE4001 does not power-up fully at reset due to its high power
 + * consumption.  We control its power via a PCA9539 I/O expander.
 + * Both boards have a MAX6647 temperature monitor which we expose to
 + * the lm90 driver.
 + *
 + * This also provides minimal support for reflashing the PHY, which is
 + * initiated by resetting it with the FLASH_CFG_1 pin pulled down.
 + * On SFE4001 rev A2 and later this is connected to the 3V3X output of
 + * the IO-expander; on the SFN4111T it is connected to Falcon's GPIO3.
 + * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually
 + * exclusive with the network device being open.
 + */
 +
 +/**************************************************************************
 + * Support for I2C IO Expander device on SFE40001
 + */
 +#define       PCA9539 0x74
 +
 +#define       P0_IN 0x00
 +#define       P0_OUT 0x02
 +#define       P0_INVERT 0x04
 +#define       P0_CONFIG 0x06
 +
 +#define       P0_EN_1V0X_LBN 0
 +#define       P0_EN_1V0X_WIDTH 1
 +#define       P0_EN_1V2_LBN 1
 +#define       P0_EN_1V2_WIDTH 1
 +#define       P0_EN_2V5_LBN 2
 +#define       P0_EN_2V5_WIDTH 1
 +#define       P0_EN_3V3X_LBN 3
 +#define       P0_EN_3V3X_WIDTH 1
 +#define       P0_EN_5V_LBN 4
 +#define       P0_EN_5V_WIDTH 1
 +#define       P0_SHORTEN_JTAG_LBN 5
 +#define       P0_SHORTEN_JTAG_WIDTH 1
 +#define       P0_X_TRST_LBN 6
 +#define       P0_X_TRST_WIDTH 1
 +#define       P0_DSP_RESET_LBN 7
 +#define       P0_DSP_RESET_WIDTH 1
 +
 +#define       P1_IN 0x01
 +#define       P1_OUT 0x03
 +#define       P1_INVERT 0x05
 +#define       P1_CONFIG 0x07
 +
 +#define       P1_AFE_PWD_LBN 0
 +#define       P1_AFE_PWD_WIDTH 1
 +#define       P1_DSP_PWD25_LBN 1
 +#define       P1_DSP_PWD25_WIDTH 1
 +#define       P1_RESERVED_LBN 2
 +#define       P1_RESERVED_WIDTH 2
 +#define       P1_SPARE_LBN 4
 +#define       P1_SPARE_WIDTH 4
 +
 +/* Temperature Sensor */
 +#define MAX664X_REG_RSL               0x02
 +#define MAX664X_REG_WLHO      0x0B
 +
 +static void sfe4001_poweroff(struct efx_nic *efx)
 +{
 +      struct i2c_client *ioexp_client = efx->board_info.ioexp_client;
 +      struct i2c_client *hwmon_client = efx->board_info.hwmon_client;
 +
 +      /* Turn off all power rails and disable outputs */
 +      i2c_smbus_write_byte_data(ioexp_client, P0_OUT, 0xff);
 +      i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 0xff);
 +      i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff);
 +
 +      /* Clear any over-temperature alert */
 +      i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
 +}
 +
 +static int sfe4001_poweron(struct efx_nic *efx)
 +{
 +      struct i2c_client *hwmon_client = efx->board_info.hwmon_client;
 +      struct i2c_client *ioexp_client = efx->board_info.ioexp_client;
 +      unsigned int i, j;
 +      int rc;
 +      u8 out;
 +
 +      /* Clear any previous over-temperature alert */
 +      rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
 +      if (rc < 0)
 +              return rc;
 +
 +      /* Enable port 0 and port 1 outputs on IO expander */
 +      rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00);
 +      if (rc)
 +              return rc;
 +      rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG,
 +                                     0xff & ~(1 << P1_SPARE_LBN));
 +      if (rc)
 +              goto fail_on;
 +
 +      /* If PHY power is on, turn it all off and wait 1 second to
 +       * ensure a full reset.
 +       */
 +      rc = i2c_smbus_read_byte_data(ioexp_client, P0_OUT);
 +      if (rc < 0)
 +              goto fail_on;
 +      out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) |
 +                     (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) |
 +                     (0 << P0_EN_1V0X_LBN));
 +      if (rc != out) {
 +              EFX_INFO(efx, "power-cycling PHY\n");
 +              rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
 +              if (rc)
 +                      goto fail_on;
 +              schedule_timeout_uninterruptible(HZ);
 +      }
 +
 +      for (i = 0; i < 20; ++i) {
 +              /* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */
 +              out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) |
 +                             (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) |
 +                             (1 << P0_X_TRST_LBN));
 +              if (efx->phy_mode & PHY_MODE_SPECIAL)
 +                      out |= 1 << P0_EN_3V3X_LBN;
 +
 +              rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
 +              if (rc)
 +                      goto fail_on;
 +              msleep(10);
 +
 +              /* Turn on 1V power rail */
 +              out &= ~(1 << P0_EN_1V0X_LBN);
 +              rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
 +              if (rc)
 +                      goto fail_on;
 +
 +              EFX_INFO(efx, "waiting for DSP boot (attempt %d)...\n", i);
 +
 +              /* In flash config mode, DSP does not turn on AFE, so
 +               * just wait 1 second.
 +               */
 +              if (efx->phy_mode & PHY_MODE_SPECIAL) {
 +                      schedule_timeout_uninterruptible(HZ);
 +                      return 0;
 +              }
 +
 +              for (j = 0; j < 10; ++j) {
 +                      msleep(100);
 +
 +                      /* Check DSP has asserted AFE power line */
 +                      rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN);
 +                      if (rc < 0)
 +                              goto fail_on;
 +                      if (rc & (1 << P1_AFE_PWD_LBN))
 +                              return 0;
 +              }
 +      }
 +
 +      EFX_INFO(efx, "timed out waiting for DSP boot\n");
 +      rc = -ETIMEDOUT;
 +fail_on:
 +      sfe4001_poweroff(efx);
 +      return rc;
 +}
 +
 +static int sfn4111t_reset(struct efx_nic *efx)
 +{
 +      efx_oword_t reg;
 +
 +      /* GPIO 3 and the GPIO register are shared with I2C, so block that */
-       mutex_unlock(&efx->i2c_adap.bus_lock);
++      i2c_lock_adapter(&efx->i2c_adap);
 +
 +      /* Pull RST_N (GPIO 2) low then let it up again, setting the
 +       * FLASH_CFG_1 strap (GPIO 3) appropriately.  Only change the
 +       * output enables; the output levels should always be 0 (low)
 +       * and we rely on external pull-ups. */
 +      efx_reado(efx, &reg, FR_AB_GPIO_CTL);
 +      EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, true);
 +      efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
 +      msleep(1000);
 +      EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, false);
 +      EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN,
 +                          !!(efx->phy_mode & PHY_MODE_SPECIAL));
 +      efx_writeo(efx, &reg, FR_AB_GPIO_CTL);
 +      msleep(1);
 +
++      i2c_unlock_adapter(&efx->i2c_adap);
 +
 +      ssleep(1);
 +      return 0;
 +}
 +
 +static ssize_t show_phy_flash_cfg(struct device *dev,
 +                                struct device_attribute *attr, char *buf)
 +{
 +      struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
 +      return sprintf(buf, "%d\n", !!(efx->phy_mode & PHY_MODE_SPECIAL));
 +}
 +
 +static ssize_t set_phy_flash_cfg(struct device *dev,
 +                               struct device_attribute *attr,
 +                               const char *buf, size_t count)
 +{
 +      struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
 +      enum efx_phy_mode old_mode, new_mode;
 +      int err;
 +
 +      rtnl_lock();
 +      old_mode = efx->phy_mode;
 +      if (count == 0 || *buf == '0')
 +              new_mode = old_mode & ~PHY_MODE_SPECIAL;
 +      else
 +              new_mode = PHY_MODE_SPECIAL;
 +      if (old_mode == new_mode) {
 +              err = 0;
 +      } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
 +              err = -EBUSY;
 +      } else {
 +              /* Reset the PHY, reconfigure the MAC and enable/disable
 +               * MAC stats accordingly. */
 +              efx->phy_mode = new_mode;
 +              if (new_mode & PHY_MODE_SPECIAL)
 +                      efx_stats_disable(efx);
 +              if (efx->board_info.type == FALCON_BOARD_SFE4001)
 +                      err = sfe4001_poweron(efx);
 +              else
 +                      err = sfn4111t_reset(efx);
 +              efx_reconfigure_port(efx);
 +              if (!(new_mode & PHY_MODE_SPECIAL))
 +                      efx_stats_enable(efx);
 +      }
 +      rtnl_unlock();
 +
 +      return err ? err : count;
 +}
 +
 +static DEVICE_ATTR(phy_flash_cfg, 0644, show_phy_flash_cfg, set_phy_flash_cfg);
 +
 +static void sfe4001_fini(struct efx_nic *efx)
 +{
 +      EFX_INFO(efx, "%s\n", __func__);
 +
 +      device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
 +      sfe4001_poweroff(efx);
 +      i2c_unregister_device(efx->board_info.ioexp_client);
 +      i2c_unregister_device(efx->board_info.hwmon_client);
 +}
 +
 +static int sfe4001_check_hw(struct efx_nic *efx)
 +{
 +      s32 status;
 +
 +      /* If XAUI link is up then do not monitor */
 +      if (EFX_WORKAROUND_7884(efx) && efx->mac_up)
 +              return 0;
 +
 +      /* Check the powered status of the PHY. Lack of power implies that
 +       * the MAX6647 has shut down power to it, probably due to a temp.
 +       * alarm. Reading the power status rather than the MAX6647 status
 +       * directly because the later is read-to-clear and would thus
 +       * start to power up the PHY again when polled, causing us to blip
 +       * the power undesirably.
 +       * We know we can read from the IO expander because we did
 +       * it during power-on. Assume failure now is bad news. */
 +      status = i2c_smbus_read_byte_data(efx->board_info.ioexp_client, P1_IN);
 +      if (status >= 0 &&
 +          (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0)
 +              return 0;
 +
 +      /* Use board power control, not PHY power control */
 +      sfe4001_poweroff(efx);
 +      efx->phy_mode = PHY_MODE_OFF;
 +
 +      return (status < 0) ? -EIO : -ERANGE;
 +}
 +
 +static struct i2c_board_info sfe4001_hwmon_info = {
 +      I2C_BOARD_INFO("max6647", 0x4e),
 +};
 +
 +/* This board uses an I2C expander to provider power to the PHY, which needs to
 + * be turned on before the PHY can be used.
 + * Context: Process context, rtnl lock held
 + */
 +static int sfe4001_init(struct efx_nic *efx)
 +{
 +      int rc;
 +
 +#if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE)
 +      efx->board_info.hwmon_client =
 +              i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
 +#else
 +      efx->board_info.hwmon_client =
 +              i2c_new_dummy(&efx->i2c_adap, sfe4001_hwmon_info.addr);
 +#endif
 +      if (!efx->board_info.hwmon_client)
 +              return -EIO;
 +
 +      /* Raise board/PHY high limit from 85 to 90 degrees Celsius */
 +      rc = i2c_smbus_write_byte_data(efx->board_info.hwmon_client,
 +                                     MAX664X_REG_WLHO, 90);
 +      if (rc)
 +              goto fail_hwmon;
 +
 +      efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
 +      if (!efx->board_info.ioexp_client) {
 +              rc = -EIO;
 +              goto fail_hwmon;
 +      }
 +
 +      /* 10Xpress has fixed-function LED pins, so there is no board-specific
 +       * blink code. */
 +      efx->board_info.blink = tenxpress_phy_blink;
 +
 +      efx->board_info.monitor = sfe4001_check_hw;
 +      efx->board_info.fini = sfe4001_fini;
 +
 +      if (efx->phy_mode & PHY_MODE_SPECIAL) {
 +              /* PHY won't generate a 156.25 MHz clock and MAC stats fetch
 +               * will fail. */
 +              efx_stats_disable(efx);
 +      }
 +      rc = sfe4001_poweron(efx);
 +      if (rc)
 +              goto fail_ioexp;
 +
 +      rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
 +      if (rc)
 +              goto fail_on;
 +
 +      EFX_INFO(efx, "PHY is powered on\n");
 +      return 0;
 +
 +fail_on:
 +      sfe4001_poweroff(efx);
 +fail_ioexp:
 +      i2c_unregister_device(efx->board_info.ioexp_client);
 +fail_hwmon:
 +      i2c_unregister_device(efx->board_info.hwmon_client);
 +      return rc;
 +}
 +
 +static int sfn4111t_check_hw(struct efx_nic *efx)
 +{
 +      s32 status;
 +
 +      /* If XAUI link is up then do not monitor */
 +      if (EFX_WORKAROUND_7884(efx) && efx->mac_up)
 +              return 0;
 +
 +      /* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */
 +      status = i2c_smbus_read_byte_data(efx->board_info.hwmon_client,
 +                                        MAX664X_REG_RSL);
 +      if (status < 0)
 +              return -EIO;
 +      if (status & 0x57)
 +              return -ERANGE;
 +      return 0;
 +}
 +
 +static void sfn4111t_fini(struct efx_nic *efx)
 +{
 +      EFX_INFO(efx, "%s\n", __func__);
 +
 +      device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
 +      i2c_unregister_device(efx->board_info.hwmon_client);
 +}
 +
 +static struct i2c_board_info sfn4111t_a0_hwmon_info = {
 +      I2C_BOARD_INFO("max6647", 0x4e),
 +};
 +
 +static struct i2c_board_info sfn4111t_r5_hwmon_info = {
 +      I2C_BOARD_INFO("max6646", 0x4d),
 +};
 +
 +static int sfn4111t_init(struct efx_nic *efx)
 +{
 +      int i = 0;
 +      int rc;
 +
 +      efx->board_info.hwmon_client =
 +              i2c_new_device(&efx->i2c_adap,
 +                             (efx->board_info.minor < 5) ?
 +                             &sfn4111t_a0_hwmon_info :
 +                             &sfn4111t_r5_hwmon_info);
 +      if (!efx->board_info.hwmon_client)
 +              return -EIO;
 +
 +      efx->board_info.blink = tenxpress_phy_blink;
 +      efx->board_info.monitor = sfn4111t_check_hw;
 +      efx->board_info.fini = sfn4111t_fini;
 +
 +      rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
 +      if (rc)
 +              goto fail_hwmon;
 +
 +      do {
 +              if (efx->phy_mode & PHY_MODE_SPECIAL) {
 +                      /* PHY may not generate a 156.25 MHz clock and MAC
 +                       * stats fetch will fail. */
 +                      efx_stats_disable(efx);
 +                      sfn4111t_reset(efx);
 +              }
 +              rc = sft9001_wait_boot(efx);
 +              if (rc == 0)
 +                      return 0;
 +              efx->phy_mode = PHY_MODE_SPECIAL;
 +      } while (rc == -EINVAL && ++i < 2);
 +
 +      device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
 +fail_hwmon:
 +      i2c_unregister_device(efx->board_info.hwmon_client);
 +      return rc;
 +}
 +
 +/*****************************************************************************
 + * Support for the SFE4002
 + *
 + */
 +static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */
 +
 +static const u8 sfe4002_lm87_regs[] = {
 +      LM87_IN_LIMITS(0, 0x83, 0x91),          /* 2.5V:  1.8V +/- 5% */
 +      LM87_IN_LIMITS(1, 0x51, 0x5a),          /* Vccp1: 1.2V +/- 5% */
 +      LM87_IN_LIMITS(2, 0xb6, 0xca),          /* 3.3V:  3.3V +/- 5% */
 +      LM87_IN_LIMITS(3, 0xb0, 0xc9),          /* 5V:    4.6-5.2V */
 +      LM87_IN_LIMITS(4, 0xb0, 0xe0),          /* 12V:   11-14V */
 +      LM87_IN_LIMITS(5, 0x44, 0x4b),          /* Vccp2: 1.0V +/- 5% */
 +      LM87_AIN_LIMITS(0, 0xa0, 0xb2),         /* AIN1:  1.66V +/- 5% */
 +      LM87_AIN_LIMITS(1, 0x91, 0xa1),         /* AIN2:  1.5V +/- 5% */
 +      LM87_TEMP_INT_LIMITS(10, 60),           /* board */
 +      LM87_TEMP_EXT1_LIMITS(10, 70),          /* Falcon */
 +      0
 +};
 +
 +static struct i2c_board_info sfe4002_hwmon_info = {
 +      I2C_BOARD_INFO("lm87", 0x2e),
 +      .platform_data  = &sfe4002_lm87_channel,
 +};
 +
 +/****************************************************************************/
 +/* LED allocations. Note that on rev A0 boards the schematic and the reality
 + * differ: red and green are swapped. Below is the fixed (A1) layout (there
 + * are only 3 A0 boards in existence, so no real reason to make this
 + * conditional).
 + */
 +#define SFE4002_FAULT_LED (2) /* Red */
 +#define SFE4002_RX_LED    (0) /* Green */
 +#define SFE4002_TX_LED    (1) /* Amber */
 +
 +static void sfe4002_init_leds(struct efx_nic *efx)
 +{
 +      /* Set the TX and RX LEDs to reflect status and activity, and the
 +       * fault LED off */
 +      falcon_qt202x_set_led(efx, SFE4002_TX_LED,
 +                            QUAKE_LED_TXLINK | QUAKE_LED_LINK_ACTSTAT);
 +      falcon_qt202x_set_led(efx, SFE4002_RX_LED,
 +                            QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT);
 +      falcon_qt202x_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
 +}
 +
 +static void sfe4002_set_id_led(struct efx_nic *efx, bool state)
 +{
 +      falcon_qt202x_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON :
 +                            QUAKE_LED_OFF);
 +}
 +
 +static int sfe4002_check_hw(struct efx_nic *efx)
 +{
 +      /* A0 board rev. 4002s report a temperature fault the whole time
 +       * (bad sensor) so we mask it out. */
 +      unsigned alarm_mask =
 +              (efx->board_info.major == 0 && efx->board_info.minor == 0) ?
 +              ~LM87_ALARM_TEMP_EXT1 : ~0;
 +
 +      return efx_check_lm87(efx, alarm_mask);
 +}
 +
 +static int sfe4002_init(struct efx_nic *efx)
 +{
 +      int rc = efx_init_lm87(efx, &sfe4002_hwmon_info, sfe4002_lm87_regs);
 +      if (rc)
 +              return rc;
 +      efx->board_info.monitor = sfe4002_check_hw;
 +      efx->board_info.init_leds = sfe4002_init_leds;
 +      efx->board_info.set_id_led = sfe4002_set_id_led;
 +      efx->board_info.blink = board_blink;
 +      efx->board_info.fini = efx_fini_lm87;
 +      return 0;
 +}
 +
 +/*****************************************************************************
 + * Support for the SFN4112F
 + *
 + */
 +static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */
 +
 +static const u8 sfn4112f_lm87_regs[] = {
 +      LM87_IN_LIMITS(0, 0x83, 0x91),          /* 2.5V:  1.8V +/- 5% */
 +      LM87_IN_LIMITS(1, 0x51, 0x5a),          /* Vccp1: 1.2V +/- 5% */
 +      LM87_IN_LIMITS(2, 0xb6, 0xca),          /* 3.3V:  3.3V +/- 5% */
 +      LM87_IN_LIMITS(4, 0xb0, 0xe0),          /* 12V:   11-14V */
 +      LM87_IN_LIMITS(5, 0x44, 0x4b),          /* Vccp2: 1.0V +/- 5% */
 +      LM87_AIN_LIMITS(1, 0x91, 0xa1),         /* AIN2:  1.5V +/- 5% */
 +      LM87_TEMP_INT_LIMITS(10, 60),           /* board */
 +      LM87_TEMP_EXT1_LIMITS(10, 70),          /* Falcon */
 +      0
 +};
 +
 +static struct i2c_board_info sfn4112f_hwmon_info = {
 +      I2C_BOARD_INFO("lm87", 0x2e),
 +      .platform_data  = &sfn4112f_lm87_channel,
 +};
 +
 +#define SFN4112F_ACT_LED      0
 +#define SFN4112F_LINK_LED     1
 +
 +static void sfn4112f_init_leds(struct efx_nic *efx)
 +{
 +      falcon_qt202x_set_led(efx, SFN4112F_ACT_LED,
 +                            QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACT);
 +      falcon_qt202x_set_led(efx, SFN4112F_LINK_LED,
 +                            QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT);
 +}
 +
 +static void sfn4112f_set_id_led(struct efx_nic *efx, bool state)
 +{
 +      falcon_qt202x_set_led(efx, SFN4112F_LINK_LED,
 +                            state ? QUAKE_LED_ON : QUAKE_LED_OFF);
 +}
 +
 +static int sfn4112f_check_hw(struct efx_nic *efx)
 +{
 +      /* Mask out unused sensors */
 +      return efx_check_lm87(efx, ~0x48);
 +}
 +
 +static int sfn4112f_init(struct efx_nic *efx)
 +{
 +      int rc = efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs);
 +      if (rc)
 +              return rc;
 +      efx->board_info.monitor = sfn4112f_check_hw;
 +      efx->board_info.init_leds = sfn4112f_init_leds;
 +      efx->board_info.set_id_led = sfn4112f_set_id_led;
 +      efx->board_info.blink = board_blink;
 +      efx->board_info.fini = efx_fini_lm87;
 +      return 0;
 +}
 +
 +/* This will get expanded as board-specific details get moved out of the
 + * PHY drivers. */
 +struct falcon_board_data {
 +      u8 type;
 +      const char *ref_model;
 +      const char *gen_type;
 +      int (*init) (struct efx_nic *nic);
 +};
 +
 +
 +static struct falcon_board_data board_data[] = {
 +      { FALCON_BOARD_SFE4001, "SFE4001", "10GBASE-T adapter", sfe4001_init },
 +      { FALCON_BOARD_SFE4002, "SFE4002", "XFP adapter", sfe4002_init },
 +      { FALCON_BOARD_SFN4111T, "SFN4111T", "100/1000/10GBASE-T adapter",
 +        sfn4111t_init },
 +      { FALCON_BOARD_SFN4112F, "SFN4112F", "SFP+ adapter",
 +        sfn4112f_init },
 +};
 +
 +void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
 +{
 +      struct falcon_board_data *data = NULL;
 +      int i;
 +
 +      efx->board_info.type = FALCON_BOARD_TYPE(revision_info);
 +      efx->board_info.major = FALCON_BOARD_MAJOR(revision_info);
 +      efx->board_info.minor = FALCON_BOARD_MINOR(revision_info);
 +
 +      for (i = 0; i < ARRAY_SIZE(board_data); i++)
 +              if (board_data[i].type == efx->board_info.type)
 +                      data = &board_data[i];
 +
 +      if (data) {
 +              EFX_INFO(efx, "board is %s rev %c%d\n",
 +                       (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
 +                       ? data->ref_model : data->gen_type,
 +                       'A' + efx->board_info.major, efx->board_info.minor);
 +              efx->board_info.init = data->init;
 +      } else {
 +              EFX_ERR(efx, "unknown board type %d\n", efx->board_info.type);
 +      }
 +}
diff --combined drivers/net/skge.c
index be28ebb3811c88e9f6c074c779f3f17c9a2a5268,8f5414348e8629569a6fa12ff08f710d425abe6a..ba5eb14094ef44ac17fd2ba43780863fe5a8019a
@@@ -37,6 -37,7 +37,7 @@@
  #include <linux/crc32.h>
  #include <linux/dma-mapping.h>
  #include <linux/debugfs.h>
+ #include <linux/sched.h>
  #include <linux/seq_file.h>
  #include <linux/mii.h>
  #include <asm/irq.h>
@@@ -3070,10 -3071,11 +3071,10 @@@ static struct sk_buff *skge_rx_get(stru
                goto error;
  
        if (len < RX_COPY_THRESHOLD) {
 -              skb = netdev_alloc_skb(dev, len + 2);
 +              skb = netdev_alloc_skb_ip_align(dev, len);
                if (!skb)
                        goto resubmit;
  
 -              skb_reserve(skb, 2);
                pci_dma_sync_single_for_cpu(skge->hw->pdev,
                                            pci_unmap_addr(e, mapaddr),
                                            len, PCI_DMA_FROMDEVICE);
                skge_rx_reuse(e, skge->rx_buf_size);
        } else {
                struct sk_buff *nskb;
 -              nskb = netdev_alloc_skb(dev, skge->rx_buf_size + NET_IP_ALIGN);
 +
 +              nskb = netdev_alloc_skb_ip_align(dev, skge->rx_buf_size);
                if (!nskb)
                        goto resubmit;
  
 -              skb_reserve(nskb, NET_IP_ALIGN);
                pci_unmap_single(skge->hw->pdev,
                                 pci_unmap_addr(e, mapaddr),
                                 pci_unmap_len(e, maplen),
diff --combined drivers/net/slip.c
index ccfe45924fd91746358a59ec543b630ec8ec0453,fe3cebb984deb028b8a2e6ac1b1a2e2ac25717a5..6640469b5d3b7b0429b37e7501993be0d743ddd8
@@@ -67,6 -67,7 +67,7 @@@
  #include <asm/system.h>
  #include <asm/uaccess.h>
  #include <linux/bitops.h>
+ #include <linux/sched.h>
  #include <linux/string.h>
  #include <linux/mm.h>
  #include <linux/interrupt.h>
@@@ -79,7 -80,6 +80,7 @@@
  #include <linux/rtnetlink.h>
  #include <linux/if_arp.h>
  #include <linux/if_slip.h>
 +#include <linux/compat.h>
  #include <linux/delay.h>
  #include <linux/init.h>
  #include "slip.h"
@@@ -1169,27 -1169,6 +1170,27 @@@ static int slip_ioctl(struct tty_struc
        }
  }
  
 +#ifdef CONFIG_COMPAT
 +static long slip_compat_ioctl(struct tty_struct *tty, struct file *file,
 +                                      unsigned int cmd, unsigned long arg)
 +{
 +      switch (cmd) {
 +      case SIOCGIFNAME:
 +      case SIOCGIFENCAP:
 +      case SIOCSIFENCAP:
 +      case SIOCSIFHWADDR:
 +      case SIOCSKEEPALIVE:
 +      case SIOCGKEEPALIVE:
 +      case SIOCSOUTFILL:
 +      case SIOCGOUTFILL:
 +              return slip_ioctl(tty, file, cmd,
 +                                (unsigned long)compat_ptr(arg));
 +      }
 +
 +      return -ENOIOCTLCMD;
 +}
 +#endif
 +
  /* VSV changes start here */
  #ifdef CONFIG_SLIP_SMART
  /* function do_ioctl called from net/core/dev.c
@@@ -1282,9 -1261,6 +1283,9 @@@ static struct tty_ldisc_ops sl_ldisc = 
        .close          = slip_close,
        .hangup         = slip_hangup,
        .ioctl          = slip_ioctl,
 +#ifdef CONFIG_COMPAT
 +      .compat_ioctl   = slip_compat_ioctl,
 +#endif
        .receive_buf    = slip_receive_buf,
        .write_wakeup   = slip_write_wakeup,
  };
diff --combined drivers/net/sungem.c
index d6f4faf5bbcb2f726cc41bad987fdb19ae7efcd7,61640b99b7055d07836c43a08bc311f40b548dc8..b571a1babab95e879be372bbb16bf760581559e8
@@@ -38,6 -38,7 +38,7 @@@
  #include <linux/interrupt.h>
  #include <linux/ioport.h>
  #include <linux/in.h>
+ #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/string.h>
  #include <linux/delay.h>
@@@ -1033,8 -1034,10 +1034,8 @@@ static netdev_tx_t gem_start_xmit(struc
                        (csum_stuff_off << 21));
        }
  
 -      local_irq_save(flags);
 -      if (!spin_trylock(&gp->tx_lock)) {
 +      if (!spin_trylock_irqsave(&gp->tx_lock, flags)) {
                /* Tell upper layer to requeue */
 -              local_irq_restore(flags);
                return NETDEV_TX_LOCKED;
        }
        /* We raced with gem_do_stop() */
@@@ -2060,7 -2063,15 +2061,15 @@@ static int gem_check_invariants(struct 
                mif_cfg &= ~MIF_CFG_PSELECT;
                writel(mif_cfg, gp->regs + MIF_CFG);
        } else {
-               gp->phy_type = phy_serialink;
+ #ifdef CONFIG_SPARC
+               const char *p;
+               p = of_get_property(gp->of_node, "shared-pins", NULL);
+               if (p && !strcmp(p, "serdes"))
+                       gp->phy_type = phy_serdes;
+               else
+ #endif
+                       gp->phy_type = phy_serialink;
        }
        if (gp->phy_type == phy_mii_mdio1 ||
            gp->phy_type == phy_mii_mdio0) {
diff --combined drivers/net/typhoon.c
index 4b75410244240a1b01a932e79d78f919408ec23b,5921f5bdd764e57d72184142134cfdd588e40d9c..079a97000e5bf21de3ba65dde7ddf6af8ed91ca0
@@@ -108,6 -108,7 +108,7 @@@ static const int multicast_filter_limi
  
  #include <linux/module.h>
  #include <linux/kernel.h>
+ #include <linux/sched.h>
  #include <linux/string.h>
  #include <linux/timer.h>
  #include <linux/errno.h>
@@@ -2150,7 -2151,7 +2151,7 @@@ typhoon_open(struct net_device *dev
                goto out_sleep;
        }
  
 -      err = request_irq(dev->irq, &typhoon_interrupt, IRQF_SHARED,
 +      err = request_irq(dev->irq, typhoon_interrupt, IRQF_SHARED,
                                dev->name, dev);
        if(err < 0)
                goto out_sleep;
diff --combined drivers/net/virtio_net.c
index 22a8ca5d67d5e20e95003fd2eaa389a8af1e137b,b9e002fccbca22e20541136a3779c9f56bc2220c..74636c5c41f02df12e58148c6ef284a4c9a729bd
@@@ -22,7 -22,6 +22,6 @@@
  #include <linux/ethtool.h>
  #include <linux/module.h>
  #include <linux/virtio.h>
- #include <linux/virtio_ids.h>
  #include <linux/virtio_net.h>
  #include <linux/scatterlist.h>
  #include <linux/if_vlan.h>
@@@ -283,12 -282,13 +282,12 @@@ static bool try_fill_recv_maxbufs(struc
        do {
                struct skb_vnet_hdr *hdr;
  
 -              skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN + NET_IP_ALIGN);
 +              skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
                if (unlikely(!skb)) {
                        oom = true;
                        break;
                }
  
 -              skb_reserve(skb, NET_IP_ALIGN);
                skb_put(skb, MAX_PACKET_LEN);
  
                hdr = skb_vnet_hdr(skb);
@@@ -343,12 -343,14 +342,12 @@@ static bool try_fill_recv(struct virtne
        do {
                skb_frag_t *f;
  
 -              skb = netdev_alloc_skb(vi->dev, GOOD_COPY_LEN + NET_IP_ALIGN);
 +              skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
                if (unlikely(!skb)) {
                        oom = true;
                        break;
                }
  
 -              skb_reserve(skb, NET_IP_ALIGN);
 -
                f = &skb_shinfo(skb)->frags[0];
                f->page = get_a_page(vi, gfp);
                if (!f->page) {
diff --combined drivers/net/wan/cosa.c
index 2eceb1a24df223f2b44098346806f427f707741f,e2c33c06190bb1fa0975b634b765de70d22ad71f..cd8f04afed8f2cb1e30edce9212a35b41e487e5c
@@@ -76,6 -76,7 +76,7 @@@
  
  #include <linux/module.h>
  #include <linux/kernel.h>
+ #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/poll.h>
  #include <linux/fs.h>
@@@ -296,8 -297,8 +297,8 @@@ static ssize_t cosa_write(struct file *
  static unsigned int cosa_poll(struct file *file, poll_table *poll);
  static int cosa_open(struct inode *inode, struct file *file);
  static int cosa_release(struct inode *inode, struct file *file);
 -static int cosa_chardev_ioctl(struct inode *inode, struct file *file,
 -      unsigned int cmd, unsigned long arg);
 +static long cosa_chardev_ioctl(struct file *file, unsigned int cmd,
 +                              unsigned long arg);
  #ifdef COSA_FASYNC_WORKING
  static int cosa_fasync(struct inode *inode, struct file *file, int on);
  #endif
@@@ -308,7 -309,7 +309,7 @@@ static const struct file_operations cos
        .read           = cosa_read,
        .write          = cosa_write,
        .poll           = cosa_poll,
 -      .ioctl          = cosa_chardev_ioctl,
 +      .unlocked_ioctl = cosa_chardev_ioctl,
        .open           = cosa_open,
        .release        = cosa_release,
  #ifdef COSA_FASYNC_WORKING
@@@ -1203,18 -1204,12 +1204,18 @@@ static int cosa_net_ioctl(struct net_de
        return hdlc_ioctl(dev, ifr, cmd);
  }
  
 -static int cosa_chardev_ioctl(struct inode *inode, struct file *file,
 -      unsigned int cmd, unsigned long arg)
 +static long cosa_chardev_ioctl(struct file *file, unsigned int cmd,
 +                                                      unsigned long arg)
  {
        struct channel_data *channel = file->private_data;
 -      struct cosa_data *cosa = channel->cosa;
 -      return cosa_ioctl_common(cosa, channel, cmd, arg);
 +      struct cosa_data *cosa;
 +      long ret;
 +
 +      lock_kernel();
 +      cosa = channel->cosa;
 +      ret = cosa_ioctl_common(cosa, channel, cmd, arg);
 +      unlock_kernel();
 +      return ret;
  }
  
  \f
diff --combined drivers/net/wan/dscc4.c
index 63a010252a374b3facb3784e2c27da52b3f5be17,07d00b4cf48a8e80e65fadcd451901c90462c865..3f759daf3ca4a9869fdb2c5b3c5da22e8fee9342
@@@ -81,6 -81,7 +81,7 @@@
   */
  
  #include <linux/module.h>
+ #include <linux/sched.h>
  #include <linux/types.h>
  #include <linux/errno.h>
  #include <linux/list.h>
@@@ -1127,7 -1128,7 +1128,7 @@@ done
          init_timer(&dpriv->timer);
          dpriv->timer.expires = jiffies + 10*HZ;
          dpriv->timer.data = (unsigned long)dev;
 -        dpriv->timer.function = &dscc4_timer;
 +      dpriv->timer.function = dscc4_timer;
          add_timer(&dpriv->timer);
        netif_carrier_on(dev);
  
index 7d2550269ede9acb3d629030981aba67a72bd608,9b9044400218e4e59a085272001037993ccda90a..c01b8e02412f80b64f13c86cfb812bb3db03051d
@@@ -30,6 -30,7 +30,7 @@@
  #include "xmit.h"
  
  #include <linux/delay.h>
+ #include <linux/sched.h>
  
  
  static u16 generate_cookie(struct b43_pio_txqueue *q,
@@@ -341,15 -342,12 +342,15 @@@ static u16 tx_write_2byte_queue(struct 
                        q->mmio_base + B43_PIO_TXDATA,
                        sizeof(u16));
        if (data_len & 1) {
 +              u8 *tail = wl->pio_tailspace;
 +              BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
 +
                /* Write the last byte. */
                ctl &= ~B43_PIO_TXCTL_WRITEHI;
                b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
 -              wl->tx_tail[0] = data[data_len - 1];
 -              wl->tx_tail[1] = 0;
 -              ssb_block_write(dev->dev, wl->tx_tail, 2,
 +              tail[0] = data[data_len - 1];
 +              tail[1] = 0;
 +              ssb_block_write(dev->dev, tail, 2,
                                q->mmio_base + B43_PIO_TXDATA,
                                sizeof(u16));
        }
@@@ -395,31 -393,31 +396,31 @@@ static u32 tx_write_4byte_queue(struct 
                        q->mmio_base + B43_PIO8_TXDATA,
                        sizeof(u32));
        if (data_len & 3) {
 -              wl->tx_tail[3] = 0;
 +              u8 *tail = wl->pio_tailspace;
 +              BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
 +
 +              memset(tail, 0, 4);
                /* Write the last few bytes. */
                ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
                         B43_PIO8_TXCTL_24_31);
                switch (data_len & 3) {
                case 3:
                        ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
 -                      wl->tx_tail[0] = data[data_len - 3];
 -                      wl->tx_tail[1] = data[data_len - 2];
 -                      wl->tx_tail[2] = data[data_len - 1];
 +                      tail[0] = data[data_len - 3];
 +                      tail[1] = data[data_len - 2];
 +                      tail[2] = data[data_len - 1];
                        break;
                case 2:
                        ctl |= B43_PIO8_TXCTL_8_15;
 -                      wl->tx_tail[0] = data[data_len - 2];
 -                      wl->tx_tail[1] = data[data_len - 1];
 -                      wl->tx_tail[2] = 0;
 +                      tail[0] = data[data_len - 2];
 +                      tail[1] = data[data_len - 1];
                        break;
                case 1:
 -                      wl->tx_tail[0] = data[data_len - 1];
 -                      wl->tx_tail[1] = 0;
 -                      wl->tx_tail[2] = 0;
 +                      tail[0] = data[data_len - 1];
                        break;
                }
                b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
 -              ssb_block_write(dev->dev, wl->tx_tail, 4,
 +              ssb_block_write(dev->dev, tail, 4,
                                q->mmio_base + B43_PIO8_TXDATA,
                                sizeof(u32));
        }
@@@ -458,7 -456,6 +459,7 @@@ static int pio_tx_frame(struct b43_pio_
        int err;
        unsigned int hdrlen;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 +      struct b43_txhdr *txhdr = (struct b43_txhdr *)wl->pio_scratchspace;
  
        B43_WARN_ON(list_empty(&q->packets_list));
        pack = list_entry(q->packets_list.next,
  
        cookie = generate_cookie(q, pack);
        hdrlen = b43_txhdr_size(dev);
 -      err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb,
 +      BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(struct b43_txhdr));
 +      B43_WARN_ON(sizeof(wl->pio_scratchspace) < hdrlen);
 +      err = b43_generate_txhdr(dev, (u8 *)txhdr, skb,
                                 info, cookie);
        if (err)
                return err;
  
        pack->skb = skb;
        if (q->rev >= 8)
 -              pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
 +              pio_tx_frame_4byte_queue(pack, (const u8 *)txhdr, hdrlen);
        else
 -              pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
 +              pio_tx_frame_2byte_queue(pack, (const u8 *)txhdr, hdrlen);
  
        /* Remove it from the list of available packet slots.
         * It will be put back when we receive the status report. */
@@@ -630,11 -625,8 +631,11 @@@ static bool pio_rx_frame(struct b43_pio
        unsigned int i, padding;
        struct sk_buff *skb;
        const char *err_msg = NULL;
 +      struct b43_rxhdr_fw4 *rxhdr =
 +              (struct b43_rxhdr_fw4 *)wl->pio_scratchspace;
  
 -      memset(&wl->rxhdr, 0, sizeof(wl->rxhdr));
 +      BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(*rxhdr));
 +      memset(rxhdr, 0, sizeof(*rxhdr));
  
        /* Check if we have data and wait for it to get ready. */
        if (q->rev >= 8) {
@@@ -672,16 -664,16 +673,16 @@@ data_ready
  
        /* Get the preamble (RX header) */
        if (q->rev >= 8) {
 -              ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
 +              ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr),
                               q->mmio_base + B43_PIO8_RXDATA,
                               sizeof(u32));
        } else {
 -              ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
 +              ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr),
                               q->mmio_base + B43_PIO_RXDATA,
                               sizeof(u16));
        }
        /* Sanity checks. */
 -      len = le16_to_cpu(wl->rxhdr.frame_len);
 +      len = le16_to_cpu(rxhdr->frame_len);
        if (unlikely(len > 0x700)) {
                err_msg = "len > 0x700";
                goto rx_error;
                goto rx_error;
        }
  
 -      macstat = le32_to_cpu(wl->rxhdr.mac_status);
 +      macstat = le32_to_cpu(rxhdr->mac_status);
        if (macstat & B43_RX_MAC_FCSERR) {
                if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
                        /* Drop frames with failed FCS. */
                               q->mmio_base + B43_PIO8_RXDATA,
                               sizeof(u32));
                if (len & 3) {
 +                      u8 *tail = wl->pio_tailspace;
 +                      BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
 +
                        /* Read the last few bytes. */
 -                      ssb_block_read(dev->dev, wl->rx_tail, 4,
 +                      ssb_block_read(dev->dev, tail, 4,
                                       q->mmio_base + B43_PIO8_RXDATA,
                                       sizeof(u32));
                        switch (len & 3) {
                        case 3:
 -                              skb->data[len + padding - 3] = wl->rx_tail[0];
 -                              skb->data[len + padding - 2] = wl->rx_tail[1];
 -                              skb->data[len + padding - 1] = wl->rx_tail[2];
 +                              skb->data[len + padding - 3] = tail[0];
 +                              skb->data[len + padding - 2] = tail[1];
 +                              skb->data[len + padding - 1] = tail[2];
                                break;
                        case 2:
 -                              skb->data[len + padding - 2] = wl->rx_tail[0];
 -                              skb->data[len + padding - 1] = wl->rx_tail[1];
 +                              skb->data[len + padding - 2] = tail[0];
 +                              skb->data[len + padding - 1] = tail[1];
                                break;
                        case 1:
 -                              skb->data[len + padding - 1] = wl->rx_tail[0];
 +                              skb->data[len + padding - 1] = tail[0];
                                break;
                        }
                }
                               q->mmio_base + B43_PIO_RXDATA,
                               sizeof(u16));
                if (len & 1) {
 +                      u8 *tail = wl->pio_tailspace;
 +                      BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
 +
                        /* Read the last byte. */
 -                      ssb_block_read(dev->dev, wl->rx_tail, 2,
 +                      ssb_block_read(dev->dev, tail, 2,
                                       q->mmio_base + B43_PIO_RXDATA,
                                       sizeof(u16));
 -                      skb->data[len + padding - 1] = wl->rx_tail[0];
 +                      skb->data[len + padding - 1] = tail[0];
                }
        }
  
 -      b43_rx(q->dev, skb, &wl->rxhdr);
 +      b43_rx(q->dev, skb, rxhdr);
  
        return 1;
  
  rx_error:
        if (err_msg)
                b43dbg(q->dev->wl, "PIO RX error: %s\n", err_msg);
 -      b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY);
 +      if (q->rev >= 8)
 +              b43_piorx_write32(q, B43_PIO8_RXCTL, B43_PIO8_RXCTL_DATARDY);
 +      else
 +              b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY);
 +
        return 1;
  }
  
index d579bb9035c444664926fd1f3d451d16fd23985a,4b60148a5e61c9cc9b2f0eea64fe128d72d1ac55..ab6a18c2e9d9fe357163f8caaf3073f10747c30f
@@@ -37,6 -37,7 +37,7 @@@
  #include <linux/firmware.h>
  #include <linux/wireless.h>
  #include <linux/workqueue.h>
+ #include <linux/sched.h>
  #include <linux/skbuff.h>
  #include <linux/dma-mapping.h>
  #include <net/dst.h>
@@@ -2676,7 -2677,7 +2677,7 @@@ static int b43legacy_op_dev_config(stru
        if (conf->channel->hw_value != phy->channel)
                b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
  
 -      dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
 +      dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
  
        /* Adjust the desired TX power level. */
        if (conf->power_level != 0) {
@@@ -3592,7 -3593,7 +3593,7 @@@ static int b43legacy_wireless_core_atta
  {
        struct b43legacy_wl *wl = dev->wl;
        struct ssb_bus *bus = dev->dev->bus;
 -      struct pci_dev *pdev = bus->host_pci;
 +      struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
        int err;
        int have_bphy = 0;
        int have_gphy = 0;
@@@ -3706,7 -3707,7 +3707,7 @@@ static int b43legacy_one_core_attach(st
  
        if (!list_empty(&wl->devlist)) {
                /* We are not the first core on this chip. */
 -              pdev = dev->bus->host_pci;
 +              pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL;
                /* Only special chips support more than one wireless
                 * core, although some of the other chips have more than
                 * one wireless core as well. Check for this and
index 9b398db2d740811bd7bebee43aa58a01e6daa550,a6ca536e44f81658e15cc361f9e51232a517801a..9fe0e8078a8820538c7e4e51a4f9da9435816c2c
@@@ -30,6 -30,7 +30,7 @@@
  
  ******************************************************************************/
  
+ #include <linux/sched.h>
  #include "ipw2200.h"
  
  
@@@ -80,11 -81,6 +81,11 @@@ MODULE_DESCRIPTION(DRV_DESCRIPTION)
  MODULE_VERSION(DRV_VERSION);
  MODULE_AUTHOR(DRV_COPYRIGHT);
  MODULE_LICENSE("GPL");
 +MODULE_FIRMWARE("ipw2200-ibss.fw");
 +#ifdef CONFIG_IPW2200_MONITOR
 +MODULE_FIRMWARE("ipw2200-sniffer.fw");
 +#endif
 +MODULE_FIRMWARE("ipw2200-bss.fw");
  
  static int cmdlog = 0;
  static int debug = 0;
@@@ -11279,7 -11275,6 +11280,7 @@@ static int ipw_up(struct ipw_priv *priv
                if (!(priv->config & CFG_CUSTOM_MAC))
                        eeprom_parse_mac(priv, priv->mac_addr);
                memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
 +              memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN);
  
                for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
                        if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
index 26a1134f84a2dba47d2978ae91dccd876b2cee34,f059b49dc6910d318729836bf3358f3a4ed15e3a..7da1dab933d985b2777ce51412b5650e91e7c62c
@@@ -30,6 -30,7 +30,7 @@@
  #include <linux/pci.h>
  #include <linux/dma-mapping.h>
  #include <linux/delay.h>
+ #include <linux/sched.h>
  #include <linux/skbuff.h>
  #include <linux/netdevice.h>
  #include <linux/wireless.h>
@@@ -46,8 -47,7 +47,8 @@@
  #include "iwl-eeprom.h"
  #include "iwl-helpers.h"
  #include "iwl-core.h"
 -#include "iwl-agn-rs.h"
 +#include "iwl-led.h"
 +#include "iwl-3945-led.h"
  
  #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np)    \
        [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,   \
@@@ -293,7 -293,7 +294,7 @@@ static void iwl3945_tx_queue_reclaim(st
  static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
                            struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
  void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
                struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
                     (int)sizeof(struct iwl3945_notif_statistics),
                     le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
  
        memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
 -
 -      iwl3945_led_background(priv);
 -
 -      priv->last_statistics_time = jiffies;
  }
  
  /******************************************************************************
@@@ -541,18 -545,14 +542,18 @@@ static void iwl3945_pass_packet_to_mac8
                                   struct iwl_rx_mem_buffer *rxb,
                                   struct ieee80211_rx_status *stats)
  {
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
        struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
        struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
 -      short len = le16_to_cpu(rx_hdr->len);
 +      u16 len = le16_to_cpu(rx_hdr->len);
 +      struct sk_buff *skb;
 +      int ret;
 +      __le16 fc = hdr->frame_control;
  
        /* We received data from the HW, so stop the watchdog */
 -      if (unlikely((len + IWL39_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
 +      if (unlikely(len + IWL39_RX_FRAME_SIZE >
 +                   PAGE_SIZE << priv->hw_params.rx_page_order)) {
                IWL_DEBUG_DROP(priv, "Corruption detected!\n");
                return;
        }
                return;
        }
  
 -      skb_reserve(rxb->skb, (void *)rx_hdr->payload - (void *)pkt);
 -      /* Set the size of the skb to the size of the frame */
 -      skb_put(rxb->skb, le16_to_cpu(rx_hdr->len));
 +      skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
 +      if (!skb) {
 +              IWL_ERR(priv, "alloc_skb failed\n");
 +              return;
 +      }
  
        if (!iwl3945_mod_params.sw_crypto)
                iwl_set_decrypted_flag(priv,
 -                                     (struct ieee80211_hdr *)rxb->skb->data,
 +                                     (struct ieee80211_hdr *)rxb_addr(rxb),
                                       le32_to_cpu(rx_end->status), stats);
  
 -#ifdef CONFIG_IWLWIFI_LEDS
 -      if (ieee80211_is_data(hdr->frame_control))
 -              priv->rxtxpackets += len;
 -#endif
 -      iwl_update_stats(priv, false, hdr->frame_control, len);
 +      skb_reserve(skb, IWL_LINK_HDR_MAX);
 +      skb_add_rx_frag(skb, 0, rxb->page,
 +                      (void *)rx_hdr->payload - (void *)pkt, len);
 +
 +      /* mac80211 currently doesn't support paged SKB. Convert it to
 +       * linear SKB for management frame and data frame requires
 +       * software decryption or software defragementation. */
 +      if (ieee80211_is_mgmt(fc) ||
 +          ieee80211_has_protected(fc) ||
 +          ieee80211_has_morefrags(fc) ||
 +          le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)
 +              ret = skb_linearize(skb);
 +      else
 +              ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
 +                      0 : -ENOMEM;
 +
 +      if (ret) {
 +              kfree_skb(skb);
 +              goto out;
 +      }
  
 -      memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
 -      ieee80211_rx_irqsafe(priv->hw, rxb->skb);
 -      rxb->skb = NULL;
 +      /*
 +       * XXX: We cannot touch the page and its virtual memory (pkt) after
 +       * here. It might have already been freed by the above skb change.
 +       */
 +
 +      iwl_update_stats(priv, false, fc, len);
 +      memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
 +
 +      ieee80211_rx(priv->hw, skb);
 + out:
 +      priv->alloc_rxb_page--;
 +      rxb->page = NULL;
  }
  
  #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
@@@ -617,7 -591,7 +618,7 @@@ static void iwl3945_rx_reply_rx(struct 
  {
        struct ieee80211_hdr *header;
        struct ieee80211_rx_status rx_status;
 -      struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
        struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
        struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
@@@ -817,31 -791,29 +818,31 @@@ void iwl3945_hw_build_tx_cmd_rate(struc
        u8 data_retry_limit;
        __le32 tx_flags;
        __le16 fc = hdr->frame_control;
 -      struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
 +      struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
  
        rate = iwl3945_rates[rate_index].plcp;
 -      tx_flags = tx->tx_flags;
 +      tx_flags = tx_cmd->tx_flags;
  
        /* We need to figure out how to get the sta->supp_rates while
         * in this running context */
        rate_mask = IWL_RATES_MASK;
  
 +
 +      /* Set retry limit on DATA packets and Probe Responses*/
 +      if (ieee80211_is_probe_resp(fc))
 +              data_retry_limit = 3;
 +      else
 +              data_retry_limit = IWL_DEFAULT_TX_RETRY;
 +      tx_cmd->data_retry_limit = data_retry_limit;
 +
        if (tx_id >= IWL_CMD_QUEUE_NUM)
                rts_retry_limit = 3;
        else
                rts_retry_limit = 7;
  
 -      if (ieee80211_is_probe_resp(fc)) {
 -              data_retry_limit = 3;
 -              if (data_retry_limit < rts_retry_limit)
 -                      rts_retry_limit = data_retry_limit;
 -      } else
 -              data_retry_limit = IWL_DEFAULT_TX_RETRY;
 -
 -      if (priv->data_retry_limit != -1)
 -              data_retry_limit = priv->data_retry_limit;
 +      if (data_retry_limit < rts_retry_limit)
 +              rts_retry_limit = data_retry_limit;
 +      tx_cmd->rts_retry_limit = rts_retry_limit;
  
        if (ieee80211_is_mgmt(fc)) {
                switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
                }
        }
  
 -      tx->rts_retry_limit = rts_retry_limit;
 -      tx->data_retry_limit = data_retry_limit;
 -      tx->rate = rate;
 -      tx->tx_flags = tx_flags;
 +      tx_cmd->rate = rate;
 +      tx_cmd->tx_flags = tx_flags;
  
        /* OFDM */
 -      tx->supp_rates[0] =
 +      tx_cmd->supp_rates[0] =
           ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF;
  
        /* CCK */
 -      tx->supp_rates[1] = (rate_mask & 0xF);
 +      tx_cmd->supp_rates[1] = (rate_mask & 0xF);
  
        IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
                       "cck/ofdm mask: 0x%x/0x%x\n", sta_id,
 -                     tx->rate, le32_to_cpu(tx->tx_flags),
 -                     tx->supp_rates[1], tx->supp_rates[0]);
 +                     tx_cmd->rate, le32_to_cpu(tx_cmd->tx_flags),
 +                     tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
  }
  
  u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
@@@ -988,11 -962,6 +989,11 @@@ static int iwl3945_txq_ctx_reset(struc
  
        iwl3945_hw_txq_ctx_free(priv);
  
 +      /* allocate tx queue structure */
 +      rc = iwl_alloc_txq_mem(priv);
 +      if (rc)
 +              return rc;
 +
        /* Tx CMD queue */
        rc = iwl3945_tx_reset(priv);
        if (rc)
        return rc;
  }
  
 +
 +/*
 + * Start up 3945's basic functionality after it has been reset
 + * (e.g. after platform boot, or shutdown via iwl_apm_stop())
 + * NOTE:  This does not load uCode nor start the embedded processor
 + */
  static int iwl3945_apm_init(struct iwl_priv *priv)
  {
 -      int ret;
 -
 -      iwl_power_initialize(priv);
 -
 -      iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
 -                        CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
 +      int ret = iwl_apm_init(priv);
  
 -      /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
 -      iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
 -                        CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
 -
 -      /* set "initialization complete" bit to move adapter
 -      * D0U* --> D0A* state */
 -      iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 -
 -      ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
 -                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 -      if (ret < 0) {
 -              IWL_DEBUG_INFO(priv, "Failed to init the card\n");
 -              goto out;
 -      }
 -
 -      /* enable DMA */
 -      iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
 -                                              APMG_CLK_VAL_BSM_CLK_RQT);
 -
 -      udelay(20);
 +      /* Clear APMG (NIC's internal power management) interrupts */
 +      iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
 +      iwl_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF);
  
 -      /* disable L1-Active */
 -      iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
 -                        APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 +      /* Reset radio chip */
 +      iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
 +      udelay(5);
 +      iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
  
 -out:
        return ret;
  }
  
@@@ -1160,16 -1145,12 +1161,16 @@@ void iwl3945_hw_txq_ctx_free(struct iwl
        int txq_id;
  
        /* Tx queues */
 -      for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
 -              if (txq_id == IWL_CMD_QUEUE_NUM)
 -                      iwl_cmd_queue_free(priv);
 -              else
 -                      iwl_tx_queue_free(priv, txq_id);
 +      if (priv->txq)
 +              for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
 +                   txq_id++)
 +                      if (txq_id == IWL_CMD_QUEUE_NUM)
 +                              iwl_cmd_queue_free(priv);
 +                      else
 +                              iwl_tx_queue_free(priv, txq_id);
  
 +      /* free tx queue structure */
 +      iwl_free_txq_mem(priv);
  }
  
  void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
  
        /* stop SCD */
        iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
 +      iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0);
  
        /* reset TFD queues */
        for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
        iwl3945_hw_txq_ctx_free(priv);
  }
  
 -static int iwl3945_apm_stop_master(struct iwl_priv *priv)
 -{
 -      int ret = 0;
 -      unsigned long flags;
 -
 -      spin_lock_irqsave(&priv->lock, flags);
 -
 -      /* set stop master bit */
 -      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 -
 -      iwl_poll_direct_bit(priv, CSR_RESET,
 -                          CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
 -
 -      if (ret < 0)
 -              goto out;
 -
 -out:
 -      spin_unlock_irqrestore(&priv->lock, flags);
 -      IWL_DEBUG_INFO(priv, "stop master\n");
 -
 -      return ret;
 -}
 -
 -static void iwl3945_apm_stop(struct iwl_priv *priv)
 -{
 -      unsigned long flags;
 -
 -      iwl3945_apm_stop_master(priv);
 -
 -      spin_lock_irqsave(&priv->lock, flags);
 -
 -      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 -
 -      udelay(10);
 -      /* clear "init complete"  move adapter D0A* --> D0U state */
 -      iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 -      spin_unlock_irqrestore(&priv->lock, flags);
 -}
 -
 -static int iwl3945_apm_reset(struct iwl_priv *priv)
 -{
 -      iwl3945_apm_stop_master(priv);
 -
 -
 -      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 -      udelay(10);
 -
 -      iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 -
 -      iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
 -                       CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 -
 -      iwl_write_prph(priv, APMG_CLK_CTRL_REG,
 -                              APMG_CLK_VAL_BSM_CLK_RQT);
 -
 -      iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
 -      iwl_write_prph(priv, APMG_RTC_INT_STT_REG,
 -                                      0xFFFFFFFF);
 -
 -      /* enable DMA */
 -      iwl_write_prph(priv, APMG_CLK_EN_REG,
 -                              APMG_CLK_VAL_DMA_CLK_RQT |
 -                              APMG_CLK_VAL_BSM_CLK_RQT);
 -      udelay(10);
 -
 -      iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
 -                              APMG_PS_CTRL_VAL_RESET_REQ);
 -      udelay(5);
 -      iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
 -                              APMG_PS_CTRL_VAL_RESET_REQ);
 -
 -      /* Clear the 'host command active' bit... */
 -      clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 -
 -      wake_up_interruptible(&priv->wait_command_queue);
 -
 -      return 0;
 -}
 -
  /**
   * iwl3945_hw_reg_adjust_power_by_temp
   * return index delta into power gain settings table
@@@ -1799,7 -1858,7 +1800,7 @@@ int iwl3945_hw_reg_set_txpower(struct i
  static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
  {
        int rc = 0;
 -      struct iwl_rx_packet *res = NULL;
 +      struct iwl_rx_packet *pkt;
        struct iwl3945_rxon_assoc_cmd rxon_assoc;
        struct iwl_host_cmd cmd = {
                .id = REPLY_RXON_ASSOC,
        if (rc)
                return rc;
  
 -      res = (struct iwl_rx_packet *)cmd.reply_skb->data;
 -      if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
 +      pkt = (struct iwl_rx_packet *)cmd.reply_page;
 +      if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
                rc = -EIO;
        }
  
 -      priv->alloc_rxb_skb--;
 -      dev_kfree_skb_any(cmd.reply_skb);
 +      priv->alloc_rxb_page--;
 +      free_pages(cmd.reply_page, priv->hw_params.rx_page_order);
  
        return rc;
  }
@@@ -1983,6 -2042,12 +1984,6 @@@ static int iwl3945_commit_rxon(struct i
        return 0;
  }
  
 -/* will add 3945 channel switch cmd handling later */
 -int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 -{
 -      return 0;
 -}
 -
  /**
   * iwl3945_reg_txpower_periodic -  called when time to check our temperature.
   *
@@@ -2492,10 -2557,11 +2493,10 @@@ int iwl3945_hw_set_hw_params(struct iwl
        }
  
        /* Assign number of Usable TX queues */
 -      priv->hw_params.max_txq_num = IWL39_NUM_QUEUES;
 +      priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
  
        priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
 -      priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
 -      priv->hw_params.max_pkt_size = 2342;
 +      priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K);
        priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
        priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
        priv->hw_params.max_stations = IWL3945_STATION_COUNT;
@@@ -2778,7 -2844,8 +2779,7 @@@ static struct iwl_lib_ops iwl3945_lib 
        .dump_nic_error_log = iwl3945_dump_nic_error_log,
        .apm_ops = {
                .init = iwl3945_apm_init,
 -              .reset = iwl3945_apm_reset,
 -              .stop = iwl3945_apm_stop,
 +              .stop = iwl_apm_stop,
                .config = iwl3945_nic_config,
                .set_pwr_src = iwl3945_set_pwr_src,
        },
  static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
        .get_hcmd_size = iwl3945_get_hcmd_size,
        .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
 +      .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
  };
  
  static struct iwl_ops iwl3945_ops = {
        .lib = &iwl3945_lib,
        .hcmd = &iwl3945_hcmd,
        .utils = &iwl3945_hcmd_utils,
 +      .led = &iwl3945_led_ops,
  };
  
  static struct iwl_cfg iwl3945_bg_cfg = {
        .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
        .ops = &iwl3945_ops,
 +      .num_of_queues = IWL39_NUM_QUEUES,
        .mod_params = &iwl3945_mod_params,
 +      .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
 +      .set_l0s = false,
 +      .use_bsm = true,
        .use_isr_legacy = true,
        .ht_greenfield_support = false,
 +      .led_compensation = 64,
  };
  
  static struct iwl_cfg iwl3945_abg_cfg = {
        .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
        .ops = &iwl3945_ops,
 +      .num_of_queues = IWL39_NUM_QUEUES,
        .mod_params = &iwl3945_mod_params,
        .use_isr_legacy = true,
        .ht_greenfield_support = false,
 +      .led_compensation = 64,
  };
  
  struct pci_device_id iwl3945_hw_card_ids[] = {
index 1d22ea390c008376c80d370dad38071f312a67be,6f703a0418473272546f6a02aacae3821a6a248c..cc3942448703a4d22b5c25b950cde1ec00c4638a
@@@ -30,6 -30,7 +30,7 @@@
  #include <linux/pci.h>
  #include <linux/dma-mapping.h>
  #include <linux/delay.h>
+ #include <linux/sched.h>
  #include <linux/skbuff.h>
  #include <linux/netdevice.h>
  #include <linux/wireless.h>
@@@ -44,7 -45,6 +45,7 @@@
  #include "iwl-helpers.h"
  #include "iwl-calib.h"
  #include "iwl-sta.h"
 +#include "iwl-agn-led.h"
  
  static int iwl4965_send_tx_power(struct iwl_priv *priv);
  static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@@ -62,6 -62,8 +63,6 @@@
  
  /* module parameters */
  static struct iwl_mod_params iwl4965_mod_params = {
 -      .num_of_queues = IWL49_NUM_QUEUES,
 -      .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
        .amsdu_size_8K = 1,
        .restart_fw = 1,
        /* the rest are 0 by default */
@@@ -317,13 -319,63 +318,13 @@@ static void iwl4965_txq_set_sched(struc
        iwl_write_prph(priv, IWL49_SCD_TXFACT, mask);
  }
  
 -static int iwl4965_apm_init(struct iwl_priv *priv)
 -{
 -      int ret = 0;
 -
 -      iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
 -                        CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
 -
 -      /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
 -      iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
 -                        CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
 -
 -      /* set "initialization complete" bit to move adapter
 -       * D0U* --> D0A* state */
 -      iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 -
 -      /* wait for clock stabilization */
 -      ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
 -                      CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 -      if (ret < 0) {
 -              IWL_DEBUG_INFO(priv, "Failed to init the card\n");
 -              goto out;
 -      }
 -
 -      /* enable DMA */
 -      iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
 -                                              APMG_CLK_VAL_BSM_CLK_RQT);
 -
 -      udelay(20);
 -
 -      /* disable L1-Active */
 -      iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
 -                        APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 -
 -out:
 -      return ret;
 -}
 -
 -
  static void iwl4965_nic_config(struct iwl_priv *priv)
  {
        unsigned long flags;
        u16 radio_cfg;
 -      u16 lctl;
  
        spin_lock_irqsave(&priv->lock, flags);
  
 -      lctl = iwl_pcie_link_ctl(priv);
 -
 -      /* HW bug W/A - negligible power consumption */
 -      /* L1-ASPM is enabled by BIOS */
 -      if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
 -              /* L1-ASPM enabled: disable L0S  */
 -              iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
 -      else
 -              /* L1-ASPM disabled: enable L0S */
 -              iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
 -
        radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
  
        /* write radio config values to register */
        spin_unlock_irqrestore(&priv->lock, flags);
  }
  
 -static int iwl4965_apm_stop_master(struct iwl_priv *priv)
 -{
 -      unsigned long flags;
 -
 -      spin_lock_irqsave(&priv->lock, flags);
 -
 -      /* set stop master bit */
 -      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 -
 -      iwl_poll_direct_bit(priv, CSR_RESET,
 -                      CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
 -
 -      spin_unlock_irqrestore(&priv->lock, flags);
 -      IWL_DEBUG_INFO(priv, "stop master\n");
 -
 -      return 0;
 -}
 -
 -static void iwl4965_apm_stop(struct iwl_priv *priv)
 -{
 -      unsigned long flags;
 -
 -      iwl4965_apm_stop_master(priv);
 -
 -      spin_lock_irqsave(&priv->lock, flags);
 -
 -      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 -
 -      udelay(10);
 -      /* clear "init complete"  move adapter D0A* --> D0U state */
 -      iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 -      spin_unlock_irqrestore(&priv->lock, flags);
 -}
 -
 -static int iwl4965_apm_reset(struct iwl_priv *priv)
 -{
 -      int ret = 0;
 -
 -      iwl4965_apm_stop_master(priv);
 -
 -
 -      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 -
 -      udelay(10);
 -
 -      /* FIXME: put here L1A -L0S w/a */
 -
 -      iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 -
 -      ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
 -                      CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 -      if (ret < 0)
 -              goto out;
 -
 -      udelay(10);
 -
 -      /* Enable DMA and BSM Clock */
 -      iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT |
 -                                            APMG_CLK_VAL_BSM_CLK_RQT);
 -
 -      udelay(10);
 -
 -      /* disable L1A */
 -      iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
 -                        APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 -
 -      clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 -      wake_up_interruptible(&priv->wait_command_queue);
 -
 -out:
 -      return ret;
 -}
 -
  /* Reset differential Rx gains in NIC to prepare for chain noise calibration.
   * Called after every association, but this runs only once!
   *  ... once chain noise is calibrated the first time, it's good forever.  */
@@@ -371,15 -496,14 +372,15 @@@ static void iwl4965_chain_noise_reset(s
  static void iwl4965_gain_computation(struct iwl_priv *priv,
                u32 *average_noise,
                u16 min_average_noise_antenna_i,
 -              u32 min_average_noise)
 +              u32 min_average_noise,
 +              u8 default_chain)
  {
        int i, ret;
        struct iwl_chain_noise_data *data = &priv->chain_noise_data;
  
        data->delta_gain_code[min_average_noise_antenna_i] = 0;
  
 -      for (i = 0; i < NUM_RX_CHAINS; i++) {
 +      for (i = default_chain; i < NUM_RX_CHAINS; i++) {
                s32 delta_g = 0;
  
                if (!(data->disconn_array[i]) &&
        data->beacon_count = 0;
  }
  
 -static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
 -                      __le32 *tx_flags)
 -{
 -      if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
 -              *tx_flags |= TX_CMD_FLG_RTS_MSK;
 -              *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
 -      } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
 -              *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
 -              *tx_flags |= TX_CMD_FLG_CTS_MSK;
 -      }
 -}
 -
  static void iwl4965_bg_txpower_work(struct work_struct *work)
  {
        struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@@ -527,8 -663,7 +528,8 @@@ static int iwl4965_alive_notify(struct 
                iwl_write_targ_mem(priv, a, 0);
        for (; a < priv->scd_base_addr + IWL49_SCD_TRANSLATE_TBL_OFFSET; a += 4)
                iwl_write_targ_mem(priv, a, 0);
 -      for (; a < sizeof(u16) * priv->hw_params.max_txq_num; a += 4)
 +      for (; a < priv->scd_base_addr +
 +             IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
                iwl_write_targ_mem(priv, a, 0);
  
        /* Tel 4965 where to find Tx byte count tables */
@@@ -613,10 -748,6 +614,10 @@@ static struct iwl_sensitivity_ranges iw
  
        .nrg_th_cck = 100,
        .nrg_th_ofdm = 100,
 +
 +      .barker_corr_th_min = 190,
 +      .barker_corr_th_min_mrc = 390,
 +      .nrg_th_cca = 62,
  };
  
  static void iwl4965_set_ct_threshold(struct iwl_priv *priv)
   */
  static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
  {
 +      if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
 +          priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES)
 +              priv->cfg->num_of_queues =
 +                      priv->cfg->mod_params->num_of_queues;
  
 -      if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||
 -          (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
 -              IWL_ERR(priv,
 -                      "invalid queues_num, should be between %d and %d\n",
 -                      IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
 -              return -EINVAL;
 -      }
 -
 -      priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
 +      priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
        priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
        priv->hw_params.scd_bc_tbls_size =
 -                      IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
 +                      priv->cfg->num_of_queues *
 +                      sizeof(struct iwl4965_scd_bc_tbl);
        priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
        priv->hw_params.max_stations = IWL4965_STATION_COUNT;
        priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
  
        priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
  
 -      priv->hw_params.tx_chains_num = 2;
 -      priv->hw_params.rx_chains_num = 2;
 -      priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
 -      priv->hw_params.valid_rx_ant = ANT_A | ANT_B;
 +      priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
 +      priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
 +      priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
 +      priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
        if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
                priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
  
@@@ -1433,13 -1567,14 +1434,13 @@@ static int iwl4965_send_rxon_assoc(stru
        return ret;
  }
  
 -#ifdef IEEE80211_CONF_CHANNEL_SWITCH
  static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
  {
        int rc;
        u8 band = 0;
        bool is_ht40 = false;
        u8 ctrl_chan_high = 0;
 -      struct iwl4965_channel_switch_cmd cmd = { 0 };
 +      struct iwl4965_channel_switch_cmd cmd;
        const struct iwl_channel_info *ch_info;
  
        band = priv->band == IEEE80211_BAND_2GHZ;
        is_ht40 = is_ht40_channel(priv->staging_rxon.flags);
  
        if (is_ht40 &&
 -          (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
 +          (priv->staging_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
                ctrl_chan_high = 1;
  
        cmd.band = band;
        cmd.expect_beacon = 0;
        cmd.channel = cpu_to_le16(channel);
 -      cmd.rxon_flags = priv->active_rxon.flags;
 -      cmd.rxon_filter_flags = priv->active_rxon.filter_flags;
 +      cmd.rxon_flags = priv->staging_rxon.flags;
 +      cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
        cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
        if (ch_info)
                cmd.expect_beacon = is_channel_radar(ch_info);
 -      else
 -              cmd.expect_beacon = 1;
 +      else {
 +              IWL_ERR(priv, "invalid channel switch from %u to %u\n",
 +                      priv->active_rxon.channel, channel);
 +              return -EFAULT;
 +      }
  
        rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40,
                                      ctrl_chan_high, &cmd.tx_power);
                return rc;
        }
  
 -      rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
 -      return rc;
 +      priv->switch_rxon.channel = cpu_to_le16(channel);
 +      priv->switch_rxon.switch_in_progress = true;
 +
 +      return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
  }
 -#endif
  
  /**
   * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
@@@ -1674,13 -1805,11 +1675,13 @@@ static int iwl4965_txq_agg_disable(stru
                                   u16 ssn_idx, u8 tx_fifo)
  {
        if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
 -          (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
 +          (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
 +           <= txq_id)) {
                IWL_WARN(priv,
                        "queue number out of range: %d, must be %d to %d\n",
                        txq_id, IWL49_FIRST_AMPDU_QUEUE,
 -                      IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
 +                      IWL49_FIRST_AMPDU_QUEUE +
 +                      priv->cfg->num_of_ampdu_queues - 1);
                return -EINVAL;
        }
  
@@@ -1741,13 -1870,11 +1742,13 @@@ static int iwl4965_txq_agg_enable(struc
        u16 ra_tid;
  
        if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
 -          (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
 +          (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
 +           <= txq_id)) {
                IWL_WARN(priv,
                        "queue number out of range: %d, must be %d to %d\n",
                        txq_id, IWL49_FIRST_AMPDU_QUEUE,
 -                      IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
 +                      IWL49_FIRST_AMPDU_QUEUE +
 +                      priv->cfg->num_of_ampdu_queues - 1);
                return -EINVAL;
        }
  
@@@ -1951,7 -2078,7 +1952,7 @@@ static int iwl4965_tx_status_reply_tx(s
  static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                                struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
@@@ -2152,7 -2279,7 +2153,7 @@@ static struct iwl_hcmd_utils_ops iwl496
        .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
        .chain_noise_reset = iwl4965_chain_noise_reset,
        .gain_computation = iwl4965_gain_computation,
 -      .rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
 +      .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
        .calc_rssi = iwl4965_calc_rssi,
  };
  
@@@ -2174,10 -2301,10 +2175,10 @@@ static struct iwl_lib_ops iwl4965_lib 
        .load_ucode = iwl4965_load_bsm,
        .dump_nic_event_log = iwl_dump_nic_event_log,
        .dump_nic_error_log = iwl_dump_nic_error_log,
 +      .set_channel_switch = iwl4965_hw_channel_switch,
        .apm_ops = {
 -              .init = iwl4965_apm_init,
 -              .reset = iwl4965_apm_reset,
 -              .stop = iwl4965_apm_stop,
 +              .init = iwl_apm_init,
 +              .stop = iwl_apm_stop,
                .config = iwl4965_nic_config,
                .set_pwr_src = iwl_set_pwr_src,
        },
@@@ -2213,7 -2340,6 +2214,7 @@@ static struct iwl_ops iwl4965_ops = 
        .lib = &iwl4965_lib,
        .hcmd = &iwl4965_hcmd,
        .utils = &iwl4965_hcmd_utils,
 +      .led = &iwlagn_led_ops,
  };
  
  struct iwl_cfg iwl4965_agn_cfg = {
        .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
        .ops = &iwl4965_ops,
 +      .num_of_queues = IWL49_NUM_QUEUES,
 +      .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
        .mod_params = &iwl4965_mod_params,
 +      .valid_tx_ant = ANT_AB,
 +      .valid_rx_ant = ANT_ABC,
 +      .pll_cfg_val = 0,
 +      .set_l0s = true,
 +      .use_bsm = true,
        .use_isr_legacy = true,
        .ht_greenfield_support = false,
        .broken_powersave = true,
 +      .led_compensation = 61,
 +      .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
  };
  
  /* Module firmware */
  MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX));
  
 -module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
 +module_param_named(antenna, iwl4965_mod_params.antenna, int, S_IRUGO);
  MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
 -module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444);
 +module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, S_IRUGO);
  MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
  module_param_named(
 -      disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, 0444);
 +      disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, S_IRUGO);
  MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
  
 -module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444);
 +module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, S_IRUGO);
  MODULE_PARM_DESC(queues_num, "number of hw queues.");
  /* 11n */
 -module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444);
 +module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, S_IRUGO);
  MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
 -module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444);
 +module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K,
 +                 int, S_IRUGO);
  MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
  
 -module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, 0444);
 +module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, S_IRUGO);
  MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error");
index 6eaf26b07636495a0de3717abff74a6ae8be7b14,6e6f516ba404e25e85a59df55aa131c16825e332..e23d301e816fc21fc8e0f36273d9f02a59245e64
@@@ -29,6 -29,7 +29,7 @@@
  #include <linux/pci.h>
  #include <linux/dma-mapping.h>
  #include <linux/delay.h>
+ #include <linux/sched.h>
  #include <linux/skbuff.h>
  #include <linux/netdevice.h>
  #include <linux/wireless.h>
@@@ -42,7 -43,6 +43,7 @@@
  #include "iwl-io.h"
  #include "iwl-sta.h"
  #include "iwl-helpers.h"
 +#include "iwl-agn-led.h"
  #include "iwl-5000-hw.h"
  #include "iwl-6000-hw.h"
  
@@@ -72,18 -72,157 +73,18 @@@ static const u16 iwl5000_default_queue_
        IWL_TX_FIFO_HCCA_2
  };
  
 -/* FIXME: same implementation as 4965 */
 -static int iwl5000_apm_stop_master(struct iwl_priv *priv)
 -{
 -      unsigned long flags;
 -
 -      spin_lock_irqsave(&priv->lock, flags);
 -
 -      /* set stop master bit */
 -      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 -
 -      iwl_poll_direct_bit(priv, CSR_RESET,
 -                                CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
 -
 -      spin_unlock_irqrestore(&priv->lock, flags);
 -      IWL_DEBUG_INFO(priv, "stop master\n");
 -
 -      return 0;
 -}
 -
 -
 -int iwl5000_apm_init(struct iwl_priv *priv)
 -{
 -      int ret = 0;
 -
 -      iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
 -                  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
 -
 -      /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
 -      iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
 -                  CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
 -
 -      /* Set FH wait threshold to maximum (HW error during stress W/A) */
 -      iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
 -
 -      /* enable HAP INTA to move device L1a -> L0s */
 -      iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 -                  CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
 -
 -      if (priv->cfg->need_pll_cfg)
 -              iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
 -
 -      /* set "initialization complete" bit to move adapter
 -       * D0U* --> D0A* state */
 -      iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 -
 -      /* wait for clock stabilization */
 -      ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
 -                      CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 -      if (ret < 0) {
 -              IWL_DEBUG_INFO(priv, "Failed to init the card\n");
 -              return ret;
 -      }
 -
 -      /* enable DMA */
 -      iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
 -
 -      udelay(20);
 -
 -      /* disable L1-Active */
 -      iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
 -                        APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 -
 -      return ret;
 -}
 -
 -/* FIXME: this is identical to 4965 */
 -void iwl5000_apm_stop(struct iwl_priv *priv)
 -{
 -      unsigned long flags;
 -
 -      iwl5000_apm_stop_master(priv);
 -
 -      spin_lock_irqsave(&priv->lock, flags);
 -
 -      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 -
 -      udelay(10);
 -
 -      /* clear "init complete"  move adapter D0A* --> D0U state */
 -      iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 -
 -      spin_unlock_irqrestore(&priv->lock, flags);
 -}
 -
 -
 -int iwl5000_apm_reset(struct iwl_priv *priv)
 -{
 -      int ret = 0;
 -
 -      iwl5000_apm_stop_master(priv);
 -
 -      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 -
 -      udelay(10);
 -
 -
 -      /* FIXME: put here L1A -L0S w/a */
 -
 -      if (priv->cfg->need_pll_cfg)
 -              iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
 -
 -      /* set "initialization complete" bit to move adapter
 -       * D0U* --> D0A* state */
 -      iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 -
 -      /* wait for clock stabilization */
 -      ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
 -                      CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 -      if (ret < 0) {
 -              IWL_DEBUG_INFO(priv, "Failed to init the card\n");
 -              goto out;
 -      }
 -
 -      /* enable DMA */
 -      iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
 -
 -      udelay(20);
 -
 -      /* disable L1-Active */
 -      iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
 -                        APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 -out:
 -
 -      return ret;
 -}
 -
 -
 -/* NIC configuration for 5000 series and up */
 +/* NIC configuration for 5000 series */
  void iwl5000_nic_config(struct iwl_priv *priv)
  {
        unsigned long flags;
        u16 radio_cfg;
 -      u16 lctl;
  
        spin_lock_irqsave(&priv->lock, flags);
  
 -      lctl = iwl_pcie_link_ctl(priv);
 -
 -      /* HW bug W/A */
 -      /* L1-ASPM is enabled by BIOS */
 -      if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
 -              /* L1-APSM enabled: disable L0S  */
 -              iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
 -      else
 -              /* L1-ASPM disabled: enable L0S */
 -              iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
 -
        radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
  
        /* write radio config values to register */
 -      if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_5000_RF_CFG_TYPE_MAX)
 +      if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_RF_CONFIG_TYPE_MAX)
                iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
                            EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
@@@ -163,22 -302,19 +164,22 @@@ u16 iwl5000_eeprom_calib_version(struc
  static void iwl5000_gain_computation(struct iwl_priv *priv,
                u32 average_noise[NUM_RX_CHAINS],
                u16 min_average_noise_antenna_i,
 -              u32 min_average_noise)
 +              u32 min_average_noise,
 +              u8 default_chain)
  {
        int i;
        s32 delta_g;
        struct iwl_chain_noise_data *data = &priv->chain_noise_data;
  
 -      /* Find Gain Code for the antennas B and C */
 -      for (i = 1; i < NUM_RX_CHAINS; i++) {
 +      /*
 +       * Find Gain Code for the chains based on "default chain"
 +       */
 +      for (i = default_chain + 1; i < NUM_RX_CHAINS; i++) {
                if ((data->disconn_array[i])) {
                        data->delta_gain_code[i] = 0;
                        continue;
                }
 -              delta_g = (1000 * ((s32)average_noise[0] -
 +              delta_g = (1000 * ((s32)average_noise[default_chain] -
                        (s32)average_noise[i])) / 1500;
                /* bound gain by 2 bits value max, 3rd bit is sign */
                data->delta_gain_code[i] =
@@@ -271,10 -407,6 +272,10 @@@ static struct iwl_sensitivity_ranges iw
        .auto_corr_max_cck_mrc = 400,
        .nrg_th_cck = 95,
        .nrg_th_ofdm = 95,
 +
 +      .barker_corr_th_min = 190,
 +      .barker_corr_th_min_mrc = 390,
 +      .nrg_th_cca = 62,
  };
  
  static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
        .auto_corr_max_cck_mrc = 400,
        .nrg_th_cck = 95,
        .nrg_th_ofdm = 95,
 +
 +      .barker_corr_th_min = 190,
 +      .barker_corr_th_min_mrc = 390,
 +      .nrg_th_cca = 62,
  };
  
  const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
@@@ -365,7 -493,7 +366,7 @@@ static int iwl5000_send_calib_cfg(struc
  static void iwl5000_rx_calib_result(struct iwl_priv *priv,
                             struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
        int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
        int index;
@@@ -591,6 -719,16 +592,6 @@@ static void iwl5000_tx_queue_set_status
                       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
  }
  
 -static int iwl5000_send_wimax_coex(struct iwl_priv *priv)
 -{
 -      struct iwl_wimax_coex_cmd coex_cmd;
 -
 -      memset(&coex_cmd, 0, sizeof(coex_cmd));
 -
 -      return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
 -                              sizeof(coex_cmd), &coex_cmd);
 -}
 -
  int iwl5000_alive_notify(struct iwl_priv *priv)
  {
        u32 a;
        for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET;
                a += 4)
                iwl_write_targ_mem(priv, a, 0);
 -      for (; a < sizeof(u16) * priv->hw_params.max_txq_num; a += 4)
 +      for (; a < priv->scd_base_addr +
 +             IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
                iwl_write_targ_mem(priv, a, 0);
  
        iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
                iwl_txq_ctx_activate(priv, i);
                iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
        }
 -      /* TODO - need to initialize those FIFOs inside the loop above,
 -       * not only mark them as active */
 -      iwl_txq_ctx_activate(priv, 4);
 +
 +      /*
 +       * TODO - need to initialize these queues and map them to FIFOs
 +       * in the loop above, not only mark them as active. We do this
 +       * because we want the first aggregation queue to be queue #10,
 +       * but do not use 8 or 9 otherwise yet.
 +       */
        iwl_txq_ctx_activate(priv, 7);
        iwl_txq_ctx_activate(priv, 8);
        iwl_txq_ctx_activate(priv, 9);
        spin_unlock_irqrestore(&priv->lock, flags);
  
  
 -      iwl5000_send_wimax_coex(priv);
 +      iwl_send_wimax_coex(priv);
  
        iwl5000_set_Xtal_calib(priv);
        iwl_send_calib_results(priv);
  
  int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
  {
 -      if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) ||
 -          (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
 -              IWL_ERR(priv,
 -                      "invalid queues_num, should be between %d and %d\n",
 -                      IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
 -              return -EINVAL;
 -      }
 +      if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
 +          priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES)
 +              priv->cfg->num_of_queues =
 +                      priv->cfg->mod_params->num_of_queues;
  
 -      priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
 +      priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
        priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
        priv->hw_params.scd_bc_tbls_size =
 -                      IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
 +                      priv->cfg->num_of_queues *
 +                      sizeof(struct iwl5000_scd_bc_tbl);
        priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
        priv->hw_params.max_stations = IWL5000_STATION_COUNT;
        priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
  
 -      switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
 -      case CSR_HW_REV_TYPE_6x00:
 -      case CSR_HW_REV_TYPE_6x50:
 -              priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
 -              priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
 -              break;
 -      default:
 -              priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
 -              priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
 -      }
 +      priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
 +      priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
  
        priv->hw_params.max_bsm_size = 0;
        priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
@@@ -846,13 -989,11 +847,13 @@@ int iwl5000_txq_agg_enable(struct iwl_p
        u16 ra_tid;
  
        if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
 -          (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
 +          (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
 +           <= txq_id)) {
                IWL_WARN(priv,
                        "queue number out of range: %d, must be %d to %d\n",
                        txq_id, IWL50_FIRST_AMPDU_QUEUE,
 -                      IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
 +                      IWL50_FIRST_AMPDU_QUEUE +
 +                      priv->cfg->num_of_ampdu_queues - 1);
                return -EINVAL;
        }
  
@@@ -906,13 -1047,11 +907,13 @@@ int iwl5000_txq_agg_disable(struct iwl_
                                   u16 ssn_idx, u8 tx_fifo)
  {
        if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
 -          (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
 +          (IWL50_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues
 +           <= txq_id)) {
                IWL_ERR(priv,
                        "queue number out of range: %d, must be %d to %d\n",
                        txq_id, IWL50_FIRST_AMPDU_QUEUE,
 -                      IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
 +                      IWL50_FIRST_AMPDU_QUEUE +
 +                      priv->cfg->num_of_ampdu_queues - 1);
                return -EINVAL;
        }
  
@@@ -1079,7 -1218,7 +1080,7 @@@ static int iwl5000_tx_status_reply_tx(s
  static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
                                struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
@@@ -1320,24 -1459,6 +1321,24 @@@ int iwl5000_calc_rssi(struct iwl_priv *
        return max_rssi - agc - IWL49_RSSI_OFFSET;
  }
  
 +static int iwl5000_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
 +{
 +      struct iwl_tx_ant_config_cmd tx_ant_cmd = {
 +        .valid = cpu_to_le32(valid_tx_ant),
 +      };
 +
 +      if (IWL_UCODE_API(priv->ucode_ver) > 1) {
 +              IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
 +              return iwl_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD,
 +                                      sizeof(struct iwl_tx_ant_config_cmd),
 +                                      &tx_ant_cmd);
 +      } else {
 +              IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
 +              return -EOPNOTSUPP;
 +      }
 +}
 +
 +
  #define IWL5000_UCODE_GET(item)                                               \
  static u32 iwl5000_ucode_get_##item(const struct iwl_ucode_header *ucode,\
                                    u32 api_ver)                        \
@@@ -1376,43 -1497,10 +1377,43 @@@ IWL5000_UCODE_GET(init_size)
  IWL5000_UCODE_GET(init_data_size);
  IWL5000_UCODE_GET(boot_size);
  
 +static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 +{
 +      struct iwl5000_channel_switch_cmd cmd;
 +      const struct iwl_channel_info *ch_info;
 +      struct iwl_host_cmd hcmd = {
 +              .id = REPLY_CHANNEL_SWITCH,
 +              .len = sizeof(cmd),
 +              .flags = CMD_SIZE_HUGE,
 +              .data = &cmd,
 +      };
 +
 +      IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
 +              priv->active_rxon.channel, channel);
 +      cmd.band = priv->band == IEEE80211_BAND_2GHZ;
 +      cmd.channel = cpu_to_le16(channel);
 +      cmd.rxon_flags = priv->staging_rxon.flags;
 +      cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
 +      cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
 +      ch_info = iwl_get_channel_info(priv, priv->band, channel);
 +      if (ch_info)
 +              cmd.expect_beacon = is_channel_radar(ch_info);
 +      else {
 +              IWL_ERR(priv, "invalid channel switch from %u to %u\n",
 +                      priv->active_rxon.channel, channel);
 +              return -EFAULT;
 +      }
 +      priv->switch_rxon.channel = cpu_to_le16(channel);
 +      priv->switch_rxon.switch_in_progress = true;
 +
 +      return iwl_send_cmd_sync(priv, &hcmd);
 +}
 +
  struct iwl_hcmd_ops iwl5000_hcmd = {
        .rxon_assoc = iwl5000_send_rxon_assoc,
        .commit_rxon = iwl_commit_rxon,
        .set_rxon_chain = iwl_set_rxon_chain,
 +      .set_tx_ant = iwl5000_send_tx_ant_config,
  };
  
  struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
@@@ -1455,10 -1543,10 +1456,10 @@@ struct iwl_lib_ops iwl5000_lib = 
        .alive_notify = iwl5000_alive_notify,
        .send_tx_power = iwl5000_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
 +      .set_channel_switch = iwl5000_hw_channel_switch,
        .apm_ops = {
 -              .init = iwl5000_apm_init,
 -              .reset = iwl5000_apm_reset,
 -              .stop = iwl5000_apm_stop,
 +              .init = iwl_apm_init,
 +              .stop = iwl_apm_stop,
                .config = iwl5000_nic_config,
                .set_pwr_src = iwl_set_pwr_src,
        },
@@@ -1507,10 -1595,10 +1508,10 @@@ static struct iwl_lib_ops iwl5150_lib 
        .alive_notify = iwl5000_alive_notify,
        .send_tx_power = iwl5000_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
 +      .set_channel_switch = iwl5000_hw_channel_switch,
        .apm_ops = {
 -              .init = iwl5000_apm_init,
 -              .reset = iwl5000_apm_reset,
 -              .stop = iwl5000_apm_stop,
 +              .init = iwl_apm_init,
 +              .stop = iwl_apm_stop,
                .config = iwl5000_nic_config,
                .set_pwr_src = iwl_set_pwr_src,
        },
         },
  };
  
 -struct iwl_ops iwl5000_ops = {
 +static struct iwl_ops iwl5000_ops = {
        .ucode = &iwl5000_ucode,
        .lib = &iwl5000_lib,
        .hcmd = &iwl5000_hcmd,
        .utils = &iwl5000_hcmd_utils,
 +      .led = &iwlagn_led_ops,
  };
  
  static struct iwl_ops iwl5150_ops = {
        .lib = &iwl5150_lib,
        .hcmd = &iwl5000_hcmd,
        .utils = &iwl5000_hcmd_utils,
 +      .led = &iwlagn_led_ops,
  };
  
  struct iwl_mod_params iwl50_mod_params = {
 -      .num_of_queues = IWL50_NUM_QUEUES,
 -      .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
        .amsdu_size_8K = 1,
        .restart_fw = 1,
        /* the rest are 0 by default */
@@@ -1572,17 -1660,11 +1573,17 @@@ struct iwl_cfg iwl5300_agn_cfg = 
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 +      .num_of_queues = IWL50_NUM_QUEUES,
 +      .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
        .mod_params = &iwl50_mod_params,
        .valid_tx_ant = ANT_ABC,
        .valid_rx_ant = ANT_ABC,
 -      .need_pll_cfg = true,
 +      .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
 +      .set_l0s = true,
 +      .use_bsm = false,
        .ht_greenfield_support = true,
 +      .led_compensation = 51,
 +      .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
  };
  
  struct iwl_cfg iwl5100_bg_cfg = {
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 +      .num_of_queues = IWL50_NUM_QUEUES,
 +      .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
        .mod_params = &iwl50_mod_params,
        .valid_tx_ant = ANT_B,
        .valid_rx_ant = ANT_AB,
 -      .need_pll_cfg = true,
 +      .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
 +      .set_l0s = true,
 +      .use_bsm = false,
        .ht_greenfield_support = true,
 +      .led_compensation = 51,
 +      .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
  };
  
  struct iwl_cfg iwl5100_abg_cfg = {
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 +      .num_of_queues = IWL50_NUM_QUEUES,
 +      .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
        .mod_params = &iwl50_mod_params,
        .valid_tx_ant = ANT_B,
        .valid_rx_ant = ANT_AB,
 -      .need_pll_cfg = true,
 +      .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
 +      .set_l0s = true,
 +      .use_bsm = false,
        .ht_greenfield_support = true,
 +      .led_compensation = 51,
 +      .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
  };
  
  struct iwl_cfg iwl5100_agn_cfg = {
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 +      .num_of_queues = IWL50_NUM_QUEUES,
 +      .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
        .mod_params = &iwl50_mod_params,
        .valid_tx_ant = ANT_B,
        .valid_rx_ant = ANT_AB,
 -      .need_pll_cfg = true,
 +      .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
 +      .set_l0s = true,
 +      .use_bsm = false,
        .ht_greenfield_support = true,
 +      .led_compensation = 51,
 +      .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
  };
  
  struct iwl_cfg iwl5350_agn_cfg = {
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
 +      .num_of_queues = IWL50_NUM_QUEUES,
 +      .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
        .mod_params = &iwl50_mod_params,
        .valid_tx_ant = ANT_ABC,
        .valid_rx_ant = ANT_ABC,
 -      .need_pll_cfg = true,
 +      .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
 +      .set_l0s = true,
 +      .use_bsm = false,
        .ht_greenfield_support = true,
 +      .led_compensation = 51,
 +      .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
  };
  
  struct iwl_cfg iwl5150_agn_cfg = {
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
 +      .num_of_queues = IWL50_NUM_QUEUES,
 +      .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
        .mod_params = &iwl50_mod_params,
        .valid_tx_ant = ANT_A,
        .valid_rx_ant = ANT_AB,
 -      .need_pll_cfg = true,
 +      .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
 +      .set_l0s = true,
 +      .use_bsm = false,
        .ht_greenfield_support = true,
 +      .led_compensation = 51,
 +      .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
  };
  
  MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
  MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
  
 -module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444);
 +module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, S_IRUGO);
  MODULE_PARM_DESC(swcrypto50,
                  "using software crypto engine (default 0 [hardware])\n");
 -module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444);
 +module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, S_IRUGO);
  MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
 -module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444);
 +module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, S_IRUGO);
  MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality");
 -module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444);
 +module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K,
 +                 int, S_IRUGO);
  MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series");
 -module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, 0444);
 +module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, S_IRUGO);
  MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error");
index da0b38e866bac192e0443a5ca36d1785014db4f9,921dc4a26fe2eef00455865f996cf91d67d17bd3..29f7510ecdd7076a063e30819a2a8b2fe9452e20
@@@ -33,6 -33,7 +33,7 @@@
  #include <linux/pci.h>
  #include <linux/dma-mapping.h>
  #include <linux/delay.h>
+ #include <linux/sched.h>
  #include <linux/skbuff.h>
  #include <linux/netdevice.h>
  #include <linux/wireless.h>
@@@ -122,17 -123,6 +123,17 @@@ int iwl_commit_rxon(struct iwl_priv *pr
                return -EINVAL;
        }
  
 +      /*
 +       * receive commit_rxon request
 +       * abort any previous channel switch if still in process
 +       */
 +      if (priv->switch_rxon.switch_in_progress &&
 +          (priv->switch_rxon.channel != priv->staging_rxon.channel)) {
 +              IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
 +                    le16_to_cpu(priv->switch_rxon.channel));
 +              priv->switch_rxon.switch_in_progress = false;
 +      }
 +
        /* If we don't need to send a full RXON, we can use
         * iwl_rxon_assoc_cmd which is used to reconfigure filter
         * and other flags for the current radio configuration. */
                }
  
                memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
 +              iwl_print_rx_config_cmd(priv);
                return 0;
        }
  
        priv->start_calib = 0;
  
        /* Add the broadcast address so we can send broadcast frames */
 -      if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
 -                                              IWL_INVALID_STATION) {
 -              IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
 -              return -EIO;
 -      }
 +      iwl_add_bcast_station(priv);
  
        /* If we have set the ASSOC_MSK and we are in BSS mode then
         * add the IWL_AP_ID to the station rate table */
                }
                memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
        }
 +      iwl_print_rx_config_cmd(priv);
  
        iwl_init_sensitivity(priv);
  
@@@ -533,7 -525,7 +534,7 @@@ int iwl_hw_tx_queue_init(struct iwl_pri
  static void iwl_rx_reply_alive(struct iwl_priv *priv,
                                struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_alive_resp *palive;
        struct delayed_work *pwork;
  
@@@ -619,7 -611,7 +620,7 @@@ static void iwl_rx_beacon_notif(struct 
                                struct iwl_rx_mem_buffer *rxb)
  {
  #ifdef CONFIG_IWLWIFI_DEBUG
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl4965_beacon_notif *beacon =
                (struct iwl4965_beacon_notif *)pkt->u.raw;
        u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
  static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                                    struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
        unsigned long status = priv->status;
  
@@@ -778,7 -770,7 +779,7 @@@ void iwl_rx_handle(struct iwl_priv *pri
                IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
  
        /* calculate total frames need to be restock after handling RX */
 -      total_empty = r - priv->rxq.write_actual;
 +      total_empty = r - rxq->write_actual;
        if (total_empty < 0)
                total_empty += RX_QUEUE_SIZE;
  
  
                rxq->queue[i] = NULL;
  
 -              pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
 -                               priv->hw_params.rx_buf_size + 256,
 -                               PCI_DMA_FROMDEVICE);
 -              pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +              pci_unmap_page(priv->pci_dev, rxb->page_dma,
 +                             PAGE_SIZE << priv->hw_params.rx_page_order,
 +                             PCI_DMA_FROMDEVICE);
 +              pkt = rxb_addr(rxb);
 +
 +              trace_iwlwifi_dev_rx(priv, pkt,
 +                      le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
  
                /* Reclaim a command buffer only if this packet is a response
                 *   to a (driver-originated) command.
                if (priv->rx_handlers[pkt->hdr.cmd]) {
                        IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
                                i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
 -                      priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
                        priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
 +                      priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
                } else {
                        /* No handling needed */
                        IWL_DEBUG_RX(priv,
                                pkt->hdr.cmd);
                }
  
 +              /*
 +               * XXX: After here, we should always check rxb->page
 +               * against NULL before touching it or its virtual
 +               * memory (pkt). Because some rx_handler might have
 +               * already taken or freed the pages.
 +               */
 +
                if (reclaim) {
 -                      /* Invoke any callbacks, transfer the skb to caller, and
 -                       * fire off the (possibly) blocking iwl_send_cmd()
 +                      /* Invoke any callbacks, transfer the buffer to caller,
 +                       * and fire off the (possibly) blocking iwl_send_cmd()
                         * as we reclaim the driver command queue */
 -                      if (rxb && rxb->skb)
 +                      if (rxb->page)
                                iwl_tx_cmd_complete(priv, rxb);
                        else
                                IWL_WARN(priv, "Claim null rxb?\n");
                }
  
 -              /* For now we just don't re-use anything.  We can tweak this
 -               * later to try and re-use notification packets and SKBs that
 -               * fail to Rx correctly */
 -              if (rxb->skb != NULL) {
 -                      priv->alloc_rxb_skb--;
 -                      dev_kfree_skb_any(rxb->skb);
 -                      rxb->skb = NULL;
 -              }
 -
 +              /* Reuse the page if possible. For notification packets and
 +               * SKBs that fail to Rx correctly, add them back into the
 +               * rx_free list for reuse later. */
                spin_lock_irqsave(&rxq->lock, flags);
 -              list_add_tail(&rxb->list, &priv->rxq.rx_used);
 +              if (rxb->page != NULL) {
 +                      rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page,
 +                              0, PAGE_SIZE << priv->hw_params.rx_page_order,
 +                              PCI_DMA_FROMDEVICE);
 +                      list_add_tail(&rxb->list, &rxq->rx_free);
 +                      rxq->free_count++;
 +              } else
 +                      list_add_tail(&rxb->list, &rxq->rx_used);
 +
                spin_unlock_irqrestore(&rxq->lock, flags);
 +
                i = (i + 1) & RX_QUEUE_MASK;
                /* If there are a lot of unused frames,
                 * restock the Rx queue so ucode wont assert. */
                if (fill_rx) {
                        count++;
                        if (count >= 8) {
 -                              priv->rxq.read = i;
 +                              rxq->read = i;
                                iwl_rx_replenish_now(priv);
                                count = 0;
                        }
        }
  
        /* Backtrack one entry */
 -      priv->rxq.read = i;
 +      rxq->read = i;
        if (fill_rx)
                iwl_rx_replenish_now(priv);
        else
@@@ -899,7 -878,6 +900,7 @@@ static void iwl_irq_tasklet_legacy(stru
        u32 inta, handled = 0;
        u32 inta_fh;
        unsigned long flags;
 +      u32 i;
  #ifdef CONFIG_IWLWIFI_DEBUG
        u32 inta_mask;
  #endif
        }
  #endif
  
 +      spin_unlock_irqrestore(&priv->lock, flags);
 +
        /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
         * atomic, make sure that inta covers all the interrupts that
         * we've discovered, even if FH interrupt came in just after
  
                handled |= CSR_INT_BIT_HW_ERR;
  
 -              spin_unlock_irqrestore(&priv->lock, flags);
 -
                return;
        }
  
                handled |= CSR_INT_BIT_SW_ERR;
        }
  
 -      /* uCode wakes up after power-down sleep */
 +      /*
 +       * uCode wakes up after power-down sleep.
 +       * Tell device about any new tx or host commands enqueued,
 +       * and about any Rx buffers made available while asleep.
 +       */
        if (inta & CSR_INT_BIT_WAKEUP) {
                IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
                iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[0]);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[1]);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[2]);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[3]);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[4]);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[5]);
 -
 +              for (i = 0; i < priv->hw_params.max_txq_num; i++)
 +                      iwl_txq_update_write_ptr(priv, &priv->txq[i]);
                priv->isr_stats.wakeup++;
 -
                handled |= CSR_INT_BIT_WAKEUP;
        }
  
        if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
                iwl_rx_handle(priv);
                priv->isr_stats.rx++;
 +              iwl_leds_background(priv);
                handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
        }
  
 +      /* This "Tx" DMA channel is used only for loading uCode */
        if (inta & CSR_INT_BIT_FH_TX) {
 -              IWL_DEBUG_ISR(priv, "Tx interrupt\n");
 +              IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
                priv->isr_stats.tx++;
                handled |= CSR_INT_BIT_FH_TX;
 -              /* FH finished to write, send event */
 +              /* Wake up uCode load routine, now that load is complete */
                priv->ucode_write_complete = 1;
                wake_up_interruptible(&priv->wait_command_queue);
        }
                        "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
        }
  #endif
 -      spin_unlock_irqrestore(&priv->lock, flags);
  }
  
  /* tasklet for iwlagn interrupt */
@@@ -1084,7 -1063,6 +1085,7 @@@ static void iwl_irq_tasklet(struct iwl_
        u32 inta = 0;
        u32 handled = 0;
        unsigned long flags;
 +      u32 i;
  #ifdef CONFIG_IWLWIFI_DEBUG
        u32 inta_mask;
  #endif
                                inta, inta_mask);
        }
  #endif
 +
 +      spin_unlock_irqrestore(&priv->lock, flags);
 +
        /* saved interrupt in inta variable now we can reset priv->inta */
        priv->inta = 0;
  
  
                handled |= CSR_INT_BIT_HW_ERR;
  
 -              spin_unlock_irqrestore(&priv->lock, flags);
 -
                return;
        }
  
        if (inta & CSR_INT_BIT_WAKEUP) {
                IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
                iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[0]);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[1]);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[2]);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[3]);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[4]);
 -              iwl_txq_update_write_ptr(priv, &priv->txq[5]);
 +              for (i = 0; i < priv->hw_params.max_txq_num; i++)
 +                      iwl_txq_update_write_ptr(priv, &priv->txq[i]);
  
                priv->isr_stats.wakeup++;
  
                                    CSR_INT_PERIODIC_ENA);
  
                priv->isr_stats.rx++;
 +              iwl_leds_background(priv);
        }
  
 +      /* This "Tx" DMA channel is used only for loading uCode */
        if (inta & CSR_INT_BIT_FH_TX) {
                iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK);
 -              IWL_DEBUG_ISR(priv, "Tx interrupt\n");
 +              IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
                priv->isr_stats.tx++;
                handled |= CSR_INT_BIT_FH_TX;
 -              /* FH finished to write, send event */
 +              /* Wake up uCode load routine, now that load is complete */
                priv->ucode_write_complete = 1;
                wake_up_interruptible(&priv->wait_command_queue);
        }
                         inta & ~priv->inta_mask);
        }
  
 -
        /* Re-enable all interrupts */
        /* only Re-enable if diabled by irq */
        if (test_bit(STATUS_INT_ENABLED, &priv->status))
                iwl_enable_interrupts(priv);
 -
 -      spin_unlock_irqrestore(&priv->lock, flags);
 -
  }
  
  
@@@ -1384,14 -1367,6 +1385,14 @@@ static int iwl_read_ucode(struct iwl_pr
               IWL_UCODE_API(priv->ucode_ver),
               IWL_UCODE_SERIAL(priv->ucode_ver));
  
 +      snprintf(priv->hw->wiphy->fw_version,
 +               sizeof(priv->hw->wiphy->fw_version),
 +               "%u.%u.%u.%u",
 +               IWL_UCODE_MAJOR(priv->ucode_ver),
 +               IWL_UCODE_MINOR(priv->ucode_ver),
 +               IWL_UCODE_API(priv->ucode_ver),
 +               IWL_UCODE_SERIAL(priv->ucode_ver));
 +
        if (build)
                IWL_DEBUG_INFO(priv, "Build %u\n", build);
  
@@@ -1636,9 -1611,6 +1637,9 @@@ void iwl_dump_nic_error_log(struct iwl_
        line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
        time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
  
 +      trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line,
 +                                    blink1, blink2, ilink1, ilink2);
 +
        IWL_ERR(priv, "Desc                               Time       "
                "data1      data2      line\n");
        IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
@@@ -1663,7 -1635,6 +1664,7 @@@ static void iwl_print_event_log(struct 
        u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
        u32 ptr;        /* SRAM byte address of log data */
        u32 ev, time, data; /* event log data */
 +      unsigned long reg_flags;
  
        if (num_events == 0)
                return;
  
        ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
  
 +      /* Make sure device is powered up for SRAM reads */
 +      spin_lock_irqsave(&priv->reg_lock, reg_flags);
 +      iwl_grab_nic_access(priv);
 +
 +      /* Set starting address; reads will auto-increment */
 +      _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
 +      rmb();
 +
        /* "time" is actually "data" for mode 0 (no timestamp).
        * place event id # at far right for easier visual parsing. */
        for (i = 0; i < num_events; i++) {
 -              ev = iwl_read_targ_mem(priv, ptr);
 -              ptr += sizeof(u32);
 -              time = iwl_read_targ_mem(priv, ptr);
 -              ptr += sizeof(u32);
 +              ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 +              time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                if (mode == 0) {
                        /* data, ev */
 +                      trace_iwlwifi_dev_ucode_event(priv, 0, time, ev);
                        IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
                } else {
 -                      data = iwl_read_targ_mem(priv, ptr);
 -                      ptr += sizeof(u32);
 +                      data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                        IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
                                        time, data, ev);
 +                      trace_iwlwifi_dev_ucode_event(priv, time, data, ev);
                }
        }
 +
 +      /* Allow device to power down */
 +      iwl_release_nic_access(priv);
 +      spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
  }
  
 +/* For sanity check only.  Actual size is determined by uCode, typ. 512 */
 +#define MAX_EVENT_LOG_SIZE (512)
 +
  void iwl_dump_nic_event_log(struct iwl_priv *priv)
  {
        u32 base;       /* SRAM byte address of event log header */
        num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
        next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
  
 +      if (capacity > MAX_EVENT_LOG_SIZE) {
 +              IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
 +                      capacity, MAX_EVENT_LOG_SIZE);
 +              capacity = MAX_EVENT_LOG_SIZE;
 +      }
 +
 +      if (next_entry > MAX_EVENT_LOG_SIZE) {
 +              IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
 +                      next_entry, MAX_EVENT_LOG_SIZE);
 +              next_entry = MAX_EVENT_LOG_SIZE;
 +      }
 +
        size = num_wraps ? capacity : next_entry;
  
        /* bail out if nothing in log */
@@@ -1818,10 -1763,6 +1819,10 @@@ static void iwl_alive_start(struct iwl_
        priv->active_rate = priv->rates_mask;
        priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
  
 +      /* Configure Tx antenna selection based on H/W config */
 +      if (priv->cfg->ops->hcmd->set_tx_ant)
 +              priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant);
 +
        if (iwl_is_associated(priv)) {
                struct iwl_rxon_cmd *active_rxon =
                                (struct iwl_rxon_cmd *)&priv->active_rxon;
        /* At this point, the NIC is initialized and operational */
        iwl_rf_kill_ct_config(priv);
  
 -      iwl_leds_register(priv);
 +      iwl_leds_init(priv);
  
        IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
        set_bit(STATUS_READY, &priv->status);
@@@ -1887,6 -1828,8 +1888,6 @@@ static void __iwl_down(struct iwl_priv 
        if (!exit_pending)
                set_bit(STATUS_EXIT_PENDING, &priv->status);
  
 -      iwl_leds_unregister(priv);
 -
        iwl_clear_stations_table(priv);
  
        /* Unblock any waiting calls */
  
        /* device going down, Stop using ICT table */
        iwl_disable_ict(priv);
 -      spin_lock_irqsave(&priv->lock, flags);
 -      iwl_clear_bit(priv, CSR_GP_CNTRL,
 -                       CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 -      spin_unlock_irqrestore(&priv->lock, flags);
  
        iwl_txq_ctx_stop(priv);
        iwl_rxq_stop(priv);
  
 -      iwl_write_prph(priv, APMG_CLK_DIS_REG,
 -                              APMG_CLK_VAL_DMA_CLK_RQT);
 -
 +      /* Power-down device's busmaster DMA clocks */
 +      iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
        udelay(5);
  
 -      /* FIXME: apm_ops.suspend(priv) */
 -      if (exit_pending)
 -              priv->cfg->ops->lib->apm_ops.stop(priv);
 -      else
 -              priv->cfg->ops->lib->apm_ops.reset(priv);
 +      /* Make sure (redundant) we've released our request to stay awake */
 +      iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 +
 +      /* Stop the device, and put it in low power state */
 +      priv->cfg->ops->lib->apm_ops.stop(priv);
 +
   exit:
        memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
  
@@@ -2334,69 -2281,6 +2335,69 @@@ void iwl_post_associate(struct iwl_pri
  
  #define UCODE_READY_TIMEOUT   (4 * HZ)
  
 +/*
 + * Not a mac80211 entry point function, but it fits in with all the
 + * other mac80211 functions grouped here.
 + */
 +static int iwl_setup_mac(struct iwl_priv *priv)
 +{
 +      int ret;
 +      struct ieee80211_hw *hw = priv->hw;
 +      hw->rate_control_algorithm = "iwl-agn-rs";
 +
 +      /* Tell mac80211 our characteristics */
 +      hw->flags = IEEE80211_HW_SIGNAL_DBM |
 +                  IEEE80211_HW_NOISE_DBM |
 +                  IEEE80211_HW_AMPDU_AGGREGATION |
 +                  IEEE80211_HW_SPECTRUM_MGMT;
 +
 +      if (!priv->cfg->broken_powersave)
 +              hw->flags |= IEEE80211_HW_SUPPORTS_PS |
 +                           IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
 +
 +      hw->sta_data_size = sizeof(struct iwl_station_priv);
 +      hw->wiphy->interface_modes =
 +              BIT(NL80211_IFTYPE_STATION) |
 +              BIT(NL80211_IFTYPE_ADHOC);
 +
 +      hw->wiphy->custom_regulatory = true;
 +
 +      /* Firmware does not support this */
 +      hw->wiphy->disable_beacon_hints = true;
 +
 +      /*
 +       * For now, disable PS by default because it affects
 +       * RX performance significantly.
 +       */
 +      hw->wiphy->ps_default = false;
 +
 +      hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
 +      /* we create the 802.11 header and a zero-length SSID element */
 +      hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
 +
 +      /* Default value; 4 EDCA QOS priorities */
 +      hw->queues = 4;
 +
 +      hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
 +
 +      if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
 +              priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
 +                      &priv->bands[IEEE80211_BAND_2GHZ];
 +      if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
 +              priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 +                      &priv->bands[IEEE80211_BAND_5GHZ];
 +
 +      ret = ieee80211_register_hw(priv->hw);
 +      if (ret) {
 +              IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
 +              return ret;
 +      }
 +      priv->mac80211_registered = 1;
 +
 +      return 0;
 +}
 +
 +
  static int iwl_mac_start(struct ieee80211_hw *hw)
  {
        struct iwl_priv *priv = hw->priv;
                }
        }
  
 +      iwl_led_start(priv);
 +
  out:
        priv->is_open = 1;
        IWL_DEBUG_MAC80211(priv, "leave\n");
@@@ -2553,7 -2435,7 +2554,7 @@@ void iwl_config_ap(struct iwl_priv *pri
                spin_lock_irqsave(&priv->lock, flags);
                iwl_activate_qos(priv, 1);
                spin_unlock_irqrestore(&priv->lock, flags);
 -              iwl_rxon_add_station(priv, iwl_bcast_addr, 0);
 +              iwl_add_bcast_station(priv);
        }
        iwl_send_beacon_cmd(priv);
  
@@@ -2917,40 -2799,6 +2918,40 @@@ static ssize_t show_statistics(struct d
  
  static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
  
 +static ssize_t show_rts_ht_protection(struct device *d,
 +                           struct device_attribute *attr, char *buf)
 +{
 +      struct iwl_priv *priv = dev_get_drvdata(d);
 +
 +      return sprintf(buf, "%s\n",
 +              priv->cfg->use_rts_for_ht ? "RTS/CTS" : "CTS-to-self");
 +}
 +
 +static ssize_t store_rts_ht_protection(struct device *d,
 +                            struct device_attribute *attr,
 +                            const char *buf, size_t count)
 +{
 +      struct iwl_priv *priv = dev_get_drvdata(d);
 +      unsigned long val;
 +      int ret;
 +
 +      ret = strict_strtoul(buf, 10, &val);
 +      if (ret)
 +              IWL_INFO(priv, "Input is not in decimal form.\n");
 +      else {
 +              if (!iwl_is_associated(priv))
 +                      priv->cfg->use_rts_for_ht = val ? true : false;
 +              else
 +                      IWL_ERR(priv, "Sta associated with AP - "
 +                              "Change protection mechanism is not allowed\n");
 +              ret = count;
 +      }
 +      return ret;
 +}
 +
 +static DEVICE_ATTR(rts_ht_protection, S_IWUSR | S_IRUGO,
 +                      show_rts_ht_protection, store_rts_ht_protection);
 +
  
  /*****************************************************************************
   *
@@@ -3001,107 -2849,12 +3002,107 @@@ static void iwl_cancel_deferred_work(st
        del_timer_sync(&priv->statistics_periodic);
  }
  
 +static void iwl_init_hw_rates(struct iwl_priv *priv,
 +                            struct ieee80211_rate *rates)
 +{
 +      int i;
 +
 +      for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
 +              rates[i].bitrate = iwl_rates[i].ieee * 5;
 +              rates[i].hw_value = i; /* Rate scaling will work on indexes */
 +              rates[i].hw_value_short = i;
 +              rates[i].flags = 0;
 +              if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) {
 +                      /*
 +                       * If CCK != 1M then set short preamble rate flag.
 +                       */
 +                      rates[i].flags |=
 +                              (iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ?
 +                                      0 : IEEE80211_RATE_SHORT_PREAMBLE;
 +              }
 +      }
 +}
 +
 +static int iwl_init_drv(struct iwl_priv *priv)
 +{
 +      int ret;
 +
 +      priv->ibss_beacon = NULL;
 +
 +      spin_lock_init(&priv->lock);
 +      spin_lock_init(&priv->sta_lock);
 +      spin_lock_init(&priv->hcmd_lock);
 +
 +      INIT_LIST_HEAD(&priv->free_frames);
 +
 +      mutex_init(&priv->mutex);
 +
 +      /* Clear the driver's (not device's) station table */
 +      iwl_clear_stations_table(priv);
 +
 +      priv->ieee_channels = NULL;
 +      priv->ieee_rates = NULL;
 +      priv->band = IEEE80211_BAND_2GHZ;
 +
 +      priv->iw_mode = NL80211_IFTYPE_STATION;
 +      if (priv->cfg->support_sm_ps)
 +              priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DYNAMIC;
 +      else
 +              priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
 +
 +      /* Choose which receivers/antennas to use */
 +      if (priv->cfg->ops->hcmd->set_rxon_chain)
 +              priv->cfg->ops->hcmd->set_rxon_chain(priv);
 +
 +      iwl_init_scan_params(priv);
 +
 +      iwl_reset_qos(priv);
 +
 +      priv->qos_data.qos_active = 0;
 +      priv->qos_data.qos_cap.val = 0;
 +
 +      priv->rates_mask = IWL_RATES_MASK;
 +      /* Set the tx_power_user_lmt to the lowest power level
 +       * this value will get overwritten by channel max power avg
 +       * from eeprom */
 +      priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MIN;
 +
 +      ret = iwl_init_channel_map(priv);
 +      if (ret) {
 +              IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
 +              goto err;
 +      }
 +
 +      ret = iwlcore_init_geos(priv);
 +      if (ret) {
 +              IWL_ERR(priv, "initializing geos failed: %d\n", ret);
 +              goto err_free_channel_map;
 +      }
 +      iwl_init_hw_rates(priv, priv->ieee_rates);
 +
 +      return 0;
 +
 +err_free_channel_map:
 +      iwl_free_channel_map(priv);
 +err:
 +      return ret;
 +}
 +
 +static void iwl_uninit_drv(struct iwl_priv *priv)
 +{
 +      iwl_calib_free_results(priv);
 +      iwlcore_free_geos(priv);
 +      iwl_free_channel_map(priv);
 +      kfree(priv->scan);
 +}
 +
  static struct attribute *iwl_sysfs_entries[] = {
        &dev_attr_flags.attr,
        &dev_attr_filter_flags.attr,
        &dev_attr_statistics.attr,
        &dev_attr_temperature.attr,
        &dev_attr_tx_power.attr,
 +      &dev_attr_rts_ht_protection.attr,
  #ifdef CONFIG_IWLWIFI_DEBUG
        &dev_attr_debug_level.attr,
  #endif
@@@ -3237,6 -2990,12 +3238,6 @@@ static int iwl_pci_probe(struct pci_de
                goto out_iounmap;
        }
  
 -      /* amp init */
 -      err = priv->cfg->ops->lib->apm_ops.init(priv);
 -      if (err < 0) {
 -              IWL_ERR(priv, "Failed to init APMG\n");
 -              goto out_iounmap;
 -      }
        /*****************
         * 4. Read EEPROM
         *****************/
@@@ -3382,15 -3141,6 +3383,15 @@@ static void __devexit iwl_pci_remove(st
                iwl_down(priv);
        }
  
 +      /*
 +       * Make sure device is reset to low power before unloading driver.
 +       * This may be redundant with iwl_down(), but there are paths to
 +       * run iwl_down() without calling apm_ops.stop(), and there are
 +       * paths to avoid running iwl_down() at all before leaving driver.
 +       * This (inexpensive) call *makes sure* device is reset.
 +       */
 +      priv->cfg->ops->lib->apm_ops.stop(priv);
 +
        iwl_tt_exit(priv);
  
        /* make sure we flush any pending irq or
@@@ -3470,43 -3220,20 +3471,43 @@@ static struct pci_device_id iwl_hw_card
  /* 5150 Wifi/WiMax */
        {IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)},
        {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},
 -/* 6000/6050 Series */
 -      {IWL_PCI_DEVICE(0x008D, PCI_ANY_ID, iwl6000h_2agn_cfg)},
 -      {IWL_PCI_DEVICE(0x008E, PCI_ANY_ID, iwl6000h_2agn_cfg)},
 -      {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
 -      {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000i_2agn_cfg)},
 -      {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
 -      {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000i_2agn_cfg)},
 -      {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
 -      {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
 -      {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
 -      {IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)},
 +
 +/* 6x00 Series */
 +      {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)},
 +      {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)},
 +      {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)},
 +      {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)},
 +      {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)},
 +      {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)},
 +      {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)},
 +      {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)},
 +      {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
 +      {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
 +
 +/* 6x50 WiFi/WiMax Series */
 +      {IWL_PCI_DEVICE(0x0086, 0x1101, iwl6050_3agn_cfg)},
 +      {IWL_PCI_DEVICE(0x0086, 0x1121, iwl6050_3agn_cfg)},
 +      {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
 +      {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)},
 +      {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)},
 +      {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)},
 +      {IWL_PCI_DEVICE(0x0088, 0x1111, iwl6050_3agn_cfg)},
 +      {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)},
 +      {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)},
 +
  /* 1000 Series WiFi */
 -      {IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl1000_bgn_cfg)},
 -      {IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl1000_bgn_cfg)},
 +      {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)},
 +      {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)},
 +      {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)},
 +      {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)},
 +      {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)},
 +      {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)},
 +      {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)},
 +      {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)},
 +      {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)},
 +      {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)},
 +      {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)},
 +      {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)},
  #endif /* CONFIG_IWL5000 */
  
        {0}
@@@ -3561,9 -3288,9 +3562,9 @@@ module_exit(iwl_exit)
  module_init(iwl_init);
  
  #ifdef CONFIG_IWLWIFI_DEBUG
 -module_param_named(debug50, iwl_debug_level, uint, 0444);
 +module_param_named(debug50, iwl_debug_level, uint, S_IRUGO);
  MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)");
 -module_param_named(debug, iwl_debug_level, uint, 0644);
 +module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR);
  MODULE_PARM_DESC(debug, "debug output mask");
  #endif
  
index d09e748153238ecbb78ca4a59f343a0d6a5c5f5c,2dc928755454b3e9906395bca20403359c06f7d1..6b18aab8fa9ba4a1a7c8804eccc2f06e71ca0796
@@@ -29,6 -29,7 +29,7 @@@
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/etherdevice.h>
+ #include <linux/sched.h>
  #include <net/mac80211.h>
  
  #include "iwl-eeprom.h"
@@@ -46,37 -47,6 +47,37 @@@ MODULE_VERSION(IWLWIFI_VERSION)
  MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
  MODULE_LICENSE("GPL");
  
 +static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
 +      {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
 +       0, COEX_UNASSOC_IDLE_FLAGS},
 +      {COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
 +       0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
 +      {COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
 +       0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
 +      {COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
 +       0, COEX_CALIBRATION_FLAGS},
 +      {COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
 +       0, COEX_PERIODIC_CALIBRATION_FLAGS},
 +      {COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
 +       0, COEX_CONNECTION_ESTAB_FLAGS},
 +      {COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
 +       0, COEX_ASSOCIATED_IDLE_FLAGS},
 +      {COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
 +       0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
 +      {COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
 +       0, COEX_ASSOC_AUTO_SCAN_FLAGS},
 +      {COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
 +       0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
 +      {COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
 +      {COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
 +      {COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
 +       0, COEX_STAND_ALONE_DEBUG_FLAGS},
 +      {COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
 +       0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
 +      {COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
 +      {COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
 +};
 +
  #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np)    \
        [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,      \
                                    IWL_RATE_SISO_##s##M_PLCP, \
@@@ -445,12 -415,8 +446,12 @@@ static void iwlcore_init_ht_hw_capab(co
        if (priv->cfg->ht_greenfield_support)
                ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
        ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
 -      ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
 -                           (WLAN_HT_CAP_SM_PS_DISABLED << 2));
 +      if (priv->cfg->support_sm_ps)
 +              ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
 +                                   (WLAN_HT_CAP_SM_PS_DYNAMIC << 2));
 +      else
 +              ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
 +                                   (WLAN_HT_CAP_SM_PS_DISABLED << 2));
  
        max_bit_rate = MAX_BIT_RATE_20_MHZ;
        if (priv->hw_params.ht40_channel & BIT(band)) {
        }
  }
  
 -static void iwlcore_init_hw_rates(struct iwl_priv *priv,
 -                            struct ieee80211_rate *rates)
 -{
 -      int i;
 -
 -      for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
 -              rates[i].bitrate = iwl_rates[i].ieee * 5;
 -              rates[i].hw_value = i; /* Rate scaling will work on indexes */
 -              rates[i].hw_value_short = i;
 -              rates[i].flags = 0;
 -              if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) {
 -                      /*
 -                       * If CCK != 1M then set short preamble rate flag.
 -                       */
 -                      rates[i].flags |=
 -                              (iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ?
 -                                      0 : IEEE80211_RATE_SHORT_PREAMBLE;
 -              }
 -      }
 -}
 -
 -
  /**
   * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
   */
@@@ -617,27 -605,11 +618,27 @@@ void iwlcore_free_geos(struct iwl_priv 
  }
  EXPORT_SYMBOL(iwlcore_free_geos);
  
 +/*
 + *  iwlcore_rts_tx_cmd_flag: Set rts/cts. 3945 and 4965 only share this
 + *  function.
 + */
 +void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
 +                              __le32 *tx_flags)
 +{
 +      if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
 +              *tx_flags |= TX_CMD_FLG_RTS_MSK;
 +              *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
 +      } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
 +              *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
 +              *tx_flags |= TX_CMD_FLG_CTS_MSK;
 +      }
 +}
 +EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag);
 +
  static bool is_single_rx_stream(struct iwl_priv *priv)
  {
        return !priv->current_ht_config.is_ht ||
 -             ((priv->current_ht_config.mcs.rx_mask[1] == 0) &&
 -              (priv->current_ht_config.mcs.rx_mask[2] == 0));
 +             priv->current_ht_config.single_chain_sufficient;
  }
  
  static u8 iwl_is_channel_extension(struct iwl_priv *priv,
  u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
                         struct ieee80211_sta_ht_cap *sta_ht_inf)
  {
 -      struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config;
 +      struct iwl_ht_config *ht_conf = &priv->current_ht_config;
  
 -      if ((!iwl_ht_conf->is_ht) ||
 -          (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ))
 +      if (!ht_conf->is_ht || !ht_conf->is_40mhz)
                return 0;
  
        /* We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
  #endif
        return iwl_is_channel_extension(priv, priv->band,
                        le16_to_cpu(priv->staging_rxon.channel),
 -                      iwl_ht_conf->extension_chan_offset);
 +                      ht_conf->extension_chan_offset);
  }
  EXPORT_SYMBOL(iwl_is_ht40_tx_allowed);
  
@@@ -905,11 -878,11 +906,11 @@@ u8 iwl_rate_get_lowest_plcp(struct iwl_
  }
  EXPORT_SYMBOL(iwl_rate_get_lowest_plcp);
  
 -void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
 +void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
  {
        struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
  
 -      if (!ht_info->is_ht) {
 +      if (!ht_conf->is_ht) {
                rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
                        RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
                        RXON_FLG_HT40_PROT_MSK |
        /* FIXME: if the definition of ht_protection changed, the "translation"
         * will be needed for rxon->flags
         */
 -      rxon->flags |= cpu_to_le32(ht_info->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS);
 +      rxon->flags |= cpu_to_le32(ht_conf->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS);
  
        /* Set up channel bandwidth:
         * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
                         RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
        if (iwl_is_ht40_tx_allowed(priv, NULL)) {
                /* pure ht40 */
 -              if (ht_info->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
 +              if (ht_conf->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
                        rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
                        /* Note: control channel is opposite of extension channel */
 -                      switch (ht_info->extension_chan_offset) {
 +                      switch (ht_conf->extension_chan_offset) {
                        case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
                                rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
                                break;
                        }
                } else {
                        /* Note: control channel is opposite of extension channel */
 -                      switch (ht_info->extension_chan_offset) {
 +                      switch (ht_conf->extension_chan_offset) {
                        case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
                                rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
                                rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
        if (priv->cfg->ops->hcmd->set_rxon_chain)
                priv->cfg->ops->hcmd->set_rxon_chain(priv);
  
 -      IWL_DEBUG_ASSOC(priv, "supported HT rate 0x%X 0x%X 0x%X "
 -                      "rxon flags 0x%X operation mode :0x%X "
 +      IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
                        "extension channel offset 0x%x\n",
 -                      ht_info->mcs.rx_mask[0],
 -                      ht_info->mcs.rx_mask[1],
 -                      ht_info->mcs.rx_mask[2],
 -                      le32_to_cpu(rxon->flags), ht_info->ht_protection,
 -                      ht_info->extension_chan_offset);
 +                      le32_to_cpu(rxon->flags), ht_conf->ht_protection,
 +                      ht_conf->extension_chan_offset);
        return;
  }
  EXPORT_SYMBOL(iwl_set_rxon_ht);
  #define IWL_NUM_IDLE_CHAINS_DUAL      2
  #define IWL_NUM_IDLE_CHAINS_SINGLE    1
  
 -/* Determine how many receiver/antenna chains to use.
 - * More provides better reception via diversity.  Fewer saves power.
 +/*
 + * Determine how many receiver/antenna chains to use.
 + *
 + * More provides better reception via diversity.  Fewer saves power
 + * at the expense of throughput, but only when not in powersave to
 + * start with.
 + *
   * MIMO (dual stream) requires at least 2, but works better with 3.
   * This does not determine *which* chains to use, just how many.
   */
  static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
  {
 -      bool is_single = is_single_rx_stream(priv);
 -      bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
 -
        /* # of Rx chains to use when expecting MIMO. */
 -      if (is_single || (!is_cam && (priv->current_ht_config.sm_ps ==
 -                                               WLAN_HT_CAP_SM_PS_STATIC)))
 +      if (is_single_rx_stream(priv))
                return IWL_NUM_RX_CHAINS_SINGLE;
        else
                return IWL_NUM_RX_CHAINS_MULTIPLE;
  }
  
 +/*
 + * When we are in power saving mode, unless device support spatial
 + * multiplexing power save, use the active count for rx chain count.
 + */
  static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
  {
 -      int idle_cnt;
 +      int idle_cnt = active_cnt;
        bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
 -      /* # Rx chains when idling and maybe trying to save power */
 -      switch (priv->current_ht_config.sm_ps) {
 -      case WLAN_HT_CAP_SM_PS_STATIC:
 -      case WLAN_HT_CAP_SM_PS_DYNAMIC:
 -              idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
 -                                      IWL_NUM_IDLE_CHAINS_SINGLE;
 -              break;
 -      case WLAN_HT_CAP_SM_PS_DISABLED:
 -              idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE;
 -              break;
 -      case WLAN_HT_CAP_SM_PS_INVALID:
 -      default:
 -              IWL_ERR(priv, "invalid mimo ps mode %d\n",
 -                         priv->current_ht_config.sm_ps);
 -              WARN_ON(1);
 -              idle_cnt = -1;
 -              break;
 +
 +      if (priv->cfg->support_sm_ps) {
 +              /* # Rx chains when idling and maybe trying to save power */
 +              switch (priv->current_ht_config.sm_ps) {
 +              case WLAN_HT_CAP_SM_PS_STATIC:
 +              case WLAN_HT_CAP_SM_PS_DYNAMIC:
 +                      idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
 +                              IWL_NUM_IDLE_CHAINS_SINGLE;
 +                      break;
 +              case WLAN_HT_CAP_SM_PS_DISABLED:
 +                      idle_cnt = (is_cam) ? active_cnt :
 +                              IWL_NUM_IDLE_CHAINS_SINGLE;
 +                      break;
 +              case WLAN_HT_CAP_SM_PS_INVALID:
 +              default:
 +                      IWL_ERR(priv, "invalid sm_ps mode %d\n",
 +                              priv->current_ht_config.sm_ps);
 +                      WARN_ON(1);
 +                      break;
 +              }
        }
        return idle_cnt;
  }
@@@ -1036,7 -1005,7 +1037,7 @@@ static u8 iwl_count_chain_bitmap(u32 ch
        res = (chain_bitmap & BIT(0)) >> 0;
        res += (chain_bitmap & BIT(1)) >> 1;
        res += (chain_bitmap & BIT(2)) >> 2;
 -      res += (chain_bitmap & BIT(4)) >> 4;
 +      res += (chain_bitmap & BIT(3)) >> 3;
        return res;
  }
  
@@@ -1312,28 -1281,18 +1313,28 @@@ static void iwl_set_rate(struct iwl_pri
  
  void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
        struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
 -      IWL_DEBUG_11H(priv, "CSA notif: channel %d, status %d\n",
 -                    le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
 -      rxon->channel = csa->channel;
 -      priv->staging_rxon.channel = csa->channel;
 +
 +      if (priv->switch_rxon.switch_in_progress) {
 +              if (!le32_to_cpu(csa->status) &&
 +                  (csa->channel == priv->switch_rxon.channel)) {
 +                      rxon->channel = csa->channel;
 +                      priv->staging_rxon.channel = csa->channel;
 +                      IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
 +                            le16_to_cpu(csa->channel));
 +              } else
 +                      IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
 +                            le16_to_cpu(csa->channel));
 +
 +              priv->switch_rxon.switch_in_progress = false;
 +      }
  }
  EXPORT_SYMBOL(iwl_rx_csa);
  
  #ifdef CONFIG_IWLWIFI_DEBUG
 -static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
 +void iwl_print_rx_config_cmd(struct iwl_priv *priv)
  {
        struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
  
        IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
        IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
  }
 +EXPORT_SYMBOL(iwl_print_rx_config_cmd);
  #endif
  /**
   * iwl_irq_handle_error - called for HW or SW error interrupt from card
@@@ -1388,160 -1346,6 +1389,160 @@@ void iwl_irq_handle_error(struct iwl_pr
  }
  EXPORT_SYMBOL(iwl_irq_handle_error);
  
 +int iwl_apm_stop_master(struct iwl_priv *priv)
 +{
 +      int ret = 0;
 +
 +      /* stop device's busmaster DMA activity */
 +      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 +
 +      ret = iwl_poll_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
 +                      CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
 +      if (ret)
 +              IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n");
 +
 +      IWL_DEBUG_INFO(priv, "stop master\n");
 +
 +      return ret;
 +}
 +EXPORT_SYMBOL(iwl_apm_stop_master);
 +
 +void iwl_apm_stop(struct iwl_priv *priv)
 +{
 +      IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
 +
 +      /* Stop device's DMA activity */
 +      iwl_apm_stop_master(priv);
 +
 +      /* Reset the entire device */
 +      iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 +
 +      udelay(10);
 +
 +      /*
 +       * Clear "initialization complete" bit to move adapter from
 +       * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
 +       */
 +      iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 +}
 +EXPORT_SYMBOL(iwl_apm_stop);
 +
 +
 +/*
 + * Start up NIC's basic functionality after it has been reset
 + * (e.g. after platform boot, or shutdown via iwl_apm_stop())
 + * NOTE:  This does not load uCode nor start the embedded processor
 + */
 +int iwl_apm_init(struct iwl_priv *priv)
 +{
 +      int ret = 0;
 +      u16 lctl;
 +
 +      IWL_DEBUG_INFO(priv, "Init card's basic functions\n");
 +
 +      /*
 +       * Use "set_bit" below rather than "write", to preserve any hardware
 +       * bits already set by default after reset.
 +       */
 +
 +      /* Disable L0S exit timer (platform NMI Work/Around) */
 +      iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
 +                        CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
 +
 +      /*
 +       * Disable L0s without affecting L1;
 +       *  don't wait for ICH L0s (ICH bug W/A)
 +       */
 +      iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
 +                        CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
 +
 +      /* Set FH wait threshold to maximum (HW error during stress W/A) */
 +      iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
 +
 +      /*
 +       * Enable HAP INTA (interrupt from management bus) to
 +       * wake device's PCI Express link L1a -> L0s
 +       * NOTE:  This is no-op for 3945 (non-existant bit)
 +       */
 +      iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 +                                  CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
 +
 +      /*
 +       * HW bug W/A for instability in PCIe bus L0->L0S->L1 transition.
 +       * Check if BIOS (or OS) enabled L1-ASPM on this device.
 +       * If so (likely), disable L0S, so device moves directly L0->L1;
 +       *    costs negligible amount of power savings.
 +       * If not (unlikely), enable L0S, so there is at least some
 +       *    power savings, even without L1.
 +       */
 +      if (priv->cfg->set_l0s) {
 +              lctl = iwl_pcie_link_ctl(priv);
 +              if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
 +                                      PCI_CFG_LINK_CTRL_VAL_L1_EN) {
 +                      /* L1-ASPM enabled; disable(!) L0S  */
 +                      iwl_set_bit(priv, CSR_GIO_REG,
 +                                      CSR_GIO_REG_VAL_L0S_ENABLED);
 +                      IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
 +              } else {
 +                      /* L1-ASPM disabled; enable(!) L0S */
 +                      iwl_clear_bit(priv, CSR_GIO_REG,
 +                                      CSR_GIO_REG_VAL_L0S_ENABLED);
 +                      IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
 +              }
 +      }
 +
 +      /* Configure analog phase-lock-loop before activating to D0A */
 +      if (priv->cfg->pll_cfg_val)
 +              iwl_set_bit(priv, CSR_ANA_PLL_CFG, priv->cfg->pll_cfg_val);
 +
 +      /*
 +       * Set "initialization complete" bit to move adapter from
 +       * D0U* --> D0A* (powered-up active) state.
 +       */
 +      iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 +
 +      /*
 +       * Wait for clock stabilization; once stabilized, access to
 +       * device-internal resources is supported, e.g. iwl_write_prph()
 +       * and accesses to uCode SRAM.
 +       */
 +      ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
 +                      CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
 +                      CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 +      if (ret < 0) {
 +              IWL_DEBUG_INFO(priv, "Failed to init the card\n");
 +              goto out;
 +      }
 +
 +      /*
 +       * Enable DMA and BSM (if used) clocks, wait for them to stabilize.
 +       * BSM (Boostrap State Machine) is only in 3945 and 4965;
 +       * later devices (i.e. 5000 and later) have non-volatile SRAM,
 +       * and don't need BSM to restore data after power-saving sleep.
 +       *
 +       * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
 +       * do not disable clocks.  This preserves any hardware bits already
 +       * set by default in "CLK_CTRL_REG" after reset.
 +       */
 +      if (priv->cfg->use_bsm)
 +              iwl_write_prph(priv, APMG_CLK_EN_REG,
 +                      APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
 +      else
 +              iwl_write_prph(priv, APMG_CLK_EN_REG,
 +                      APMG_CLK_VAL_DMA_CLK_RQT);
 +      udelay(20);
 +
 +      /* Disable L1-Active */
 +      iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
 +                        APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 +
 +out:
 +      return ret;
 +}
 +EXPORT_SYMBOL(iwl_apm_init);
 +
 +
 +
  void iwl_configure_filter(struct ieee80211_hw *hw,
                          unsigned int changed_flags,
                          unsigned int *total_flags,
  }
  EXPORT_SYMBOL(iwl_configure_filter);
  
 -int iwl_setup_mac(struct iwl_priv *priv)
 -{
 -      int ret;
 -      struct ieee80211_hw *hw = priv->hw;
 -      hw->rate_control_algorithm = "iwl-agn-rs";
 -
 -      /* Tell mac80211 our characteristics */
 -      hw->flags = IEEE80211_HW_SIGNAL_DBM |
 -                  IEEE80211_HW_NOISE_DBM |
 -                  IEEE80211_HW_AMPDU_AGGREGATION |
 -                  IEEE80211_HW_SPECTRUM_MGMT;
 -
 -      if (!priv->cfg->broken_powersave)
 -              hw->flags |= IEEE80211_HW_SUPPORTS_PS |
 -                           IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
 -
 -      hw->wiphy->interface_modes =
 -              BIT(NL80211_IFTYPE_STATION) |
 -              BIT(NL80211_IFTYPE_ADHOC);
 -
 -      hw->wiphy->custom_regulatory = true;
 -
 -      /* Firmware does not support this */
 -      hw->wiphy->disable_beacon_hints = true;
 -
 -      /*
 -       * For now, disable PS by default because it affects
 -       * RX performance significantly.
 -       */
 -      hw->wiphy->ps_default = false;
 -
 -      hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
 -      /* we create the 802.11 header and a zero-length SSID element */
 -      hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
 -
 -      /* Default value; 4 EDCA QOS priorities */
 -      hw->queues = 4;
 -
 -      hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
 -
 -      if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
 -              priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
 -                      &priv->bands[IEEE80211_BAND_2GHZ];
 -      if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
 -              priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 -                      &priv->bands[IEEE80211_BAND_5GHZ];
 -
 -      ret = ieee80211_register_hw(priv->hw);
 -      if (ret) {
 -              IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
 -              return ret;
 -      }
 -      priv->mac80211_registered = 1;
 -
 -      return 0;
 -}
 -EXPORT_SYMBOL(iwl_setup_mac);
 -
  int iwl_set_hw_params(struct iwl_priv *priv)
  {
        priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
        priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
        if (priv->cfg->mod_params->amsdu_size_8K)
 -              priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K;
 +              priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K);
        else
 -              priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K;
 -      priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256;
 +              priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K);
  
        priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
  
  }
  EXPORT_SYMBOL(iwl_set_hw_params);
  
 -int iwl_init_drv(struct iwl_priv *priv)
 -{
 -      int ret;
 -
 -      priv->ibss_beacon = NULL;
 -
 -      spin_lock_init(&priv->lock);
 -      spin_lock_init(&priv->sta_lock);
 -      spin_lock_init(&priv->hcmd_lock);
 -
 -      INIT_LIST_HEAD(&priv->free_frames);
 -
 -      mutex_init(&priv->mutex);
 -
 -      /* Clear the driver's (not device's) station table */
 -      iwl_clear_stations_table(priv);
 -
 -      priv->data_retry_limit = -1;
 -      priv->ieee_channels = NULL;
 -      priv->ieee_rates = NULL;
 -      priv->band = IEEE80211_BAND_2GHZ;
 -
 -      priv->iw_mode = NL80211_IFTYPE_STATION;
 -
 -      priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
 -
 -      /* Choose which receivers/antennas to use */
 -      if (priv->cfg->ops->hcmd->set_rxon_chain)
 -              priv->cfg->ops->hcmd->set_rxon_chain(priv);
 -
 -      iwl_init_scan_params(priv);
 -
 -      iwl_reset_qos(priv);
 -
 -      priv->qos_data.qos_active = 0;
 -      priv->qos_data.qos_cap.val = 0;
 -
 -      priv->rates_mask = IWL_RATES_MASK;
 -      /* Set the tx_power_user_lmt to the lowest power level
 -       * this value will get overwritten by channel max power avg
 -       * from eeprom */
 -      priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MIN;
 -
 -      ret = iwl_init_channel_map(priv);
 -      if (ret) {
 -              IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
 -              goto err;
 -      }
 -
 -      ret = iwlcore_init_geos(priv);
 -      if (ret) {
 -              IWL_ERR(priv, "initializing geos failed: %d\n", ret);
 -              goto err_free_channel_map;
 -      }
 -      iwlcore_init_hw_rates(priv, priv->ieee_rates);
 -
 -      return 0;
 -
 -err_free_channel_map:
 -      iwl_free_channel_map(priv);
 -err:
 -      return ret;
 -}
 -EXPORT_SYMBOL(iwl_init_drv);
 -
  int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
  {
        int ret = 0;
  }
  EXPORT_SYMBOL(iwl_set_tx_power);
  
 -void iwl_uninit_drv(struct iwl_priv *priv)
 -{
 -      iwl_calib_free_results(priv);
 -      iwlcore_free_geos(priv);
 -      iwl_free_channel_map(priv);
 -      kfree(priv->scan);
 -}
 -EXPORT_SYMBOL(iwl_uninit_drv);
 -
  #define ICT_COUNT (PAGE_SIZE/sizeof(u32))
  
  /* Free dram table */
@@@ -1978,9 -1915,9 +1979,9 @@@ EXPORT_SYMBOL(iwl_isr_legacy)
  int iwl_send_bt_config(struct iwl_priv *priv)
  {
        struct iwl_bt_cmd bt_cmd = {
 -              .flags = 3,
 -              .lead_time = 0xAA,
 -              .max_kill = 1,
 +              .flags = BT_COEX_MODE_4W,
 +              .lead_time = BT_LEAD_TIME_DEF,
 +              .max_kill = BT_MAX_KILL_DEF,
                .kill_ack_mask = 0,
                .kill_cts_mask = 0,
        };
@@@ -2140,7 -2077,10 +2141,7 @@@ void iwl_rf_kill_ct_config(struct iwl_p
        spin_unlock_irqrestore(&priv->lock, flags);
        priv->thermal_throttle.ct_kill_toggle = false;
  
 -      switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
 -      case CSR_HW_REV_TYPE_1000:
 -      case CSR_HW_REV_TYPE_6x00:
 -      case CSR_HW_REV_TYPE_6x50:
 +      if (priv->cfg->support_ct_kill_exit) {
                adv_cmd.critical_temperature_enter =
                        cpu_to_le32(priv->hw_params.ct_kill_threshold);
                adv_cmd.critical_temperature_exit =
                                        "exit is %d\n",
                                       priv->hw_params.ct_kill_threshold,
                                       priv->hw_params.ct_kill_exit_threshold);
 -              break;
 -      default:
 +      } else {
                cmd.critical_temperature_R =
                        cpu_to_le32(priv->hw_params.ct_kill_threshold);
  
                                        "succeeded, "
                                        "critical temperature is %d\n",
                                        priv->hw_params.ct_kill_threshold);
 -              break;
        }
  }
  EXPORT_SYMBOL(iwl_rf_kill_ct_config);
@@@ -2201,7 -2143,7 +2202,7 @@@ void iwl_rx_pm_sleep_notif(struct iwl_p
                           struct iwl_rx_mem_buffer *rxb)
  {
  #ifdef CONFIG_IWLWIFI_DEBUG
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
        IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
                     sleep->pm_sleep_mode, sleep->pm_wakeup_src);
@@@ -2212,7 -2154,7 +2213,7 @@@ EXPORT_SYMBOL(iwl_rx_pm_sleep_notif)
  void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
                                      struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
        IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
                        "notification for %s:\n", len,
@@@ -2224,7 -2166,7 +2225,7 @@@ EXPORT_SYMBOL(iwl_rx_pm_debug_statistic
  void iwl_rx_reply_error(struct iwl_priv *priv,
                        struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
  
        IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
                "seq 0x%04X ser 0x%08X\n",
@@@ -2286,58 -2228,42 +2287,58 @@@ int iwl_mac_conf_tx(struct ieee80211_h
  EXPORT_SYMBOL(iwl_mac_conf_tx);
  
  static void iwl_ht_conf(struct iwl_priv *priv,
 -                          struct ieee80211_bss_conf *bss_conf)
 +                      struct ieee80211_bss_conf *bss_conf)
  {
 -      struct ieee80211_sta_ht_cap *ht_conf;
 -      struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
 +      struct iwl_ht_config *ht_conf = &priv->current_ht_config;
        struct ieee80211_sta *sta;
  
        IWL_DEBUG_MAC80211(priv, "enter: \n");
  
 -      if (!iwl_conf->is_ht)
 +      if (!ht_conf->is_ht)
                return;
  
 +      ht_conf->ht_protection =
 +              bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
 +      ht_conf->non_GF_STA_present =
 +              !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
  
 -      /*
 -       * It is totally wrong to base global information on something
 -       * that is valid only when associated, alas, this driver works
 -       * that way and I don't know how to fix it.
 -       */
 +      ht_conf->single_chain_sufficient = false;
  
 -      rcu_read_lock();
 -      sta = ieee80211_find_sta(priv->hw, priv->bssid);
 -      if (!sta) {
 +      switch (priv->iw_mode) {
 +      case NL80211_IFTYPE_STATION:
 +              rcu_read_lock();
 +              sta = ieee80211_find_sta(priv->vif, priv->bssid);
 +              if (sta) {
 +                      struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
 +                      int maxstreams;
 +
 +                      maxstreams = (ht_cap->mcs.tx_params &
 +                                    IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
 +                                      >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
 +                      maxstreams += 1;
 +
 +                      if ((ht_cap->mcs.rx_mask[1] == 0) &&
 +                          (ht_cap->mcs.rx_mask[2] == 0))
 +                              ht_conf->single_chain_sufficient = true;
 +                      if (maxstreams <= 1)
 +                              ht_conf->single_chain_sufficient = true;
 +              } else {
 +                      /*
 +                       * If at all, this can only happen through a race
 +                       * when the AP disconnects us while we're still
 +                       * setting up the connection, in that case mac80211
 +                       * will soon tell us about that.
 +                       */
 +                      ht_conf->single_chain_sufficient = true;
 +              }
                rcu_read_unlock();
 -              return;
 +              break;
 +      case NL80211_IFTYPE_ADHOC:
 +              ht_conf->single_chain_sufficient = true;
 +              break;
 +      default:
 +              break;
        }
 -      ht_conf = &sta->ht_cap;
 -
 -      iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
 -
 -      memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
 -
 -      iwl_conf->ht_protection =
 -              bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
 -      iwl_conf->non_GF_STA_present =
 -              !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
 -
 -      rcu_read_unlock();
  
        IWL_DEBUG_MAC80211(priv, "leave\n");
  }
@@@ -2461,8 -2387,6 +2462,8 @@@ void iwl_bss_info_changed(struct ieee80
                        priv->timestamp = bss_conf->timestamp;
                        priv->assoc_capability = bss_conf->assoc_capability;
  
 +                      iwl_led_associate(priv);
 +
                        /*
                         * We have just associated, don't start scan too early
                         * leave time for EAPOL exchange to complete.
                                        IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
                        if (!iwl_is_rfkill(priv))
                                priv->cfg->ops->lib->post_associate(priv);
 -              } else
 +              } else {
                        priv->assoc_id = 0;
 -
 +                      iwl_led_disassociate(priv);
 +              }
        }
  
        if (changes && iwl_is_associated(priv) && priv->assoc_id) {
@@@ -2647,7 -2570,7 +2648,7 @@@ int iwl_mac_config(struct ieee80211_hw 
        struct iwl_priv *priv = hw->priv;
        const struct iwl_channel_info *ch_info;
        struct ieee80211_conf *conf = &hw->conf;
 -      struct iwl_ht_info *ht_conf = &priv->current_ht_config;
 +      struct iwl_ht_config *ht_conf = &priv->current_ht_config;
        unsigned long flags = 0;
        int ret = 0;
        u16 ch;
                        if (conf_is_ht40_minus(conf)) {
                                ht_conf->extension_chan_offset =
                                        IEEE80211_HT_PARAM_CHA_SEC_BELOW;
 -                              ht_conf->supported_chan_width =
 -                                      IWL_CHANNEL_WIDTH_40MHZ;
 +                              ht_conf->is_40mhz = true;
                        } else if (conf_is_ht40_plus(conf)) {
                                ht_conf->extension_chan_offset =
                                        IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
 -                              ht_conf->supported_chan_width =
 -                                      IWL_CHANNEL_WIDTH_40MHZ;
 +                              ht_conf->is_40mhz = true;
                        } else {
                                ht_conf->extension_chan_offset =
                                        IEEE80211_HT_PARAM_CHA_SEC_NONE;
 -                              ht_conf->supported_chan_width =
 -                                      IWL_CHANNEL_WIDTH_20MHZ;
 +                              ht_conf->is_40mhz = false;
                        }
                } else
 -                      ht_conf->supported_chan_width = IWL_CHANNEL_WIDTH_20MHZ;
 +                      ht_conf->is_40mhz = false;
                /* Default to no protection. Protection mode will later be set
                 * from BSS config in iwl_ht_conf */
                ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
  
                iwl_set_flags_for_band(priv, conf->channel->band);
                spin_unlock_irqrestore(&priv->lock, flags);
 +              if (iwl_is_associated(priv) &&
 +                  (le16_to_cpu(priv->active_rxon.channel) != ch) &&
 +                  priv->cfg->ops->lib->set_channel_switch) {
 +                      iwl_set_rate(priv);
 +                      /*
 +                       * at this point, staging_rxon has the
 +                       * configuration for channel switch
 +                       */
 +                      ret = priv->cfg->ops->lib->set_channel_switch(priv,
 +                              ch);
 +                      if (!ret) {
 +                              iwl_print_rx_config_cmd(priv);
 +                              goto out;
 +                      }
 +                      priv->switch_rxon.switch_in_progress = false;
 +              }
   set_ch_out:
                /* The list of supported rates and rate mask can be different
                 * for each band; since the band may have changed, reset
                iwl_set_rate(priv);
        }
  
 -      if (changed & IEEE80211_CONF_CHANGE_PS) {
 +      if (changed & (IEEE80211_CONF_CHANGE_PS |
 +                      IEEE80211_CONF_CHANGE_IDLE)) {
                ret = iwl_power_update_mode(priv, false);
                if (ret)
                        IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
@@@ -2831,7 -2740,7 +2832,7 @@@ void iwl_mac_reset_tsf(struct ieee80211
        IWL_DEBUG_MAC80211(priv, "enter\n");
  
        spin_lock_irqsave(&priv->lock, flags);
 -      memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
 +      memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
        spin_unlock_irqrestore(&priv->lock, flags);
  
        iwl_reset_qos(priv);
  }
  EXPORT_SYMBOL(iwl_mac_reset_tsf);
  
 +int iwl_alloc_txq_mem(struct iwl_priv *priv)
 +{
 +      if (!priv->txq)
 +              priv->txq = kzalloc(
 +                      sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues,
 +                      GFP_KERNEL);
 +      if (!priv->txq) {
 +              IWL_ERR(priv, "Not enough memory for txq \n");
 +              return -ENOMEM;
 +      }
 +      return 0;
 +}
 +EXPORT_SYMBOL(iwl_alloc_txq_mem);
 +
 +void iwl_free_txq_mem(struct iwl_priv *priv)
 +{
 +      kfree(priv->txq);
 +      priv->txq = NULL;
 +}
 +EXPORT_SYMBOL(iwl_free_txq_mem);
 +
 +int iwl_send_wimax_coex(struct iwl_priv *priv)
 +{
 +      struct iwl_wimax_coex_cmd uninitialized_var(coex_cmd);
 +
 +      if (priv->cfg->support_wimax_coexist) {
 +              /* UnMask wake up src at associated sleep */
 +              coex_cmd.flags |= COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
 +
 +              /* UnMask wake up src at unassociated sleep */
 +              coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
 +              memcpy(coex_cmd.sta_prio, cu_priorities,
 +                      sizeof(struct iwl_wimax_coex_event_entry) *
 +                       COEX_NUM_OF_EVENTS);
 +
 +              /* enabling the coexistence feature */
 +              coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
 +
 +              /* enabling the priorities tables */
 +              coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
 +      } else {
 +              /* coexistence is disabled */
 +              memset(&coex_cmd, 0, sizeof(coex_cmd));
 +      }
 +      return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
 +                              sizeof(coex_cmd), &coex_cmd);
 +}
 +EXPORT_SYMBOL(iwl_send_wimax_coex);
 +
  #ifdef CONFIG_IWLWIFI_DEBUGFS
  
  #define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
index e8002c1d3eba792934c8b0985221939332701673,a6856daf14cb68072795517a20760ab0ae8bf9f3..a23165948202054c4ec59a78f42a6ddb580efb10
@@@ -28,6 -28,7 +28,7 @@@
  
  #include <linux/kernel.h>
  #include <linux/module.h>
+ #include <linux/sched.h>
  #include <net/mac80211.h>
  
  #include "iwl-dev.h" /* FIXME: remove */
@@@ -55,8 -56,6 +56,8 @@@ const char *get_cmd_string(u8 cmd
                IWL_CMD(REPLY_LEDS_CMD);
                IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
                IWL_CMD(COEX_PRIORITY_TABLE_CMD);
 +              IWL_CMD(COEX_MEDIUM_NOTIFICATION);
 +              IWL_CMD(COEX_EVENT_CMD);
                IWL_CMD(RADAR_NOTIFICATION);
                IWL_CMD(REPLY_QUIET_CMD);
                IWL_CMD(REPLY_CHANNEL_SWITCH);
@@@ -94,8 -93,6 +95,8 @@@
                IWL_CMD(CALIBRATION_RES_NOTIFICATION);
                IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION);
                IWL_CMD(REPLY_TX_POWER_DBM_CMD);
 +              IWL_CMD(TEMPERATURE_NOTIFICATION);
 +              IWL_CMD(TX_ANT_CONFIGURATION_CMD);
        default:
                return "UNKNOWN";
  
@@@ -107,8 -104,17 +108,8 @@@ EXPORT_SYMBOL(get_cmd_string)
  
  static void iwl_generic_cmd_callback(struct iwl_priv *priv,
                                     struct iwl_device_cmd *cmd,
 -                                   struct sk_buff *skb)
 +                                   struct iwl_rx_packet *pkt)
  {
 -      struct iwl_rx_packet *pkt = NULL;
 -
 -      if (!skb) {
 -              IWL_ERR(priv, "Error: Response NULL in %s.\n",
 -                              get_cmd_string(cmd->hdr.cmd));
 -              return;
 -      }
 -
 -      pkt = (struct iwl_rx_packet *)skb->data;
        if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
                        get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
@@@ -199,18 -205,18 +200,18 @@@ int iwl_send_cmd_sync(struct iwl_priv *
        }
  
        if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
 -              IWL_DEBUG_INFO(priv, "Command %s aborted: RF KILL Switch\n",
 +              IWL_ERR(priv, "Command %s aborted: RF KILL Switch\n",
                               get_cmd_string(cmd->id));
                ret = -ECANCELED;
                goto fail;
        }
        if (test_bit(STATUS_FW_ERROR, &priv->status)) {
 -              IWL_DEBUG_INFO(priv, "Command %s failed: FW Error\n",
 +              IWL_ERR(priv, "Command %s failed: FW Error\n",
                               get_cmd_string(cmd->id));
                ret = -EIO;
                goto fail;
        }
 -      if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_skb) {
 +      if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) {
                IWL_ERR(priv, "Error: Response NULL in '%s'\n",
                          get_cmd_string(cmd->id));
                ret = -EIO;
@@@ -232,9 -238,9 +233,9 @@@ cancel
                                                        ~CMD_WANT_SKB;
        }
  fail:
 -      if (cmd->reply_skb) {
 -              dev_kfree_skb_any(cmd->reply_skb);
 -              cmd->reply_skb = NULL;
 +      if (cmd->reply_page) {
 +              free_pages(cmd->reply_page, priv->hw_params.rx_page_order);
 +              cmd->reply_page = 0;
        }
  out:
        clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
@@@ -267,7 -273,7 +268,7 @@@ int iwl_send_cmd_pdu_async(struct iwl_p
                           u8 id, u16 len, const void *data,
                           void (*callback)(struct iwl_priv *priv,
                                            struct iwl_device_cmd *cmd,
 -                                          struct sk_buff *skb))
 +                                          struct iwl_rx_packet *pkt))
  {
        struct iwl_host_cmd cmd = {
                .id = id,
index 9370e062000d2118dafddf5fe3abb1d173d1eb3a,fb9bcfa6d9471e057bac4a2d7e98237c451c03e0..6199bf60d3132e13ba6a9864c1be4ec6a2acce79
@@@ -28,6 -28,7 +28,7 @@@
   *****************************************************************************/
  
  #include <linux/etherdevice.h>
+ #include <linux/sched.h>
  #include <net/mac80211.h>
  #include "iwl-eeprom.h"
  #include "iwl-dev.h"
@@@ -96,8 -97,7 +97,8 @@@ int iwl_txq_update_write_ptr(struct iwl
                reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
  
                if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
 -                      IWL_DEBUG_INFO(priv, "Requesting wakeup, GP1 = 0x%x\n", reg);
 +                      IWL_DEBUG_INFO(priv, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
 +                                    txq_id, reg);
                        iwl_set_bit(priv, CSR_GP_CNTRL,
                                    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
                        return ret;
@@@ -132,7 -132,7 +133,7 @@@ void iwl_tx_queue_free(struct iwl_priv 
        struct iwl_tx_queue *txq = &priv->txq[txq_id];
        struct iwl_queue *q = &txq->q;
        struct pci_dev *dev = priv->pci_dev;
 -      int i, len;
 +      int i;
  
        if (q->n_bd == 0)
                return;
             q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
                priv->cfg->ops->lib->txq_free_tfd(priv, txq);
  
 -      len = sizeof(struct iwl_device_cmd) * q->n_window;
 -
        /* De-alloc array of command/tx buffers */
        for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
                kfree(txq->cmd[i]);
@@@ -179,11 -181,14 +180,11 @@@ void iwl_cmd_queue_free(struct iwl_pri
        struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
        struct iwl_queue *q = &txq->q;
        struct pci_dev *dev = priv->pci_dev;
 -      int i, len;
 +      int i;
  
        if (q->n_bd == 0)
                return;
  
 -      len = sizeof(struct iwl_device_cmd) * q->n_window;
 -      len += IWL_MAX_SCAN_SIZE;
 -
        /* De-alloc array of command/tx buffers */
        for (i = 0; i <= TFD_CMD_SLOTS; i++)
                kfree(txq->cmd[i]);
@@@ -365,13 -370,8 +366,13 @@@ int iwl_tx_queue_init(struct iwl_priv *
  
        txq->need_update = 0;
  
 -      /* aggregation TX queues will get their ID when aggregation begins */
 -      if (txq_id <= IWL_TX_FIFO_AC3)
 +      /*
 +       * Aggregation TX queues will get their ID when aggregation begins;
 +       * they overwrite the setting done here. The command FIFO doesn't
 +       * need an swq_id so don't set one to catch errors, all others can
 +       * be set up to the identity mapping.
 +       */
 +      if (txq_id != IWL_CMD_QUEUE_NUM)
                txq->swq_id = txq_id;
  
        /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
@@@ -406,19 -406,15 +407,19 @@@ void iwl_hw_txq_ctx_free(struct iwl_pri
        int txq_id;
  
        /* Tx queues */
 -      for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
 -              if (txq_id == IWL_CMD_QUEUE_NUM)
 -                      iwl_cmd_queue_free(priv);
 -              else
 -                      iwl_tx_queue_free(priv, txq_id);
 -
 +      if (priv->txq)
 +              for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
 +                   txq_id++)
 +                      if (txq_id == IWL_CMD_QUEUE_NUM)
 +                              iwl_cmd_queue_free(priv);
 +                      else
 +                              iwl_tx_queue_free(priv, txq_id);
        iwl_free_dma_ptr(priv, &priv->kw);
  
        iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
 +
 +      /* free tx queue structure */
 +      iwl_free_txq_mem(priv);
  }
  EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
  
@@@ -450,12 -446,6 +451,12 @@@ int iwl_txq_ctx_reset(struct iwl_priv *
                IWL_ERR(priv, "Keep Warm allocation failed\n");
                goto error_kw;
        }
 +
 +      /* allocate tx queue structure */
 +      ret = iwl_alloc_txq_mem(priv);
 +      if (ret)
 +              goto error;
 +
        spin_lock_irqsave(&priv->lock, flags);
  
        /* Turn off all Tx DMA fifos */
@@@ -592,7 -582,9 +593,7 @@@ static void iwl_tx_cmd_build_rate(struc
        u8 rate_plcp;
  
        /* Set retry limit on DATA packets and Probe Responses*/
 -      if (priv->data_retry_limit != -1)
 -              data_retry_limit = priv->data_retry_limit;
 -      else if (ieee80211_is_probe_resp(fc))
 +      if (ieee80211_is_probe_resp(fc))
                data_retry_limit = 3;
        else
                data_retry_limit = IWL_DEFAULT_TX_RETRY;
@@@ -718,7 -710,7 +719,7 @@@ int iwl_tx_skb(struct iwl_priv *priv, s
        dma_addr_t phys_addr;
        dma_addr_t txcmd_phys;
        dma_addr_t scratch_phys;
 -      u16 len, len_org;
 +      u16 len, len_org, firstlen, secondlen;
        u16 seq_number = 0;
        __le16 fc;
        u8 hdr_len;
                sizeof(struct iwl_cmd_header) + hdr_len;
  
        len_org = len;
 -      len = (len + 3) & ~3;
 +      firstlen = len = (len + 3) & ~3;
  
        if (len_org != len)
                len_org = 1;
  
        /* Set up TFD's 2nd entry to point directly to remainder of skb,
         * if any (802.11 null frames have no payload). */
 -      len = skb->len - hdr_len;
 +      secondlen = len = skb->len - hdr_len;
        if (len) {
                phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
                                           len, PCI_DMA_TODEVICE);
        pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
                                       len, PCI_DMA_BIDIRECTIONAL);
  
 +      trace_iwlwifi_dev_tx(priv,
 +                           &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
 +                           sizeof(struct iwl_tfd),
 +                           &out_cmd->hdr, firstlen,
 +                           skb->data + hdr_len, secondlen);
 +
        /* Tell device the write index *just past* this latest filled TFD */
        q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
        ret = iwl_txq_update_write_ptr(priv, txq);
@@@ -984,20 -970,13 +985,20 @@@ int iwl_enqueue_hcmd(struct iwl_priv *p
        BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
               !(cmd->flags & CMD_SIZE_HUGE));
  
 -      if (iwl_is_rfkill(priv)) {
 -              IWL_DEBUG_INFO(priv, "Not sending command - RF KILL\n");
 +      if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
 +              IWL_WARN(priv, "Not sending command - %s KILL\n",
 +                       iwl_is_rfkill(priv) ? "RF" : "CT");
                return -EIO;
        }
  
        if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
                IWL_ERR(priv, "No space for Tx\n");
 +              if (iwl_within_ct_kill_margin(priv))
 +                      iwl_tt_enter_ct_kill(priv);
 +              else {
 +                      IWL_ERR(priv, "Restarting adapter due to queue full\n");
 +                      queue_work(priv->workqueue, &priv->restart);
 +              }
                return -ENOSPC;
        }
  
        pci_unmap_addr_set(out_meta, mapping, phys_addr);
        pci_unmap_len_set(out_meta, len, fix_size);
  
 +      trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags);
 +
        priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
                                                   phys_addr, fix_size, 1,
                                                   U32_PAD(cmd->len));
@@@ -1128,6 -1105,11 +1129,6 @@@ static void iwl_hcmd_queue_reclaim(stru
                return;
        }
  
 -      pci_unmap_single(priv->pci_dev,
 -              pci_unmap_addr(&txq->meta[cmd_idx], mapping),
 -              pci_unmap_len(&txq->meta[cmd_idx], len),
 -              PCI_DMA_BIDIRECTIONAL);
 -
        for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
             q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
  
   */
  void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
        cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
        meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
  
 +      pci_unmap_single(priv->pci_dev,
 +                       pci_unmap_addr(meta, mapping),
 +                       pci_unmap_len(meta, len),
 +                       PCI_DMA_BIDIRECTIONAL);
 +
        /* Input error checking is done when commands are added to queue. */
        if (meta->flags & CMD_WANT_SKB) {
 -              meta->source->reply_skb = rxb->skb;
 -              rxb->skb = NULL;
 +              meta->source->reply_page = (unsigned long)rxb_addr(rxb);
 +              rxb->page = NULL;
        } else if (meta->callback)
 -              meta->callback(priv, cmd, rxb->skb);
 +              meta->callback(priv, cmd, pkt);
  
        iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
  
@@@ -1424,7 -1401,7 +1425,7 @@@ static int iwl_tx_status_reply_compress
  
        info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]);
        memset(&info->status, 0, sizeof(info->status));
 -      info->flags = IEEE80211_TX_STAT_ACK;
 +      info->flags |= IEEE80211_TX_STAT_ACK;
        info->flags |= IEEE80211_TX_STAT_AMPDU;
        info->status.ampdu_ack_map = successes;
        info->status.ampdu_ack_len = agg->frame_count;
  void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
                                           struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
        struct iwl_tx_queue *txq = NULL;
        struct iwl_ht_agg *agg;
index 05f118529feaf88c2f8d26d149ccfc0ecf9ac720,d00a80334095beb2a5fd372697b01f1c7a4c3410..5d26330b43e8f1208ff83207812ba14dd018ce0b
@@@ -33,6 -33,7 +33,7 @@@
  #include <linux/pci.h>
  #include <linux/dma-mapping.h>
  #include <linux/delay.h>
+ #include <linux/sched.h>
  #include <linux/skbuff.h>
  #include <linux/netdevice.h>
  #include <linux/wireless.h>
@@@ -41,6 -42,7 +42,6 @@@
  #include <linux/if_arp.h>
  
  #include <net/ieee80211_radiotap.h>
 -#include <net/lib80211.h>
  #include <net/mac80211.h>
  
  #include <asm/div64.h>
@@@ -88,6 -90,7 +89,6 @@@ MODULE_LICENSE("GPL")
  
   /* module parameters */
  struct iwl_mod_params iwl3945_mod_params = {
 -      .num_of_queues = IWL39_NUM_QUEUES, /* Not used */
        .sw_crypto = 1,
        .restart_fw = 1,
        /* the rest are 0 by default */
@@@ -365,13 -368,13 +366,13 @@@ static void iwl3945_build_tx_cmd_hwcryp
                                      struct sk_buff *skb_frag,
                                      int sta_id)
  {
 -      struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
 +      struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
        struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
  
        switch (keyinfo->alg) {
        case ALG_CCMP:
 -              tx->sec_ctl = TX_CMD_SEC_CCM;
 -              memcpy(tx->key, keyinfo->key, keyinfo->keylen);
 +              tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
 +              memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen);
                IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
                break;
  
                break;
  
        case ALG_WEP:
 -              tx->sec_ctl = TX_CMD_SEC_WEP |
 +              tx_cmd->sec_ctl = TX_CMD_SEC_WEP |
                    (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
  
                if (keyinfo->keylen == 13)
 -                      tx->sec_ctl |= TX_CMD_SEC_KEY128;
 +                      tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
  
 -              memcpy(&tx->key[3], keyinfo->key, keyinfo->keylen);
 +              memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen);
  
                IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
                             "with key %d\n", info->control.hw_key->hw_key_idx);
@@@ -405,11 -408,12 +406,11 @@@ static void iwl3945_build_tx_cmd_basic(
                                  struct ieee80211_tx_info *info,
                                  struct ieee80211_hdr *hdr, u8 std_id)
  {
 -      struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
 -      __le32 tx_flags = tx->tx_flags;
 +      struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
 +      __le32 tx_flags = tx_cmd->tx_flags;
        __le16 fc = hdr->frame_control;
 -      u8 rc_flags = info->control.rates[0].flags;
  
 -      tx->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 +      tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
                tx_flags |= TX_CMD_FLG_ACK_MSK;
                if (ieee80211_is_mgmt(fc))
                tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
        }
  
 -      tx->sta_id = std_id;
 +      tx_cmd->sta_id = std_id;
        if (ieee80211_has_morefrags(fc))
                tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
  
        if (ieee80211_is_data_qos(fc)) {
                u8 *qc = ieee80211_get_qos_ctl(hdr);
 -              tx->tid_tspec = qc[0] & 0xf;
 +              tx_cmd->tid_tspec = qc[0] & 0xf;
                tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
        } else {
                tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
        }
  
 -      if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
 -              tx_flags |= TX_CMD_FLG_RTS_MSK;
 -              tx_flags &= ~TX_CMD_FLG_CTS_MSK;
 -      } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
 -              tx_flags &= ~TX_CMD_FLG_RTS_MSK;
 -              tx_flags |= TX_CMD_FLG_CTS_MSK;
 -      }
 +      priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags);
  
        if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
                tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
        tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
        if (ieee80211_is_mgmt(fc)) {
                if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
 -                      tx->timeout.pm_frame_timeout = cpu_to_le16(3);
 +                      tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
                else
 -                      tx->timeout.pm_frame_timeout = cpu_to_le16(2);
 +                      tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
        } else {
 -              tx->timeout.pm_frame_timeout = 0;
 -#ifdef CONFIG_IWLWIFI_LEDS
 -              priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len);
 -#endif
 +              tx_cmd->timeout.pm_frame_timeout = 0;
        }
  
 -      tx->driver_txop = 0;
 -      tx->tx_flags = tx_flags;
 -      tx->next_frame_len = 0;
 +      tx_cmd->driver_txop = 0;
 +      tx_cmd->tx_flags = tx_flags;
 +      tx_cmd->next_frame_len = 0;
  }
  
  /*
@@@ -461,7 -474,7 +462,7 @@@ static int iwl3945_tx_skb(struct iwl_pr
  {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 -      struct iwl3945_tx_cmd *tx;
 +      struct iwl3945_tx_cmd *tx_cmd;
        struct iwl_tx_queue *txq = NULL;
        struct iwl_queue *q = NULL;
        struct iwl_device_cmd *out_cmd;
        /* Init first empty entry in queue's array of Tx/cmd buffers */
        out_cmd = txq->cmd[idx];
        out_meta = &txq->meta[idx];
 -      tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
 +      tx_cmd = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
        memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
 -      memset(tx, 0, sizeof(*tx));
 +      memset(tx_cmd, 0, sizeof(*tx_cmd));
  
        /*
         * Set up the Tx-command (not MAC!) header.
                                INDEX_TO_SEQ(q->write_ptr)));
  
        /* Copy MAC header from skb into command buffer */
 -      memcpy(tx->hdr, hdr, hdr_len);
 +      memcpy(tx_cmd->hdr, hdr, hdr_len);
  
  
        if (info->control.hw_key)
  
        /* Total # bytes to be transmitted */
        len = (u16)skb->len;
 -      tx->len = cpu_to_le16(len);
 +      tx_cmd->len = cpu_to_le16(len);
  
        iwl_dbg_log_tx_data_frame(priv, len, hdr);
        iwl_update_stats(priv, true, fc, len);
 -      tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
 -      tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
 +      tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
 +      tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
  
        if (!ieee80211_has_morefrags(hdr->frame_control)) {
                txq->need_update = 1;
  
        IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n",
                     le16_to_cpu(out_cmd->hdr.sequence));
 -      IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx->tx_flags));
 -      iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
 -      iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
 +      IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags));
 +      iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd));
 +      iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr,
                           ieee80211_hdrlen(fc));
  
        /*
@@@ -745,7 -758,7 +746,7 @@@ static int iwl3945_get_measurement(stru
                               u8 type)
  {
        struct iwl_spectrum_cmd spectrum;
 -      struct iwl_rx_packet *res;
 +      struct iwl_rx_packet *pkt;
        struct iwl_host_cmd cmd = {
                .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
                .data = (void *)&spectrum,
        if (rc)
                return rc;
  
 -      res = (struct iwl_rx_packet *)cmd.reply_skb->data;
 -      if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
 +      pkt = (struct iwl_rx_packet *)cmd.reply_page;
 +      if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
                rc = -EIO;
        }
  
 -      spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
 +      spectrum_resp_status = le16_to_cpu(pkt->u.spectrum.status);
        switch (spectrum_resp_status) {
        case 0:         /* Command will be handled */
 -              if (res->u.spectrum.id != 0xff) {
 +              if (pkt->u.spectrum.id != 0xff) {
                        IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n",
 -                                              res->u.spectrum.id);
 +                                              pkt->u.spectrum.id);
                        priv->measurement_status &= ~MEASUREMENT_READY;
                }
                priv->measurement_status |= MEASUREMENT_ACTIVE;
                break;
        }
  
 -      dev_kfree_skb_any(cmd.reply_skb);
 +      free_pages(cmd.reply_page, priv->hw_params.rx_page_order);
  
        return rc;
  }
  static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
                               struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_alive_resp *palive;
        struct delayed_work *pwork;
  
@@@ -859,7 -872,7 +860,7 @@@ static void iwl3945_rx_reply_add_sta(st
                                 struct iwl_rx_mem_buffer *rxb)
  {
  #ifdef CONFIG_IWLWIFI_DEBUG
 -      struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
  #endif
  
        IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
@@@ -895,7 -908,7 +896,7 @@@ static void iwl3945_rx_beacon_notif(str
                                struct iwl_rx_mem_buffer *rxb)
  {
  #ifdef CONFIG_IWLWIFI_DEBUG
 -      struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
        u8 rate = beacon->beacon_notify_hdr.rate;
  
  static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
                                    struct iwl_rx_mem_buffer *rxb)
  {
 -      struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 +      struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
        unsigned long status = priv->status;
  
@@@ -1082,7 -1095,7 +1083,7 @@@ static int iwl3945_rx_queue_restock(str
                list_del(element);
  
                /* Point to Rx buffer via next RBD in circular buffer */
 -              rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->real_dma_addr);
 +              rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->page_dma);
                rxq->queue[rxq->write] = rxb;
                rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
                rxq->free_count--;
@@@ -1122,9 -1135,8 +1123,9 @@@ static void iwl3945_rx_allocate(struct 
        struct iwl_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
        struct iwl_rx_mem_buffer *rxb;
 -      struct sk_buff *skb;
 +      struct page *page;
        unsigned long flags;
 +      gfp_t gfp_mask = priority;
  
        while (1) {
                spin_lock_irqsave(&rxq->lock, flags);
                spin_unlock_irqrestore(&rxq->lock, flags);
  
                if (rxq->free_count > RX_LOW_WATERMARK)
 -                      priority |= __GFP_NOWARN;
 +                      gfp_mask |= __GFP_NOWARN;
 +
 +              if (priv->hw_params.rx_page_order > 0)
 +                      gfp_mask |= __GFP_COMP;
 +
                /* Alloc a new receive buffer */
 -              skb = alloc_skb(priv->hw_params.rx_buf_size, priority);
 -              if (!skb) {
 +              page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
 +              if (!page) {
                        if (net_ratelimit())
                                IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n");
                        if ((rxq->free_count <= RX_LOW_WATERMARK) &&
                spin_lock_irqsave(&rxq->lock, flags);
                if (list_empty(&rxq->rx_used)) {
                        spin_unlock_irqrestore(&rxq->lock, flags);
 -                      dev_kfree_skb_any(skb);
 +                      __free_pages(page, priv->hw_params.rx_page_order);
                        return;
                }
                element = rxq->rx_used.next;
                list_del(element);
                spin_unlock_irqrestore(&rxq->lock, flags);
  
 -              rxb->skb = skb;
 -
 -              /* If radiotap head is required, reserve some headroom here.
 -               * The physical head count is a variable rx_stats->phy_count.
 -               * We reserve 4 bytes here. Plus these extra bytes, the
 -               * headroom of the physical head should be enough for the
 -               * radiotap head that iwl3945 supported. See iwl3945_rt.
 -               */
 -              skb_reserve(rxb->skb, 4);
 -
 +              rxb->page = page;
                /* Get physical address of RB/SKB */
 -              rxb->real_dma_addr = pci_map_single(priv->pci_dev,
 -                                              rxb->skb->data,
 -                                              priv->hw_params.rx_buf_size,
 -                                              PCI_DMA_FROMDEVICE);
 +              rxb->page_dma = pci_map_page(priv->pci_dev, page, 0,
 +                              PAGE_SIZE << priv->hw_params.rx_page_order,
 +                              PCI_DMA_FROMDEVICE);
  
                spin_lock_irqsave(&rxq->lock, flags);
 +
                list_add_tail(&rxb->list, &rxq->rx_free);
 -              priv->alloc_rxb_skb++;
                rxq->free_count++;
 +              priv->alloc_rxb_page++;
 +
                spin_unlock_irqrestore(&rxq->lock, flags);
        }
  }
@@@ -1195,14 -1211,14 +1196,14 @@@ void iwl3945_rx_queue_reset(struct iwl_
        for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
                /* In the reset function, these buffers may have been allocated
                 * to an SKB, so we need to unmap and free potential storage */
 -              if (rxq->pool[i].skb != NULL) {
 -                      pci_unmap_single(priv->pci_dev,
 -                                       rxq->pool[i].real_dma_addr,
 -                                       priv->hw_params.rx_buf_size,
 -                                       PCI_DMA_FROMDEVICE);
 -                      priv->alloc_rxb_skb--;
 -                      dev_kfree_skb(rxq->pool[i].skb);
 -                      rxq->pool[i].skb = NULL;
 +              if (rxq->pool[i].page != NULL) {
 +                      pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
 +                              PAGE_SIZE << priv->hw_params.rx_page_order,
 +                              PCI_DMA_FROMDEVICE);
 +                      priv->alloc_rxb_page--;
 +                      __free_pages(rxq->pool[i].page,
 +                                   priv->hw_params.rx_page_order);
 +                      rxq->pool[i].page = NULL;
                }
                list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
        }
        /* Set us so that we have processed and used all buffers, but have
         * not restocked the Rx queue with fresh buffers */
        rxq->read = rxq->write = 0;
 -      rxq->free_count = 0;
        rxq->write_actual = 0;
 +      rxq->free_count = 0;
        spin_unlock_irqrestore(&rxq->lock, flags);
  }
  
@@@ -1244,14 -1260,12 +1245,14 @@@ static void iwl3945_rx_queue_free(struc
  {
        int i;
        for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
 -              if (rxq->pool[i].skb != NULL) {
 -                      pci_unmap_single(priv->pci_dev,
 -                                       rxq->pool[i].real_dma_addr,
 -                                       priv->hw_params.rx_buf_size,
 -                                       PCI_DMA_FROMDEVICE);
 -                      dev_kfree_skb(rxq->pool[i].skb);
 +              if (rxq->pool[i].page != NULL) {
 +                      pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
 +                              PAGE_SIZE << priv->hw_params.rx_page_order,
 +                              PCI_DMA_FROMDEVICE);
 +                      __free_pages(rxq->pool[i].page,
 +                                   priv->hw_params.rx_page_order);
 +                      rxq->pool[i].page = NULL;
 +                      priv->alloc_rxb_page--;
                }
        }
  
@@@ -1367,7 -1381,7 +1368,7 @@@ static void iwl3945_rx_handle(struct iw
        i = rxq->read;
  
        /* calculate total frames need to be restock after handling RX */
 -      total_empty = r - priv->rxq.write_actual;
 +      total_empty = r - rxq->write_actual;
        if (total_empty < 0)
                total_empty += RX_QUEUE_SIZE;
  
  
                rxq->queue[i] = NULL;
  
 -              pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
 -                              priv->hw_params.rx_buf_size,
 -                              PCI_DMA_FROMDEVICE);
 -              pkt = (struct iwl_rx_packet *)rxb->skb->data;
 +              pci_unmap_page(priv->pci_dev, rxb->page_dma,
 +                             PAGE_SIZE << priv->hw_params.rx_page_order,
 +                             PCI_DMA_FROMDEVICE);
 +              pkt = rxb_addr(rxb);
 +
 +              trace_iwlwifi_dev_rx(priv, pkt,
 +                      le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
  
                /* Reclaim a command buffer only if this packet is a response
                 *   to a (driver-originated) command.
                if (priv->rx_handlers[pkt->hdr.cmd]) {
                        IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i,
                                get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
 -                      priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
                        priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
 +                      priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
                } else {
                        /* No handling needed */
 -                      IWL_DEBUG_RX(priv, "r %d i %d No handler needed for %s, 0x%02x\n",
 +                      IWL_DEBUG_RX(priv,
 +                              "r %d i %d No handler needed for %s, 0x%02x\n",
                                r, i, get_cmd_string(pkt->hdr.cmd),
                                pkt->hdr.cmd);
                }
  
 +              /*
 +               * XXX: After here, we should always check rxb->page
 +               * against NULL before touching it or its virtual
 +               * memory (pkt). Because some rx_handler might have
 +               * already taken or freed the pages.
 +               */
 +
                if (reclaim) {
 -                      /* Invoke any callbacks, transfer the skb to caller, and
 -                       * fire off the (possibly) blocking iwl_send_cmd()
 +                      /* Invoke any callbacks, transfer the buffer to caller,
 +                       * and fire off the (possibly) blocking iwl_send_cmd()
                         * as we reclaim the driver command queue */
 -                      if (rxb && rxb->skb)
 +                      if (rxb->page)
                                iwl_tx_cmd_complete(priv, rxb);
                        else
                                IWL_WARN(priv, "Claim null rxb?\n");
                }
  
 -              /* For now we just don't re-use anything.  We can tweak this
 -               * later to try and re-use notification packets and SKBs that
 -               * fail to Rx correctly */
 -              if (rxb->skb != NULL) {
 -                      priv->alloc_rxb_skb--;
 -                      dev_kfree_skb_any(rxb->skb);
 -                      rxb->skb = NULL;
 -              }
 -
 +              /* Reuse the page if possible. For notification packets and
 +               * SKBs that fail to Rx correctly, add them back into the
 +               * rx_free list for reuse later. */
                spin_lock_irqsave(&rxq->lock, flags);
 -              list_add_tail(&rxb->list, &priv->rxq.rx_used);
 +              if (rxb->page != NULL) {
 +                      rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page,
 +                              0, PAGE_SIZE << priv->hw_params.rx_page_order,
 +                              PCI_DMA_FROMDEVICE);
 +                      list_add_tail(&rxb->list, &rxq->rx_free);
 +                      rxq->free_count++;
 +              } else
 +                      list_add_tail(&rxb->list, &rxq->rx_used);
 +
                spin_unlock_irqrestore(&rxq->lock, flags);
 +
                i = (i + 1) & RX_QUEUE_MASK;
                /* If there are a lot of unused frames,
                 * restock the Rx queue so ucode won't assert. */
                if (fill_rx) {
                        count++;
                        if (count >= 8) {
 -                              priv->rxq.read = i;
 +                              rxq->read = i;
                                iwl3945_rx_replenish_now(priv);
                                count = 0;
                        }
        }
  
        /* Backtrack one entry */
 -      priv->rxq.read = i;
 +      rxq->read = i;
        if (fill_rx)
                iwl3945_rx_replenish_now(priv);
        else
@@@ -1551,9 -1551,8 +1552,9 @@@ void iwl3945_dump_nic_error_log(struct 
                        "%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
                        desc_lookup(desc), desc, time, blink1, blink2,
                        ilink1, ilink2, data1);
 +              trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, 0,
 +                                      0, blink1, blink2, ilink1, ilink2);
        }
 -
  }
  
  #define EVENT_START_OFFSET  (6 * sizeof(u32))
@@@ -1570,7 -1569,6 +1571,7 @@@ static void iwl3945_print_event_log(str
        u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
        u32 ptr;        /* SRAM byte address of log data */
        u32 ev, time, data; /* event log data */
 +      unsigned long reg_flags;
  
        if (num_events == 0)
                return;
  
        ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
  
 +      /* Make sure device is powered up for SRAM reads */
 +      spin_lock_irqsave(&priv->reg_lock, reg_flags);
 +      iwl_grab_nic_access(priv);
 +
 +      /* Set starting address; reads will auto-increment */
 +      _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
 +      rmb();
 +
        /* "time" is actually "data" for mode 0 (no timestamp).
         * place event id # at far right for easier visual parsing. */
        for (i = 0; i < num_events; i++) {
 -              ev = iwl_read_targ_mem(priv, ptr);
 -              ptr += sizeof(u32);
 -              time = iwl_read_targ_mem(priv, ptr);
 -              ptr += sizeof(u32);
 +              ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
 +              time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                if (mode == 0) {
                        /* data, ev */
                        IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
 +                      trace_iwlwifi_dev_ucode_event(priv, 0, time, ev);
                } else {
 -                      data = iwl_read_targ_mem(priv, ptr);
 -                      ptr += sizeof(u32);
 +                      data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                        IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev);
 +                      trace_iwlwifi_dev_ucode_event(priv, time, data, ev);
                }
        }
 +
 +      /* Allow device to power down */
 +      iwl_release_nic_access(priv);
 +      spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
  }
  
 +/* For sanity check only.  Actual size is determined by uCode, typ. 512 */
 +#define IWL3945_MAX_EVENT_LOG_SIZE (512)
 +
  void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
  {
        u32 base;       /* SRAM byte address of event log header */
        num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
        next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
  
 +      if (capacity > IWL3945_MAX_EVENT_LOG_SIZE) {
 +              IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
 +                      capacity, IWL3945_MAX_EVENT_LOG_SIZE);
 +              capacity = IWL3945_MAX_EVENT_LOG_SIZE;
 +      }
 +
 +      if (next_entry > IWL3945_MAX_EVENT_LOG_SIZE) {
 +              IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
 +                      next_entry, IWL3945_MAX_EVENT_LOG_SIZE);
 +              next_entry = IWL3945_MAX_EVENT_LOG_SIZE;
 +      }
 +
        size = num_wraps ? capacity : next_entry;
  
        /* bail out if nothing in log */
@@@ -1713,8 -1685,6 +1714,8 @@@ static void iwl3945_irq_tasklet(struct 
        }
  #endif
  
 +      spin_unlock_irqrestore(&priv->lock, flags);
 +
        /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
         * atomic, make sure that inta covers all the interrupts that
         * we've discovered, even if FH interrupt came in just after
  
                handled |= CSR_INT_BIT_HW_ERR;
  
 -              spin_unlock_irqrestore(&priv->lock, flags);
 -
                return;
        }
  
                        "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
        }
  #endif
 -      spin_unlock_irqrestore(&priv->lock, flags);
  }
  
  static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
@@@ -2185,14 -2158,6 +2186,14 @@@ static int iwl3945_read_ucode(struct iw
                IWL_UCODE_API(priv->ucode_ver),
                IWL_UCODE_SERIAL(priv->ucode_ver));
  
 +      snprintf(priv->hw->wiphy->fw_version,
 +               sizeof(priv->hw->wiphy->fw_version),
 +               "%u.%u.%u.%u",
 +               IWL_UCODE_MAJOR(priv->ucode_ver),
 +               IWL_UCODE_MINOR(priv->ucode_ver),
 +               IWL_UCODE_API(priv->ucode_ver),
 +               IWL_UCODE_SERIAL(priv->ucode_ver));
 +
        IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
                       priv->ucode_ver);
        IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
@@@ -2514,7 -2479,7 +2515,7 @@@ static void iwl3945_alive_start(struct 
  
        iwl3945_reg_txpower_periodic(priv);
  
 -      iwl3945_led_register(priv);
 +      iwl_leds_init(priv);
  
        IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
        set_bit(STATUS_READY, &priv->status);
@@@ -2552,6 -2517,7 +2553,6 @@@ static void __iwl3945_down(struct iwl_p
        if (!exit_pending)
                set_bit(STATUS_EXIT_PENDING, &priv->status);
  
 -      iwl3945_led_unregister(priv);
        iwl_clear_stations_table(priv);
  
        /* Unblock any waiting calls */
                        test_bit(STATUS_EXIT_PENDING, &priv->status) <<
                                STATUS_EXIT_PENDING;
  
 -      priv->cfg->ops->lib->apm_ops.reset(priv);
 -      spin_lock_irqsave(&priv->lock, flags);
 -      iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 -      spin_unlock_irqrestore(&priv->lock, flags);
 -
        iwl3945_hw_txq_ctx_stop(priv);
        iwl3945_hw_rxq_stop(priv);
  
 -      iwl_write_prph(priv, APMG_CLK_DIS_REG,
 -                              APMG_CLK_VAL_DMA_CLK_RQT);
 -
 +      /* Power-down device's busmaster DMA clocks */
 +      iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
        udelay(5);
  
 -      if (exit_pending)
 -              priv->cfg->ops->lib->apm_ops.stop(priv);
 -      else
 -              priv->cfg->ops->lib->apm_ops.reset(priv);
 +      /* Stop the device, and put it in low power state */
 +      priv->cfg->ops->lib->apm_ops.stop(priv);
  
   exit:
        memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
@@@ -2750,34 -2724,19 +2751,34 @@@ static void iwl3945_bg_alive_start(stru
        mutex_unlock(&priv->mutex);
  }
  
 +/*
 + * 3945 cannot interrupt driver when hardware rf kill switch toggles;
 + * driver must poll CSR_GP_CNTRL_REG register for change.  This register
 + * *is* readable even when device has been SW_RESET into low power mode
 + * (e.g. during RF KILL).
 + */
  static void iwl3945_rfkill_poll(struct work_struct *data)
  {
        struct iwl_priv *priv =
            container_of(data, struct iwl_priv, rfkill_poll.work);
 +      bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status);
 +      bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL)
 +                      & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
  
 -      if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
 -              clear_bit(STATUS_RF_KILL_HW, &priv->status);
 -      else
 -              set_bit(STATUS_RF_KILL_HW, &priv->status);
 +      if (new_rfkill != old_rfkill) {
 +              if (new_rfkill)
 +                      set_bit(STATUS_RF_KILL_HW, &priv->status);
 +              else
 +                      clear_bit(STATUS_RF_KILL_HW, &priv->status);
  
 -      wiphy_rfkill_set_hw_state(priv->hw->wiphy,
 -                      test_bit(STATUS_RF_KILL_HW, &priv->status));
 +              wiphy_rfkill_set_hw_state(priv->hw->wiphy, new_rfkill);
 +
 +              IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
 +                              new_rfkill ? "disable radio" : "enable radio");
 +      }
  
 +      /* Keep this running, even if radio now enabled.  This will be
 +       * cancelled in mac_start() if system decides to start again */
        queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
                           round_jiffies_relative(2 * HZ));
  
@@@ -3193,8 -3152,6 +3194,8 @@@ static int iwl3945_mac_start(struct iee
         * no need to poll the killswitch state anymore */
        cancel_delayed_work(&priv->rfkill_poll);
  
 +      iwl_led_start(priv);
 +
        priv->is_open = 1;
        IWL_DEBUG_MAC80211(priv, "leave\n");
        return 0;
@@@ -3838,6 -3795,7 +3839,6 @@@ static int iwl3945_init_drv(struct iwl_
        /* Clear the driver's (not device's) station table */
        iwl_clear_stations_table(priv);
  
 -      priv->data_retry_limit = -1;
        priv->ieee_channels = NULL;
        priv->ieee_rates = NULL;
        priv->band = IEEE80211_BAND_2GHZ;
@@@ -4024,6 -3982,13 +4025,6 @@@ static int iwl3945_pci_probe(struct pci
         */
        spin_lock_init(&priv->reg_lock);
  
 -      /* amp init */
 -      err = priv->cfg->ops->lib->apm_ops.init(priv);
 -      if (err < 0) {
 -              IWL_DEBUG_INFO(priv, "Failed to init the card\n");
 -              goto out_iounmap;
 -      }
 -
        /***********************
         * 4. Read EEPROM
         * ********************/
                             &priv->bands[IEEE80211_BAND_2GHZ].channels[5]);
        iwl3945_setup_deferred_work(priv);
        iwl3945_setup_rx_handlers(priv);
 +      iwl_power_initialize(priv);
  
        /*********************************
         * 8. Setup and Register mac80211
@@@ -4160,15 -4124,6 +4161,15 @@@ static void __devexit iwl3945_pci_remov
                iwl3945_down(priv);
        }
  
 +      /*
 +       * Make sure device is reset to low power before unloading driver.
 +       * This may be redundant with iwl_down(), but there are paths to
 +       * run iwl_down() without calling apm_ops.stop(), and there are
 +       * paths to avoid running iwl_down() at all before leaving driver.
 +       * This (inexpensive) call *makes sure* device is reset.
 +       */
 +      priv->cfg->ops->lib->apm_ops.stop(priv);
 +
        /* make sure we flush any pending irq or
         * tasklet for the driver
         */
@@@ -4271,19 -4226,18 +4272,19 @@@ static void __exit iwl3945_exit(void
  
  MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
  
 -module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444);
 +module_param_named(antenna, iwl3945_mod_params.antenna, int, S_IRUGO);
  MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
 -module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
 +module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, S_IRUGO);
  MODULE_PARM_DESC(swcrypto,
                 "using software crypto (default 1 [software])\n");
  #ifdef CONFIG_IWLWIFI_DEBUG
 -module_param_named(debug, iwl_debug_level, uint, 0644);
 +module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR);
  MODULE_PARM_DESC(debug, "debug output mask");
  #endif
 -module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, 0444);
 +module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan,
 +                 int, S_IRUGO);
  MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
 -module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444);
 +module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO);
  MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
  
  module_exit(iwl3945_exit);
index af72cc746f1560467c15aa914b1b7655a0b4333e,f3c55658225bb97951a5ab9055030b84f9ed6389..2e00a4b389e64933c810413d85a460881a7eaca2
@@@ -23,6 -23,7 +23,7 @@@
  
  #include <linux/kernel.h>
  #include <linux/netdevice.h>
+ #include <linux/sched.h>
  #include <linux/etherdevice.h>
  #include <linux/wireless.h>
  #include <linux/ieee80211.h>
@@@ -404,21 -405,39 +405,21 @@@ static int iwm_cfg80211_join_ibss(struc
  {
        struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
        struct ieee80211_channel *chan = params->channel;
 -      struct cfg80211_bss *bss;
  
        if (!test_bit(IWM_STATUS_READY, &iwm->status))
                return -EIO;
  
 -      /* UMAC doesn't support creating IBSS network with specified bssid.
 -       * This should be removed after we have join only mode supported. */
 +      /* UMAC doesn't support creating or joining an IBSS network
 +       * with specified bssid. */
        if (params->bssid)
                return -EOPNOTSUPP;
  
 -      bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
 -                              params->ssid, params->ssid_len);
 -      if (!bss) {
 -              iwm_scan_one_ssid(iwm, params->ssid, params->ssid_len);
 -              schedule_timeout_interruptible(2 * HZ);
 -              bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
 -                                      params->ssid, params->ssid_len);
 -      }
 -      /* IBSS join only mode is not supported by UMAC ATM */
 -      if (bss) {
 -              cfg80211_put_bss(bss);
 -              return -EOPNOTSUPP;
 -      }
 -
        iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
        iwm->umac_profile->ibss.band = chan->band;
        iwm->umac_profile->ibss.channel = iwm->channel;
        iwm->umac_profile->ssid.ssid_len = params->ssid_len;
        memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
  
 -      if (params->bssid)
 -              memcpy(&iwm->umac_profile->bssid[0], params->bssid, ETH_ALEN);
 -
        return iwm_send_mlme_profile(iwm);
  }
  
@@@ -471,12 -490,12 +472,12 @@@ static int iwm_set_wpa_version(struct i
                return 0;
        }
  
 +      if (wpa_version & NL80211_WPA_VERSION_1)
 +              iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
 +
        if (wpa_version & NL80211_WPA_VERSION_2)
                iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
  
 -      if (wpa_version & NL80211_WPA_VERSION_1)
 -              iwm->umac_profile->sec.flags |= UMAC_SEC_FLG_WPA_ON_MSK;
 -
        return 0;
  }
  
@@@ -627,13 -646,6 +628,13 @@@ static int iwm_cfg80211_connect(struct 
                iwm->default_key = sme->key_idx;
        }
  
 +      /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
 +      if ((iwm->umac_profile->sec.flags &
 +           (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
 +          iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
 +                      iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
 +      }
 +
        ret = iwm_send_mlme_profile(iwm);
  
        if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
@@@ -670,19 -682,9 +671,19 @@@ static int iwm_cfg80211_disconnect(stru
  static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
                                    enum tx_power_setting type, int dbm)
  {
 +      struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
 +      int ret;
 +
        switch (type) {
        case TX_POWER_AUTOMATIC:
                return 0;
 +      case TX_POWER_FIXED:
 +              ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
 +                                            CFG_TX_PWR_LIMIT_USR, dbm * 2);
 +              if (ret < 0)
 +                      return ret;
 +
 +              return iwm_tx_power_trigger(iwm);
        default:
                return -EOPNOTSUPP;
        }
@@@ -694,7 -696,7 +695,7 @@@ static int iwm_cfg80211_get_txpower(str
  {
        struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
  
 -      *dbm = iwm->txpower;
 +      *dbm = iwm->txpower >> 1;
  
        return 0;
  }
index cad511afd90759df67bf3459bf131957b4d3b34f,84158b6d35d818ae80701e74cc1c5411f909085a..7e12438551ba02106bb415216063d20774d2e70e
@@@ -40,6 -40,7 +40,7 @@@
  #include <linux/wireless.h>
  #include <linux/etherdevice.h>
  #include <linux/ieee80211.h>
+ #include <linux/sched.h>
  
  #include "iwm.h"
  #include "bus.h"
@@@ -76,11 -77,6 +77,11 @@@ int iwm_send_wifi_if_cmd(struct iwm_pri
        int ret;
        u8 oid = hdr->oid;
  
 +      if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
 +              IWM_ERR(iwm, "Interface is not ready yet");
 +              return -EAGAIN;
 +      }
 +
        umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER;
        umac_cmd.resp = resp;
  
@@@ -279,17 -275,6 +280,17 @@@ int iwm_send_calib_results(struct iwm_p
        return ret;
  }
  
 +int iwm_send_ct_kill_cfg(struct iwm_priv *iwm, u8 entry, u8 exit)
 +{
 +      struct iwm_ct_kill_cfg_cmd cmd;
 +
 +      cmd.entry_threshold = entry;
 +      cmd.exit_threshold = exit;
 +
 +      return iwm_send_lmac_ptrough_cmd(iwm, REPLY_CT_KILL_CONFIG_CMD, &cmd,
 +                                       sizeof(struct iwm_ct_kill_cfg_cmd), 0);
 +}
 +
  int iwm_send_umac_reset(struct iwm_priv *iwm, __le32 reset_flags, bool resp)
  {
        struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
@@@ -793,24 -778,11 +794,24 @@@ int iwm_invalidate_mlme_profile(struct 
                return ret;
  
        ret = wait_event_interruptible_timeout(iwm->mlme_queue,
 -                              (iwm->umac_profile_active == 0), 2 * HZ);
 +                              (iwm->umac_profile_active == 0), 5 * HZ);
  
        return ret ? 0 : -EBUSY;
  }
  
 +int iwm_tx_power_trigger(struct iwm_priv *iwm)
 +{
 +      struct iwm_umac_pwr_trigger pwr_trigger;
 +
 +      pwr_trigger.hdr.oid = UMAC_WIFI_IF_CMD_TX_PWR_TRIGGER;
 +      pwr_trigger.hdr.buf_size =
 +              cpu_to_le16(sizeof(struct iwm_umac_pwr_trigger) -
 +                          sizeof(struct iwm_umac_wifi_if));
 +
 +
 +      return iwm_send_wifi_if_cmd(iwm, &pwr_trigger, sizeof(pwr_trigger), 1);
 +}
 +
  int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags)
  {
        struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
index f93e9139b0f20d50fd9f04b5ff3ec99c48209d84,222eb2cf1b30706b3f73c50f1aa91fe1fda39822..75f105a595430be0308de7490c3ac674b1911d0b
@@@ -38,6 -38,7 +38,7 @@@
  
  #include <linux/kernel.h>
  #include <linux/netdevice.h>
+ #include <linux/sched.h>
  #include <linux/ieee80211.h>
  #include <linux/wireless.h>
  
@@@ -63,8 -64,6 +64,8 @@@ static struct iwm_conf def_iwm_conf = 
                                  BIT(PHY_CALIBRATE_TX_IQ_CMD)  |
                                  BIT(PHY_CALIBRATE_RX_IQ_CMD)  |
                                  BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
 +      .ct_kill_entry          = 110,
 +      .ct_kill_exit           = 110,
        .reset_on_fatal_err     = 1,
        .auto_connect           = 1,
        .wimax_not_present      = 0,
@@@ -135,17 -134,6 +136,17 @@@ static void iwm_disconnect_work(struct 
        cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
  }
  
 +static void iwm_ct_kill_work(struct work_struct *work)
 +{
 +      struct iwm_priv *iwm =
 +              container_of(work, struct iwm_priv, ct_kill_delay.work);
 +      struct wiphy *wiphy = iwm_to_wiphy(iwm);
 +
 +      IWM_INFO(iwm, "CT kill delay timeout\n");
 +
 +      wiphy_rfkill_set_hw_state(wiphy, false);
 +}
 +
  static int __iwm_up(struct iwm_priv *iwm);
  static int __iwm_down(struct iwm_priv *iwm);
  
@@@ -207,33 -195,6 +208,33 @@@ static void iwm_reset_worker(struct wor
        mutex_unlock(&iwm->mutex);
  }
  
 +static void iwm_auth_retry_worker(struct work_struct *work)
 +{
 +      struct iwm_priv *iwm;
 +      int i, ret;
 +
 +      iwm = container_of(work, struct iwm_priv, auth_retry_worker);
 +      if (iwm->umac_profile_active) {
 +              ret = iwm_invalidate_mlme_profile(iwm);
 +              if (ret < 0)
 +                      return;
 +      }
 +
 +      iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
 +
 +      ret = iwm_send_mlme_profile(iwm);
 +      if (ret < 0)
 +              return;
 +
 +      for (i = 0; i < IWM_NUM_KEYS; i++)
 +              if (iwm->keys[i].key_len)
 +                      iwm_set_key(iwm, 0, &iwm->keys[i]);
 +
 +      iwm_set_tx_key(iwm, iwm->default_key);
 +}
 +
 +
 +
  static void iwm_watchdog(unsigned long data)
  {
        struct iwm_priv *iwm = (struct iwm_priv *)data;
@@@ -265,9 -226,7 +266,9 @@@ int iwm_priv_init(struct iwm_priv *iwm
        iwm->scan_id = 1;
        INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
        INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
 +      INIT_DELAYED_WORK(&iwm->ct_kill_delay, iwm_ct_kill_work);
        INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
 +      INIT_WORK(&iwm->auth_retry_worker, iwm_auth_retry_worker);
        INIT_LIST_HEAD(&iwm->bss_list);
  
        skb_queue_head_init(&iwm->rx_list);
@@@ -628,7 -587,6 +629,7 @@@ static int __iwm_up(struct iwm_priv *iw
  {
        int ret;
        struct iwm_notif *notif_reboot, *notif_ack = NULL;
 +      struct wiphy *wiphy = iwm_to_wiphy(iwm);
  
        ret = iwm_bus_enable(iwm);
        if (ret) {
                IWM_ERR(iwm, "MAC reading failed\n");
                goto err_disable;
        }
 +      memcpy(iwm_to_ndev(iwm)->perm_addr, iwm_to_ndev(iwm)->dev_addr,
 +              ETH_ALEN);
  
        /* We can load the FWs */
        ret = iwm_load_fw(iwm);
                goto err_disable;
        }
  
 +      snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "L%s_U%s",
 +               iwm->lmac_version, iwm->umac_version);
 +
        /* We configure the UMAC and enable the wifi module */
        ret = iwm_send_umac_config(iwm,
                        cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_CORE_EN) |
index 3ad95dc0dd8dd956de9ba0e846b4995cc7b01e05,771a301003c9ff79b23bb855636c9990f8cc774e..bdb1d7e7979db78436a4b48aae7c3d1ea9f1f540
@@@ -38,6 -38,7 +38,7 @@@
  
  #include <linux/kernel.h>
  #include <linux/netdevice.h>
+ #include <linux/sched.h>
  #include <linux/etherdevice.h>
  #include <linux/wireless.h>
  #include <linux/ieee80211.h>
@@@ -422,9 -423,7 +423,9 @@@ static int iwm_ntf_rx_ticket(struct iwm
                        if (IS_ERR(ticket_node))
                                return PTR_ERR(ticket_node);
  
 -                      IWM_DBG_RX(iwm, DBG, "TICKET RELEASE(%d)\n",
 +                      IWM_DBG_RX(iwm, DBG, "TICKET %s(%d)\n",
 +                                 ticket->action ==  IWM_RX_TICKET_RELEASE ?
 +                                 "RELEASE" : "DROP",
                                   ticket->id);
                        list_add_tail(&ticket_node->node, &iwm->rx_tickets);
  
@@@ -501,18 -500,6 +502,18 @@@ static int iwm_mlme_assoc_start(struct 
        return 0;
  }
  
 +static u8 iwm_is_open_wep_profile(struct iwm_priv *iwm)
 +{
 +      if ((iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_40 ||
 +           iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_104) &&
 +          (iwm->umac_profile->sec.ucast_cipher ==
 +           iwm->umac_profile->sec.mcast_cipher) &&
 +          (iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN))
 +             return 1;
 +
 +       return 0;
 +}
 +
  static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
                                   unsigned long buf_size,
                                   struct iwm_wifi_cmd *cmd)
                        goto ibss;
  
                if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
 -                      cfg80211_connect_result(iwm_to_ndev(iwm),
 -                                              complete->bssid,
 -                                              NULL, 0, NULL, 0,
 -                                              WLAN_STATUS_UNSPECIFIED_FAILURE,
 -                                              GFP_KERNEL);
 +                      if (!iwm_is_open_wep_profile(iwm)) {
 +                              cfg80211_connect_result(iwm_to_ndev(iwm),
 +                                             complete->bssid,
 +                                             NULL, 0, NULL, 0,
 +                                             WLAN_STATUS_UNSPECIFIED_FAILURE,
 +                                             GFP_KERNEL);
 +                      } else {
 +                              /* Let's try shared WEP auth */
 +                              IWM_ERR(iwm, "Trying WEP shared auth\n");
 +                              schedule_work(&iwm->auth_retry_worker);
 +                      }
                else
                        cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0,
                                              GFP_KERNEL);
@@@ -732,19 -713,6 +733,19 @@@ static int iwm_mlme_update_sta_table(st
        return 0;
  }
  
 +static int iwm_mlme_medium_lost(struct iwm_priv *iwm, u8 *buf,
 +                              unsigned long buf_size,
 +                              struct iwm_wifi_cmd *cmd)
 +{
 +      struct wiphy *wiphy = iwm_to_wiphy(iwm);
 +
 +      IWM_DBG_NTF(iwm, DBG, "WiFi/WiMax coexistence radio is OFF\n");
 +
 +      wiphy_rfkill_set_hw_state(wiphy, true);
 +
 +      return 0;
 +}
 +
  static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf,
                                     unsigned long buf_size,
                                     struct iwm_wifi_cmd *cmd)
@@@ -931,8 -899,6 +932,8 @@@ static int iwm_ntf_mlme(struct iwm_pri
        case WIFI_IF_NTFY_EXTENDED_IE_REQUIRED:
                IWM_DBG_MLME(iwm, DBG, "Extended IE required\n");
                break;
 +      case WIFI_IF_NTFY_RADIO_PREEMPTION:
 +              return iwm_mlme_medium_lost(iwm, buf, buf_size, cmd);
        case WIFI_IF_NTFY_BSS_TRK_TABLE_CHANGED:
                return iwm_mlme_update_bss_table(iwm, buf, buf_size, cmd);
        case WIFI_IF_NTFY_BSS_TRK_ENTRIES_REMOVED:
@@@ -1090,14 -1056,8 +1091,14 @@@ static int iwm_ntf_wifi_if_wrapper(stru
                                   unsigned long buf_size,
                                   struct iwm_wifi_cmd *cmd)
  {
 -      struct iwm_umac_wifi_if *hdr =
 -                      (struct iwm_umac_wifi_if *)cmd->buf.payload;
 +      struct iwm_umac_wifi_if *hdr;
 +
 +      if (cmd == NULL) {
 +              IWM_ERR(iwm, "Couldn't find expected wifi command\n");
 +              return -EINVAL;
 +      }
 +
 +      hdr = (struct iwm_umac_wifi_if *)cmd->buf.payload;
  
        IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: "
                    "oid is 0x%x\n", hdr->oid);
        return 0;
  }
  
 +#define CT_KILL_DELAY (30 * HZ)
  static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf,
                              unsigned long buf_size, struct iwm_wifi_cmd *cmd)
  {
                 flags & IWM_CARD_STATE_HW_DISABLED ? "ON" : "OFF",
                 flags & IWM_CARD_STATE_CTKILL_DISABLED ? "ON" : "OFF");
  
 -      wiphy_rfkill_set_hw_state(wiphy, flags & IWM_CARD_STATE_HW_DISABLED);
 +      if (flags & IWM_CARD_STATE_CTKILL_DISABLED) {
 +              /*
 +               * We got a CTKILL event: We bring the interface down in
 +               * oder to cool the device down, and try to bring it up
 +               * 30 seconds later. If it's still too hot, we'll go through
 +               * this code path again.
 +               */
 +              cancel_delayed_work_sync(&iwm->ct_kill_delay);
 +              schedule_delayed_work(&iwm->ct_kill_delay, CT_KILL_DELAY);
 +      }
 +
 +      wiphy_rfkill_set_hw_state(wiphy, flags &
 +                                (IWM_CARD_STATE_HW_DISABLED |
 +                                 IWM_CARD_STATE_CTKILL_DISABLED));
  
        return 0;
  }
@@@ -1336,14 -1282,6 +1337,14 @@@ int iwm_rx_handle(struct iwm_priv *iwm
  
        switch (le32_to_cpu(hdr->cmd)) {
        case UMAC_REBOOT_BARKER:
 +              if (test_bit(IWM_STATUS_READY, &iwm->status)) {
 +                      IWM_ERR(iwm, "Unexpected BARKER\n");
 +
 +                      schedule_work(&iwm->reset_worker);
 +
 +                      return 0;
 +              }
 +
                return iwm_notif_send(iwm, NULL, IWM_BARKER_REBOOT_NOTIFICATION,
                                      IWM_SRC_UDMA, buf, buf_size);
        case UMAC_ACK_BARKER:
@@@ -1506,8 -1444,7 +1507,8 @@@ static void iwm_rx_process_packet(struc
                }
                break;
        case IWM_RX_TICKET_DROP:
 -              IWM_DBG_RX(iwm, DBG, "DROP packet\n");
 +              IWM_DBG_RX(iwm, DBG, "DROP packet: 0x%x\n",
 +                         le16_to_cpu(ticket_node->ticket->flags));
                kfree_skb(packet->skb);
                break;
        default:
index 5d7c011fe29657aac6cae61f758d3c1ea19ea92f,8c3766a6e8e7f9c7c948e7aab5a0af6c779ba33a..eb856adbf8eace1712544a295688e74e3f4dcb6d
@@@ -3,8 -3,9 +3,9 @@@
    */
  #include <linux/netdevice.h>
  #include <linux/etherdevice.h>
+ #include <linux/sched.h>
  
 -#include "hostcmd.h"
 +#include "host.h"
  #include "radiotap.h"
  #include "decl.h"
  #include "defs.h"
index 3e6a71ce5b5433a736a929b92af1e7517fc550e3,2505be56ae39fd8c48c2f3ea562ec64453141841..a3ba3539db027df101ce154d986ff1645be71fee
@@@ -23,6 -23,7 +23,7 @@@
  #include <linux/netdevice.h>
  #include <linux/ethtool.h>
  #include <linux/pci.h>
+ #include <linux/sched.h>
  #include <linux/etherdevice.h>
  #include <linux/delay.h>
  #include <linux/if_arp.h>
@@@ -40,9 -41,6 +41,9 @@@
  #define ISL3877_IMAGE_FILE    "isl3877"
  #define ISL3886_IMAGE_FILE    "isl3886"
  #define ISL3890_IMAGE_FILE    "isl3890"
 +MODULE_FIRMWARE(ISL3877_IMAGE_FILE);
 +MODULE_FIRMWARE(ISL3886_IMAGE_FILE);
 +MODULE_FIRMWARE(ISL3890_IMAGE_FILE);
  
  static int prism54_bring_down(islpci_private *);
  static int islpci_alloc_memory(islpci_private *);
index 595e4414d770ae333f0bd83e7a46ec5e8ded44a8,1c88c2ea59aa4e605fc738f8adde1e2d01ea26cb..5ee9d2a193601afe146767e134fff59a17ee6c76
@@@ -2074,7 -2074,7 +2074,7 @@@ static irqreturn_t ray_interrupt(int ir
                                del_timer(&local->timer);
                                local->timer.expires = jiffies + HZ * 5;
                                local->timer.data = (long)local;
 -                              if (status == CCS_START_NETWORK) {
 +                              if (cmd == CCS_START_NETWORK) {
                                        DEBUG(0,
                                              "ray_cs interrupt network \"%s\" start failed\n",
                                              local->sparm.b4.a_current_ess_id);
@@@ -2879,7 -2879,7 +2879,7 @@@ static int write_essid(struct file *fil
                       unsigned long count, void *data)
  {
        static char proc_essid[33];
-       int len = count;
+       unsigned int len = count;
  
        if (len > 32)
                len = 32;
index e6b0fbbc3fc75e360e2cb9f98103ed8c2cd0f233,68bc9bb1dbf9fdcdf57857a2f260afdca93f8086..7d323a763b54014142bf8dc51a2f509621b14733
@@@ -1,5 -1,5 +1,5 @@@
  /*
 -      Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
 +      Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
        <http://rt2x00.serialmonkey.com>
  
        This program is free software; you can redistribute it and/or modify
@@@ -27,6 -27,7 +27,7 @@@
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/poll.h>
+ #include <linux/sched.h>
  #include <linux/uaccess.h>
  
  #include "rt2x00.h"
diff --combined drivers/staging/Kconfig
index 4e3873bfd010dd91ebe37d8253154d3f1c7f89e3,d21b3469f6d7a5d1a85904d14315d3c64639c295..dfcd75cf4907f5c992bc853f59850611848c128a
@@@ -59,8 -59,6 +59,6 @@@ source "drivers/staging/echo/Kconfig
  
  source "drivers/staging/poch/Kconfig"
  
- source "drivers/staging/agnx/Kconfig"
  source "drivers/staging/otus/Kconfig"
  
  source "drivers/staging/rt2860/Kconfig"
@@@ -95,8 -93,6 +93,6 @@@ source "drivers/staging/dst/Kconfig
  
  source "drivers/staging/pohmelfs/Kconfig"
  
- source "drivers/staging/stlc45xx/Kconfig"
  source "drivers/staging/b3dfg/Kconfig"
  
  source "drivers/staging/phison/Kconfig"
@@@ -129,15 -125,5 +125,13 @@@ source "drivers/staging/sep/Kconfig
  
  source "drivers/staging/iio/Kconfig"
  
- source "drivers/staging/cowloop/Kconfig"
 +source "drivers/staging/strip/Kconfig"
 +
 +source "drivers/staging/arlan/Kconfig"
 +
 +source "drivers/staging/wavelan/Kconfig"
 +
 +source "drivers/staging/netwave/Kconfig"
 +
  endif # !STAGING_EXCLUDE_BUILD
  endif # STAGING
diff --combined drivers/staging/Makefile
index fb1d7851b5635a21e33ae43d19d75abbeb5d948c,8cbf1aebea2ec7e440662569fbbac7258cea88a4..7719d04a4a860b2fee784759d73a1aa514d53348
@@@ -12,7 -12,6 +12,6 @@@ obj-$(CONFIG_W35UND)          += winbond
  obj-$(CONFIG_PRISM2_USB)      += wlan-ng/
  obj-$(CONFIG_ECHO)            += echo/
  obj-$(CONFIG_POCH)            += poch/
- obj-$(CONFIG_AGNX)            += agnx/
  obj-$(CONFIG_OTUS)            += otus/
  obj-$(CONFIG_RT2860)          += rt2860/
  obj-$(CONFIG_RT2870)          += rt2870/
@@@ -30,7 -29,6 +29,6 @@@ obj-$(CONFIG_ANDROID)         += android
  obj-$(CONFIG_ANDROID)         += dream/
  obj-$(CONFIG_DST)             += dst/
  obj-$(CONFIG_POHMELFS)                += pohmelfs/
- obj-$(CONFIG_STLC45XX)                += stlc45xx/
  obj-$(CONFIG_B3DFG)           += b3dfg/
  obj-$(CONFIG_IDE_PHISON)      += phison/
  obj-$(CONFIG_PLAN9AUTH)               += p9auth/
@@@ -46,9 -44,3 +44,8 @@@ obj-$(CONFIG_VME_BUS)         += vme
  obj-$(CONFIG_RAR_REGISTER)    += rar/
  obj-$(CONFIG_DX_SEP)          += sep/
  obj-$(CONFIG_IIO)             += iio/
- obj-$(CONFIG_COWLOOP)         += cowloop/
 +obj-$(CONFIG_STRIP)           += strip/
 +obj-$(CONFIG_ARLAN)           += arlan/
 +obj-$(CONFIG_WAVELAN)         += wavelan/
 +obj-$(CONFIG_PCMCIA_WAVELAN)  += wavelan/
 +obj-$(CONFIG_PCMCIA_NETWAVE)  += netwave/
index faf6c608741409fe2901a888d287739cabef641b,203c79b8180f3fc1c930348a5e3cb4c954150ba7..3211dd3765a094b43ad876397962841e9fa96877
@@@ -1,7 -1,6 +1,7 @@@
  config RTL8187SE
        tristate "RealTek RTL8187SE Wireless LAN NIC driver"
-       depends on PCI
+       depends on PCI && WLAN
 -      depends on WIRELESS_EXT
 +      select WIRELESS_EXT
 +      select WEXT_PRIV
        default N
        ---help---
index 5c077b9fdc77d6a947ffe2e4c01b8dd29ec4f7b9,37e4fde4507382917a5aa4c4ecb13a4c43941f6e..2ae3745f775f6f1fa8af6d2befcc66f0be3ecbc1
@@@ -1,7 -1,6 +1,7 @@@
  config RTL8192E
        tristate "RealTek RTL8192E Wireless LAN NIC driver"
-       depends on PCI
+       depends on PCI && WLAN
 -      depends on WIRELESS_EXT
 +      select WIRELESS_EXT
 +      select WEXT_PRIV
        default N
        ---help---
diff --combined fs/compat_ioctl.c
index cacf8a83e394f16e36ce0e5c21e09ef51b42487c,d84e7058c298a56dd9b22c6c6fa6fb286fb730c9..229e722181651f240607bf2606886956bf2c8532
@@@ -246,6 -246,428 +246,6 @@@ static int do_video_set_spu_palette(uns
        return err;
  }
  
 -#ifdef CONFIG_NET
 -static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      struct compat_timeval __user *up = compat_ptr(arg);
 -      struct timeval ktv;
 -      mm_segment_t old_fs = get_fs();
 -      int err;
 -
 -      set_fs(KERNEL_DS);
 -      err = sys_ioctl(fd, cmd, (unsigned long)&ktv);
 -      set_fs(old_fs);
 -      if(!err) {
 -              err = put_user(ktv.tv_sec, &up->tv_sec);
 -              err |= __put_user(ktv.tv_usec, &up->tv_usec);
 -      }
 -      return err;
 -}
 -
 -static int do_siocgstampns(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      struct compat_timespec __user *up = compat_ptr(arg);
 -      struct timespec kts;
 -      mm_segment_t old_fs = get_fs();
 -      int err;
 -
 -      set_fs(KERNEL_DS);
 -      err = sys_ioctl(fd, cmd, (unsigned long)&kts);
 -      set_fs(old_fs);
 -      if (!err) {
 -              err = put_user(kts.tv_sec, &up->tv_sec);
 -              err |= __put_user(kts.tv_nsec, &up->tv_nsec);
 -      }
 -      return err;
 -}
 -
 -struct ifmap32 {
 -      compat_ulong_t mem_start;
 -      compat_ulong_t mem_end;
 -      unsigned short base_addr;
 -      unsigned char irq;
 -      unsigned char dma;
 -      unsigned char port;
 -};
 -
 -struct ifreq32 {
 -#define IFHWADDRLEN     6
 -#define IFNAMSIZ        16
 -        union {
 -                char    ifrn_name[IFNAMSIZ];            /* if name, e.g. "en0" */
 -        } ifr_ifrn;
 -        union {
 -                struct  sockaddr ifru_addr;
 -                struct  sockaddr ifru_dstaddr;
 -                struct  sockaddr ifru_broadaddr;
 -                struct  sockaddr ifru_netmask;
 -                struct  sockaddr ifru_hwaddr;
 -                short   ifru_flags;
 -                compat_int_t     ifru_ivalue;
 -                compat_int_t     ifru_mtu;
 -                struct  ifmap32 ifru_map;
 -                char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
 -              char    ifru_newname[IFNAMSIZ];
 -                compat_caddr_t ifru_data;
 -          /* XXXX? ifru_settings should be here */
 -        } ifr_ifru;
 -};
 -
 -struct ifconf32 {
 -        compat_int_t  ifc_len;                        /* size of buffer       */
 -        compat_caddr_t  ifcbuf;
 -};
 -
 -static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      struct ifreq __user *uifr;
 -      int err;
 -
 -      uifr = compat_alloc_user_space(sizeof(struct ifreq));
 -      if (copy_in_user(uifr, compat_ptr(arg), sizeof(struct ifreq32)))
 -              return -EFAULT;
 -
 -      err = sys_ioctl(fd, SIOCGIFNAME, (unsigned long)uifr);
 -      if (err)
 -              return err;
 -
 -      if (copy_in_user(compat_ptr(arg), uifr, sizeof(struct ifreq32)))
 -              return -EFAULT;
 -
 -      return 0;
 -}
 -
 -static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      struct ifconf32 ifc32;
 -      struct ifconf ifc;
 -      struct ifconf __user *uifc;
 -      struct ifreq32 __user *ifr32;
 -      struct ifreq __user *ifr;
 -      unsigned int i, j;
 -      int err;
 -
 -      if (copy_from_user(&ifc32, compat_ptr(arg), sizeof(struct ifconf32)))
 -              return -EFAULT;
 -
 -      if (ifc32.ifcbuf == 0) {
 -              ifc32.ifc_len = 0;
 -              ifc.ifc_len = 0;
 -              ifc.ifc_req = NULL;
 -              uifc = compat_alloc_user_space(sizeof(struct ifconf));
 -      } else {
 -              size_t len =((ifc32.ifc_len / sizeof (struct ifreq32)) + 1) *
 -                      sizeof (struct ifreq);
 -              uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);
 -              ifc.ifc_len = len;
 -              ifr = ifc.ifc_req = (void __user *)(uifc + 1);
 -              ifr32 = compat_ptr(ifc32.ifcbuf);
 -              for (i = 0; i < ifc32.ifc_len; i += sizeof (struct ifreq32)) {
 -                      if (copy_in_user(ifr, ifr32, sizeof(struct ifreq32)))
 -                              return -EFAULT;
 -                      ifr++;
 -                      ifr32++; 
 -              }
 -      }
 -      if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
 -              return -EFAULT;
 -
 -      err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)uifc); 
 -      if (err)
 -              return err;
 -
 -      if (copy_from_user(&ifc, uifc, sizeof(struct ifconf))) 
 -              return -EFAULT;
 -
 -      ifr = ifc.ifc_req;
 -      ifr32 = compat_ptr(ifc32.ifcbuf);
 -      for (i = 0, j = 0;
 -             i + sizeof (struct ifreq32) <= ifc32.ifc_len && j < ifc.ifc_len;
 -           i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
 -              if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32)))
 -                      return -EFAULT;
 -              ifr32++;
 -              ifr++;
 -      }
 -
 -      if (ifc32.ifcbuf == 0) {
 -              /* Translate from 64-bit structure multiple to
 -               * a 32-bit one.
 -               */
 -              i = ifc.ifc_len;
 -              i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
 -              ifc32.ifc_len = i;
 -      } else {
 -              ifc32.ifc_len = i;
 -      }
 -      if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32)))
 -              return -EFAULT;
 -
 -      return 0;
 -}
 -
 -static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      struct ifreq __user *ifr;
 -      struct ifreq32 __user *ifr32;
 -      u32 data;
 -      void __user *datap;
 -      
 -      ifr = compat_alloc_user_space(sizeof(*ifr));
 -      ifr32 = compat_ptr(arg);
 -
 -      if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
 -              return -EFAULT;
 -
 -      if (get_user(data, &ifr32->ifr_ifru.ifru_data))
 -              return -EFAULT;
 -
 -      datap = compat_ptr(data);
 -      if (put_user(datap, &ifr->ifr_ifru.ifru_data))
 -              return -EFAULT;
 -
 -      return sys_ioctl(fd, cmd, (unsigned long) ifr);
 -}
 -
 -static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      struct ifreq kifr;
 -      struct ifreq __user *uifr;
 -      struct ifreq32 __user *ifr32 = compat_ptr(arg);
 -      mm_segment_t old_fs;
 -      int err;
 -      u32 data;
 -      void __user *datap;
 -
 -      switch (cmd) {
 -      case SIOCBONDENSLAVE:
 -      case SIOCBONDRELEASE:
 -      case SIOCBONDSETHWADDR:
 -      case SIOCBONDCHANGEACTIVE:
 -              if (copy_from_user(&kifr, ifr32, sizeof(struct ifreq32)))
 -                      return -EFAULT;
 -
 -              old_fs = get_fs();
 -              set_fs (KERNEL_DS);
 -              err = sys_ioctl (fd, cmd, (unsigned long)&kifr);
 -              set_fs (old_fs);
 -
 -              return err;
 -      case SIOCBONDSLAVEINFOQUERY:
 -      case SIOCBONDINFOQUERY:
 -              uifr = compat_alloc_user_space(sizeof(*uifr));
 -              if (copy_in_user(&uifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
 -                      return -EFAULT;
 -
 -              if (get_user(data, &ifr32->ifr_ifru.ifru_data))
 -                      return -EFAULT;
 -
 -              datap = compat_ptr(data);
 -              if (put_user(datap, &uifr->ifr_ifru.ifru_data))
 -                      return -EFAULT;
 -
 -              return sys_ioctl (fd, cmd, (unsigned long)uifr);
 -      default:
 -              return -EINVAL;
 -      };
 -}
 -
 -static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      struct ifreq __user *u_ifreq64;
 -      struct ifreq32 __user *u_ifreq32 = compat_ptr(arg);
 -      char tmp_buf[IFNAMSIZ];
 -      void __user *data64;
 -      u32 data32;
 -
 -      if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
 -                         IFNAMSIZ))
 -              return -EFAULT;
 -      if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
 -              return -EFAULT;
 -      data64 = compat_ptr(data32);
 -
 -      u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
 -
 -      /* Don't check these user accesses, just let that get trapped
 -       * in the ioctl handler instead.
 -       */
 -      if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
 -                       IFNAMSIZ))
 -              return -EFAULT;
 -      if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
 -              return -EFAULT;
 -
 -      return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64);
 -}
 -
 -static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      struct ifreq ifr;
 -      struct ifreq32 __user *uifr32;
 -      struct ifmap32 __user *uifmap32;
 -      mm_segment_t old_fs;
 -      int err;
 -      
 -      uifr32 = compat_ptr(arg);
 -      uifmap32 = &uifr32->ifr_ifru.ifru_map;
 -      switch (cmd) {
 -      case SIOCSIFMAP:
 -              err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
 -              err |= __get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
 -              err |= __get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
 -              err |= __get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
 -              err |= __get_user(ifr.ifr_map.irq, &uifmap32->irq);
 -              err |= __get_user(ifr.ifr_map.dma, &uifmap32->dma);
 -              err |= __get_user(ifr.ifr_map.port, &uifmap32->port);
 -              if (err)
 -                      return -EFAULT;
 -              break;
 -      case SIOCSHWTSTAMP:
 -              if (copy_from_user(&ifr, uifr32, sizeof(*uifr32)))
 -                      return -EFAULT;
 -              ifr.ifr_data = compat_ptr(uifr32->ifr_ifru.ifru_data);
 -              break;
 -      default:
 -              if (copy_from_user(&ifr, uifr32, sizeof(*uifr32)))
 -                      return -EFAULT;
 -              break;
 -      }
 -      old_fs = get_fs();
 -      set_fs (KERNEL_DS);
 -      err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
 -      set_fs (old_fs);
 -      if (!err) {
 -              switch (cmd) {
 -              /* TUNSETIFF is defined as _IOW, it should be _IORW
 -               * as the data is copied back to user space, but that
 -               * cannot be fixed without breaking all existing apps.
 -               */
 -              case TUNSETIFF:
 -              case TUNGETIFF:
 -              case SIOCGIFFLAGS:
 -              case SIOCGIFMETRIC:
 -              case SIOCGIFMTU:
 -              case SIOCGIFMEM:
 -              case SIOCGIFHWADDR:
 -              case SIOCGIFINDEX:
 -              case SIOCGIFADDR:
 -              case SIOCGIFBRDADDR:
 -              case SIOCGIFDSTADDR:
 -              case SIOCGIFNETMASK:
 -              case SIOCGIFTXQLEN:
 -                      if (copy_to_user(uifr32, &ifr, sizeof(*uifr32)))
 -                              return -EFAULT;
 -                      break;
 -              case SIOCGIFMAP:
 -                      err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
 -                      err |= __put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
 -                      err |= __put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
 -                      err |= __put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
 -                      err |= __put_user(ifr.ifr_map.irq, &uifmap32->irq);
 -                      err |= __put_user(ifr.ifr_map.dma, &uifmap32->dma);
 -                      err |= __put_user(ifr.ifr_map.port, &uifmap32->port);
 -                      if (err)
 -                              err = -EFAULT;
 -                      break;
 -              }
 -      }
 -      return err;
 -}
 -
 -struct rtentry32 {
 -        u32                   rt_pad1;
 -        struct sockaddr rt_dst;         /* target address               */
 -        struct sockaddr rt_gateway;     /* gateway addr (RTF_GATEWAY)   */
 -        struct sockaddr rt_genmask;     /* target network mask (IP)     */
 -        unsigned short  rt_flags;
 -        short           rt_pad2;
 -        u32                   rt_pad3;
 -        unsigned char   rt_tos;
 -        unsigned char   rt_class;
 -        short           rt_pad4;
 -        short           rt_metric;      /* +1 for binary compatibility! */
 -        /* char * */ u32 rt_dev;        /* forcing the device at add    */
 -        u32                   rt_mtu;         /* per route MTU/Window         */
 -        u32                   rt_window;      /* Window clamping              */
 -        unsigned short  rt_irtt;        /* Initial RTT                  */
 -
 -};
 -
 -struct in6_rtmsg32 {
 -      struct in6_addr         rtmsg_dst;
 -      struct in6_addr         rtmsg_src;
 -      struct in6_addr         rtmsg_gateway;
 -      u32                     rtmsg_type;
 -      u16                     rtmsg_dst_len;
 -      u16                     rtmsg_src_len;
 -      u32                     rtmsg_metric;
 -      u32                     rtmsg_info;
 -      u32                     rtmsg_flags;
 -      s32                     rtmsg_ifindex;
 -};
 -
 -static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      int ret;
 -      void *r = NULL;
 -      struct in6_rtmsg r6;
 -      struct rtentry r4;
 -      char devname[16];
 -      u32 rtdev;
 -      mm_segment_t old_fs = get_fs();
 -      
 -      struct socket *mysock = sockfd_lookup(fd, &ret);
 -
 -      if (mysock && mysock->sk && mysock->sk->sk_family == AF_INET6) { /* ipv6 */
 -              struct in6_rtmsg32 __user *ur6 = compat_ptr(arg);
 -              ret = copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst),
 -                      3 * sizeof(struct in6_addr));
 -              ret |= __get_user (r6.rtmsg_type, &(ur6->rtmsg_type));
 -              ret |= __get_user (r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len));
 -              ret |= __get_user (r6.rtmsg_src_len, &(ur6->rtmsg_src_len));
 -              ret |= __get_user (r6.rtmsg_metric, &(ur6->rtmsg_metric));
 -              ret |= __get_user (r6.rtmsg_info, &(ur6->rtmsg_info));
 -              ret |= __get_user (r6.rtmsg_flags, &(ur6->rtmsg_flags));
 -              ret |= __get_user (r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex));
 -              
 -              r = (void *) &r6;
 -      } else { /* ipv4 */
 -              struct rtentry32 __user *ur4 = compat_ptr(arg);
 -              ret = copy_from_user (&r4.rt_dst, &(ur4->rt_dst),
 -                                      3 * sizeof(struct sockaddr));
 -              ret |= __get_user (r4.rt_flags, &(ur4->rt_flags));
 -              ret |= __get_user (r4.rt_metric, &(ur4->rt_metric));
 -              ret |= __get_user (r4.rt_mtu, &(ur4->rt_mtu));
 -              ret |= __get_user (r4.rt_window, &(ur4->rt_window));
 -              ret |= __get_user (r4.rt_irtt, &(ur4->rt_irtt));
 -              ret |= __get_user (rtdev, &(ur4->rt_dev));
 -              if (rtdev) {
 -                      ret |= copy_from_user (devname, compat_ptr(rtdev), 15);
 -                      r4.rt_dev = devname; devname[15] = 0;
 -              } else
 -                      r4.rt_dev = NULL;
 -
 -              r = (void *) &r4;
 -      }
 -
 -      if (ret) {
 -              ret = -EFAULT;
 -              goto out;
 -      }
 -
 -      set_fs (KERNEL_DS);
 -      ret = sys_ioctl (fd, cmd, (unsigned long) r);
 -      set_fs (old_fs);
 -
 -out:
 -      if (mysock)
 -              sockfd_put(mysock);
 -
 -      return ret;
 -}
 -#endif
 -
  #ifdef CONFIG_BLOCK
  typedef struct sg_io_hdr32 {
        compat_int_t interface_id;      /* [i] 'S' for SCSI generic (required) */
@@@ -790,6 -1212,170 +790,6 @@@ static int do_smb_getmountuid(unsigned 
        return err;
  }
  
 -struct atmif_sioc32 {
 -        compat_int_t  number;
 -        compat_int_t  length;
 -        compat_caddr_t        arg;
 -};
 -
 -struct atm_iobuf32 {
 -      compat_int_t    length;
 -      compat_caddr_t  buffer;
 -};
 -
 -#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
 -#define ATM_GETNAMES32    _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
 -#define ATM_GETTYPE32     _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
 -#define ATM_GETESI32    _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
 -#define ATM_GETADDR32   _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
 -#define ATM_RSTADDR32   _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
 -#define ATM_ADDADDR32   _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
 -#define ATM_DELADDR32   _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
 -#define ATM_GETCIRANGE32  _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
 -#define ATM_SETCIRANGE32  _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
 -#define ATM_SETESI32      _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
 -#define ATM_SETESIF32     _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
 -#define ATM_GETSTAT32     _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
 -#define ATM_GETSTATZ32    _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
 -#define ATM_GETLOOP32   _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
 -#define ATM_SETLOOP32   _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
 -#define ATM_QUERYLOOP32         _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
 -
 -static struct {
 -        unsigned int cmd32;
 -        unsigned int cmd;
 -} atm_ioctl_map[] = {
 -        { ATM_GETLINKRATE32, ATM_GETLINKRATE },
 -      { ATM_GETNAMES32,    ATM_GETNAMES },
 -        { ATM_GETTYPE32,     ATM_GETTYPE },
 -        { ATM_GETESI32,      ATM_GETESI },
 -        { ATM_GETADDR32,     ATM_GETADDR },
 -        { ATM_RSTADDR32,     ATM_RSTADDR },
 -        { ATM_ADDADDR32,     ATM_ADDADDR },
 -        { ATM_DELADDR32,     ATM_DELADDR },
 -        { ATM_GETCIRANGE32,  ATM_GETCIRANGE },
 -      { ATM_SETCIRANGE32,  ATM_SETCIRANGE },
 -      { ATM_SETESI32,      ATM_SETESI },
 -      { ATM_SETESIF32,     ATM_SETESIF },
 -      { ATM_GETSTAT32,     ATM_GETSTAT },
 -      { ATM_GETSTATZ32,    ATM_GETSTATZ },
 -      { ATM_GETLOOP32,     ATM_GETLOOP },
 -      { ATM_SETLOOP32,     ATM_SETLOOP },
 -      { ATM_QUERYLOOP32,   ATM_QUERYLOOP }
 -};
 -
 -#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
 -
 -static int do_atm_iobuf(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      struct atm_iobuf   __user *iobuf;
 -      struct atm_iobuf32 __user *iobuf32;
 -      u32 data;
 -      void __user *datap;
 -      int len, err;
 -
 -      iobuf = compat_alloc_user_space(sizeof(*iobuf));
 -      iobuf32 = compat_ptr(arg);
 -
 -      if (get_user(len, &iobuf32->length) ||
 -          get_user(data, &iobuf32->buffer))
 -              return -EFAULT;
 -      datap = compat_ptr(data);
 -      if (put_user(len, &iobuf->length) ||
 -          put_user(datap, &iobuf->buffer))
 -              return -EFAULT;
 -
 -      err = sys_ioctl(fd, cmd, (unsigned long)iobuf);
 -
 -      if (!err) {
 -              if (copy_in_user(&iobuf32->length, &iobuf->length,
 -                               sizeof(int)))
 -                      err = -EFAULT;
 -      }
 -
 -      return err;
 -}
 -
 -static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -        struct atmif_sioc   __user *sioc;
 -      struct atmif_sioc32 __user *sioc32;
 -      u32 data;
 -      void __user *datap;
 -      int err;
 -        
 -      sioc = compat_alloc_user_space(sizeof(*sioc));
 -      sioc32 = compat_ptr(arg);
 -
 -      if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int)) ||
 -          get_user(data, &sioc32->arg))
 -              return -EFAULT;
 -      datap = compat_ptr(data);
 -      if (put_user(datap, &sioc->arg))
 -              return -EFAULT;
 -
 -      err = sys_ioctl(fd, cmd, (unsigned long) sioc);
 -
 -      if (!err) {
 -              if (copy_in_user(&sioc32->length, &sioc->length,
 -                               sizeof(int)))
 -                      err = -EFAULT;
 -      }
 -      return err;
 -}
 -
 -static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
 -{
 -        int i;
 -        unsigned int cmd = 0;
 -        
 -      switch (cmd32) {
 -      case SONET_GETSTAT:
 -      case SONET_GETSTATZ:
 -      case SONET_GETDIAG:
 -      case SONET_SETDIAG:
 -      case SONET_CLRDIAG:
 -      case SONET_SETFRAMING:
 -      case SONET_GETFRAMING:
 -      case SONET_GETFRSENSE:
 -              return do_atmif_sioc(fd, cmd32, arg);
 -      }
 -
 -      for (i = 0; i < NR_ATM_IOCTL; i++) {
 -              if (cmd32 == atm_ioctl_map[i].cmd32) {
 -                      cmd = atm_ioctl_map[i].cmd;
 -                      break;
 -              }
 -      }
 -      if (i == NR_ATM_IOCTL)
 -              return -EINVAL;
 -        
 -        switch (cmd) {
 -      case ATM_GETNAMES:
 -              return do_atm_iobuf(fd, cmd, arg);
 -          
 -      case ATM_GETLINKRATE:
 -        case ATM_GETTYPE:
 -        case ATM_GETESI:
 -        case ATM_GETADDR:
 -        case ATM_RSTADDR:
 -        case ATM_ADDADDR:
 -        case ATM_DELADDR:
 -        case ATM_GETCIRANGE:
 -      case ATM_SETCIRANGE:
 -      case ATM_SETESI:
 -      case ATM_SETESIF:
 -      case ATM_GETSTAT:
 -      case ATM_GETSTATZ:
 -      case ATM_GETLOOP:
 -      case ATM_SETLOOP:
 -      case ATM_QUERYLOOP:
 -                return do_atmif_sioc(fd, cmd, arg);
 -        }
 -
 -        return -EINVAL;
 -}
 -
  static __used int
  ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
  {
@@@ -1132,6 -1718,21 +1132,6 @@@ static int do_i2c_smbus_ioctl(unsigned 
        return sys_ioctl(fd, cmd, (unsigned long)tdata);
  }
  
 -/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
 - * for some operations; this forces use of the newer bridge-utils that
 - * use compatible ioctls
 - */
 -static int old_bridge_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 -{
 -      u32 tmp;
 -
 -      if (get_user(tmp, (u32 __user *) arg))
 -              return -EFAULT;
 -      if (tmp == BRCTL_GET_VERSION)
 -              return BRCTL_VERSION + 1;
 -      return -EINVAL;
 -}
 -
  #define RTC_IRQP_READ32               _IOR('p', 0x0b, compat_ulong_t)
  #define RTC_IRQP_SET32                _IOW('p', 0x0c, compat_ulong_t)
  #define RTC_EPOCH_READ32      _IOR('p', 0x0d, compat_ulong_t)
@@@ -1199,7 -1800,7 +1199,7 @@@ struct space_resv_32 
  /* just account for different alignment */
  static int compat_ioctl_preallocate(struct file *file, unsigned long arg)
  {
-       struct space_resv_32    __user *p32 = (void __user *)arg;
+       struct space_resv_32    __user *p32 = compat_ptr(arg);
        struct space_resv       __user *p = compat_alloc_user_space(sizeof(*p));
  
        if (copy_in_user(&p->l_type,    &p32->l_type,   sizeof(s16)) ||
@@@ -1378,6 -1979,18 +1378,6 @@@ COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAN
  COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
  COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
  #endif
 -/* Big T */
 -COMPATIBLE_IOCTL(TUNSETNOCSUM)
 -COMPATIBLE_IOCTL(TUNSETDEBUG)
 -COMPATIBLE_IOCTL(TUNSETPERSIST)
 -COMPATIBLE_IOCTL(TUNSETOWNER)
 -COMPATIBLE_IOCTL(TUNSETLINK)
 -COMPATIBLE_IOCTL(TUNSETGROUP)
 -COMPATIBLE_IOCTL(TUNGETFEATURES)
 -COMPATIBLE_IOCTL(TUNSETOFFLOAD)
 -COMPATIBLE_IOCTL(TUNSETTXFILTER)
 -COMPATIBLE_IOCTL(TUNGETSNDBUF)
 -COMPATIBLE_IOCTL(TUNSETSNDBUF)
  /* Big V */
  COMPATIBLE_IOCTL(VT_SETMODE)
  COMPATIBLE_IOCTL(VT_GETMODE)
@@@ -1419,6 -2032,30 +1419,6 @@@ COMPATIBLE_IOCTL(_IOW('p', 21, int[7])
  COMPATIBLE_IOCTL(MTIOCTOP)
  /* Socket level stuff */
  COMPATIBLE_IOCTL(FIOQSIZE)
 -COMPATIBLE_IOCTL(FIOSETOWN)
 -COMPATIBLE_IOCTL(SIOCSPGRP)
 -COMPATIBLE_IOCTL(FIOGETOWN)
 -COMPATIBLE_IOCTL(SIOCGPGRP)
 -COMPATIBLE_IOCTL(SIOCATMARK)
 -COMPATIBLE_IOCTL(SIOCSIFLINK)
 -COMPATIBLE_IOCTL(SIOCSIFENCAP)
 -COMPATIBLE_IOCTL(SIOCGIFENCAP)
 -COMPATIBLE_IOCTL(SIOCSIFNAME)
 -COMPATIBLE_IOCTL(SIOCSARP)
 -COMPATIBLE_IOCTL(SIOCGARP)
 -COMPATIBLE_IOCTL(SIOCDARP)
 -COMPATIBLE_IOCTL(SIOCSRARP)
 -COMPATIBLE_IOCTL(SIOCGRARP)
 -COMPATIBLE_IOCTL(SIOCDRARP)
 -COMPATIBLE_IOCTL(SIOCADDDLCI)
 -COMPATIBLE_IOCTL(SIOCDELDLCI)
 -COMPATIBLE_IOCTL(SIOCGMIIPHY)
 -COMPATIBLE_IOCTL(SIOCGMIIREG)
 -COMPATIBLE_IOCTL(SIOCSMIIREG)
 -COMPATIBLE_IOCTL(SIOCGIFVLAN)
 -COMPATIBLE_IOCTL(SIOCSIFVLAN)
 -COMPATIBLE_IOCTL(SIOCBRADDBR)
 -COMPATIBLE_IOCTL(SIOCBRDELBR)
  #ifdef CONFIG_BLOCK
  /* SG stuff */
  COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
@@@ -1674,6 -2311,22 +1674,6 @@@ COMPATIBLE_IOCTL(RAW_SETBIND
  COMPATIBLE_IOCTL(RAW_GETBIND)
  /* SMB ioctls which do not need any translations */
  COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
 -/* Little a */
 -COMPATIBLE_IOCTL(ATMSIGD_CTRL)
 -COMPATIBLE_IOCTL(ATMARPD_CTRL)
 -COMPATIBLE_IOCTL(ATMLEC_CTRL)
 -COMPATIBLE_IOCTL(ATMLEC_MCAST)
 -COMPATIBLE_IOCTL(ATMLEC_DATA)
 -COMPATIBLE_IOCTL(ATM_SETSC)
 -COMPATIBLE_IOCTL(SIOCSIFATMTCP)
 -COMPATIBLE_IOCTL(SIOCMKCLIP)
 -COMPATIBLE_IOCTL(ATMARP_MKIP)
 -COMPATIBLE_IOCTL(ATMARP_SETENTRY)
 -COMPATIBLE_IOCTL(ATMARP_ENCAP)
 -COMPATIBLE_IOCTL(ATMTCP_CREATE)
 -COMPATIBLE_IOCTL(ATMTCP_REMOVE)
 -COMPATIBLE_IOCTL(ATMMPC_CTRL)
 -COMPATIBLE_IOCTL(ATMMPC_DATA)
  /* Watchdog */
  COMPATIBLE_IOCTL(WDIOC_GETSUPPORT)
  COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
@@@ -1879,6 -2532,63 +1879,6 @@@ COMPATIBLE_IOCTL(JSIOCGBUTTONS
  COMPATIBLE_IOCTL(JSIOCGNAME(0))
  
  /* now things that need handlers */
 -#ifdef CONFIG_NET
 -HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32)
 -HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
 -HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc)
 -HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc)
 -HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFHWBROADCAST, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSHWTSTAMP, dev_ifsioc)
 -
 -/* ioctls used by appletalk ddp.c */
 -HANDLE_IOCTL(SIOCATALKDIFADDR, dev_ifsioc)
 -HANDLE_IOCTL(SIOCDIFADDR, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSARP, dev_ifsioc)
 -HANDLE_IOCTL(SIOCDARP, dev_ifsioc)
 -
 -HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc)
 -HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc)
 -HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc)
 -HANDLE_IOCTL(TUNSETIFF, dev_ifsioc)
 -HANDLE_IOCTL(TUNGETIFF, dev_ifsioc)
 -HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl)
 -HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl)
 -HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl)
 -HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl)
 -HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl)
 -HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl)
 -HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl)
 -HANDLE_IOCTL(SIOCADDRT, routing_ioctl)
 -HANDLE_IOCTL(SIOCDELRT, routing_ioctl)
 -HANDLE_IOCTL(SIOCBRADDIF, dev_ifsioc)
 -HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc)
 -/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
 -HANDLE_IOCTL(SIOCRTMSG, ret_einval)
 -HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
 -HANDLE_IOCTL(SIOCGSTAMPNS, do_siocgstampns)
 -#endif
  #ifdef CONFIG_BLOCK
  HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
  HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans)
@@@ -1903,6 -2613,31 +1903,6 @@@ HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioct
  /* One SMB ioctl needs translations. */
  #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
  HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
 -HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl)
 -HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl)
 -HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl)
 -HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl)
 -HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl)
 -HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl)
 -HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl)
 -HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl)
 -HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl)
 -HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl)
  /* block stuff */
  #ifdef CONFIG_BLOCK
  /* loop */
@@@ -1937,7 -2672,11 +1937,7 @@@ COMPATIBLE_IOCTL(USBDEVFS_IOCTL32
  HANDLE_IOCTL(I2C_FUNCS, w_long)
  HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
  HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
 -/* bridge */
 -HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
 -HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl)
  /* Not implemented in the native kernel */
 -IGNORE_IOCTL(SIOCGIFCOUNT)
  HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl)
  HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl)
  HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl)
@@@ -2063,7 -2802,7 +2063,7 @@@ asmlinkage long compat_sys_ioctl(unsign
  #else
        case FS_IOC_RESVSP:
        case FS_IOC_RESVSP64:
-               error = ioctl_preallocate(filp, (void __user *)arg);
+               error = ioctl_preallocate(filp, compat_ptr(arg));
                goto out_fput;
  #endif
  
                        goto found_handler;
        }
  
 -#ifdef CONFIG_NET
 -      if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) &&
 -          cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
 -              error = siocdevprivate_ioctl(fd, cmd, arg);
 -      } else
 -#endif
        {
                static int count;
  
diff --combined net/8021q/vlan.c
index d9cb020029b907578a3794c6db8e835d0db87c89,a29c5ab5815cef5887f99a381a89e9bc2c312b26..1483243edf1443a56fc44b053865989ae5161ce2
@@@ -41,7 -41,7 +41,7 @@@
  
  /* Global VLAN variables */
  
 -int vlan_net_id;
 +int vlan_net_id __read_mostly;
  
  /* Our listing of VLAN group(s) */
  static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
@@@ -140,7 -140,7 +140,7 @@@ static void vlan_rcu_free(struct rcu_he
        vlan_group_free(container_of(rcu, struct vlan_group, rcu));
  }
  
 -void unregister_vlan_dev(struct net_device *dev)
 +void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
  {
        struct vlan_dev_info *vlan = vlan_dev_info(dev);
        struct net_device *real_dev = vlan->real_dev;
        if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
                ops->ndo_vlan_rx_kill_vid(real_dev, vlan_id);
  
 -      vlan_group_set_device(grp, vlan_id, NULL);
        grp->nr_vlans--;
  
 -      synchronize_net();
 +      vlan_group_set_device(grp, vlan_id, NULL);
 +      if (!grp->killall)
 +              synchronize_net();
  
 -      unregister_netdevice(dev);
 +      unregister_netdevice_queue(dev, head);
  
        /* If the group is now empty, kill off the group. */
        if (grp->nr_vlans == 0) {
@@@ -282,8 -281,11 +282,11 @@@ out_uninit_applicant
        if (ngrp)
                vlan_gvrp_uninit_applicant(real_dev);
  out_free_group:
-       if (ngrp)
-               vlan_group_free(ngrp);
+       if (ngrp) {
+               hlist_del_rcu(&ngrp->hlist);
+               /* Free the group, after all cpu's are done. */
+               call_rcu(&ngrp->rcu, vlan_rcu_free);
+       }
        return err;
  }
  
@@@ -428,7 -430,6 +431,7 @@@ static int vlan_device_event(struct not
        struct vlan_group *grp;
        int i, flgs;
        struct net_device *vlandev;
 +      LIST_HEAD(list);
  
        if (is_vlan_dev(dev))
                __vlan_device_event(dev, event);
  
        case NETDEV_UNREGISTER:
                /* Delete all VLANs for this dev. */
 +              grp->killall = 1;
 +
                for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
                        vlandev = vlan_group_get_device(grp, i);
                        if (!vlandev)
                        if (grp->nr_vlans == 1)
                                i = VLAN_GROUP_ARRAY_LEN;
  
 -                      unregister_vlan_dev(vlandev);
 +                      unregister_vlan_dev(vlandev, &list);
                }
 +              unregister_netdevice_many(&list);
                break;
        }
  
@@@ -647,7 -645,7 +650,7 @@@ static int vlan_ioctl_handler(struct ne
                err = -EPERM;
                if (!capable(CAP_NET_ADMIN))
                        break;
 -              unregister_vlan_dev(dev);
 +              unregister_vlan_dev(dev, NULL);
                err = 0;
                break;
  
diff --combined net/core/skbuff.c
index 941bac907484de1a82de69b82ff78b9367e70362,ec85681a7dd83765878cd6c791538a7941732178..739b8f4dd327b76d1da7d5ef2ae3289b2d543e37
@@@ -493,9 -493,6 +493,9 @@@ int skb_recycle_check(struct sk_buff *s
  {
        struct skb_shared_info *shinfo;
  
 +      if (irqs_disabled())
 +              return 0;
 +
        if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE)
                return 0;
  
@@@ -2704,7 -2701,8 +2704,8 @@@ int skb_gro_receive(struct sk_buff **he
  
                NAPI_GRO_CB(skb)->free = 1;
                goto done;
-       }
+       } else if (skb_gro_len(p) != pinfo->gso_size)
+               return -E2BIG;
  
        headroom = skb_headroom(p);
        nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p));
diff --combined net/wireless/core.c
index 02835172b2279fc33c335d83db5e1b03e62886f7,a595f712b5bf3edf09e3f97a6dd10c118e0341a3..45bd63ad2eb28052ef59c585249a4add53b3bfcb
@@@ -14,6 -14,7 +14,7 @@@
  #include <linux/device.h>
  #include <linux/etherdevice.h>
  #include <linux/rtnetlink.h>
+ #include <linux/sched.h>
  #include <net/genetlink.h>
  #include <net/cfg80211.h>
  #include "nl80211.h"
@@@ -21,7 -22,6 +22,7 @@@
  #include "sysfs.h"
  #include "debugfs.h"
  #include "wext-compat.h"
 +#include "ethtool.h"
  
  /* name for sysfs, %d is appended */
  #define PHY_NAME "phy"
@@@ -359,10 -359,6 +360,10 @@@ struct wiphy *wiphy_new(const struct cf
        INIT_LIST_HEAD(&rdev->bss_list);
        INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
  
 +#ifdef CONFIG_CFG80211_WEXT
 +      rdev->wiphy.wext = &cfg80211_wext_handler;
 +#endif
 +
        device_initialize(&rdev->wiphy.dev);
        rdev->wiphy.dev.class = &ieee80211_class;
        rdev->wiphy.dev.platform_data = rdev;
@@@ -546,7 -542,7 +547,7 @@@ void wiphy_unregister(struct wiphy *wip
         * First remove the hardware from everywhere, this makes
         * it impossible to find from userspace.
         */
 -      cfg80211_debugfs_rdev_del(rdev);
 +      debugfs_remove_recursive(rdev->wiphy.debugfsdir);
        list_del(&rdev->list);
  
        /*
  
        cfg80211_rdev_list_generation++;
        device_del(&rdev->wiphy.dev);
 -      debugfs_remove(rdev->wiphy.debugfsdir);
  
        mutex_unlock(&cfg80211_mutex);
  
@@@ -629,10 -626,6 +630,10 @@@ static void wdev_cleanup_work(struct wo
        dev_put(wdev->netdev);
  }
  
 +static struct device_type wiphy_type = {
 +      .name   = "wlan",
 +};
 +
  static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
                                         unsigned long state,
                                         void *ndev)
        WARN_ON(wdev->iftype == NL80211_IFTYPE_UNSPECIFIED);
  
        switch (state) {
 +      case NETDEV_POST_INIT:
 +              SET_NETDEV_DEVTYPE(dev, &wiphy_type);
 +              break;
        case NETDEV_REGISTER:
                /*
                 * NB: cannot take rdev->mtx here because this may be
                wdev->netdev = dev;
                wdev->sme_state = CFG80211_SME_IDLE;
                mutex_unlock(&rdev->devlist_mtx);
 -#ifdef CONFIG_WIRELESS_EXT
 -              if (!dev->wireless_handlers)
 -                      dev->wireless_handlers = &cfg80211_wext_handler;
 +#ifdef CONFIG_CFG80211_WEXT
                wdev->wext.default_key = -1;
                wdev->wext.default_mgmt_key = -1;
                wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
                                wdev->wext.ps = false;
                        }
  #endif
 +              if (!dev->ethtool_ops)
 +                      dev->ethtool_ops = &cfg80211_ethtool_ops;
                break;
        case NETDEV_GOING_DOWN:
                switch (wdev->iftype) {
                        break;
                case NL80211_IFTYPE_STATION:
                        wdev_lock(wdev);
 -#ifdef CONFIG_WIRELESS_EXT
 +#ifdef CONFIG_CFG80211_WEXT
                        kfree(wdev->wext.ie);
                        wdev->wext.ie = NULL;
                        wdev->wext.ie_len = 0;
                        mutex_unlock(&rdev->devlist_mtx);
                        dev_put(dev);
                }
 -#ifdef CONFIG_WIRELESS_EXT
 +#ifdef CONFIG_CFG80211_WEXT
                cfg80211_lock_rdev(rdev);
                mutex_lock(&rdev->devlist_mtx);
                wdev_lock(wdev);
                        sysfs_remove_link(&dev->dev.kobj, "phy80211");
                        list_del_init(&wdev->list);
                        rdev->devlist_generation++;
 -#ifdef CONFIG_WIRELESS_EXT
 +#ifdef CONFIG_CFG80211_WEXT
                        kfree(wdev->wext.keys);
  #endif
                }