]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 29 Jun 2012 16:42:14 +0000 (12:42 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 29 Jun 2012 16:42:14 +0000 (12:42 -0400)
Conflicts:
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c

13 files changed:
1  2 
MAINTAINERS
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
drivers/net/wireless/brcm80211/brcmsmac/main.c
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sta_cmd.c
drivers/net/wireless/mwifiex/sta_cmdresp.c
drivers/net/wireless/rtlwifi/cam.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/ti/wlcore/tx.c
net/wireless/nl80211.c

diff --combined MAINTAINERS
index 5095340716cf34c68b3a23df4c67e28d9e4ea190,fe6dd3d7d2c410ede875ec3c0e3f7c97355d7cdc..d350dae2ce1c059b1de4c44d6b883cb38af6c0ad
@@@ -579,7 -579,7 +579,7 @@@ F: drivers/net/appletalk
  F:    net/appletalk/
  
  ARASAN COMPACT FLASH PATA CONTROLLER
 -M:    Viresh Kumar <viresh.kumar@st.com>
 +M:     Viresh Kumar <viresh.linux@gmail.com>
  L:    linux-ide@vger.kernel.org
  S:    Maintained
  F:    include/linux/pata_arasan_cf_data.h
@@@ -1077,7 -1077,7 +1077,7 @@@ F:      drivers/media/video/s5p-fimc
  ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
  M:    Kyungmin Park <kyungmin.park@samsung.com>
  M:    Kamil Debski <k.debski@samsung.com>
 -M:     Jeongtae Park <jtp.park@samsung.com>
 +M:    Jeongtae Park <jtp.park@samsung.com>
  L:    linux-arm-kernel@lists.infradead.org
  L:    linux-media@vger.kernel.org
  S:    Maintained
@@@ -1595,6 -1595,7 +1595,7 @@@ M:      Arend van Spriel <arend@broadcom.com
  M:    Franky (Zhenhui) Lin <frankyl@broadcom.com>
  M:    Kan Yan <kanyan@broadcom.com>
  L:    linux-wireless@vger.kernel.org
+ L:    brcm80211-dev-list@broadcom.com
  S:    Supported
  F:    drivers/net/wireless/brcm80211/
  
@@@ -1646,11 -1647,11 +1647,11 @@@ S:   Maintaine
  F:    drivers/gpio/gpio-bt8xx.c
  
  BTRFS FILE SYSTEM
 -M:    Chris Mason <chris.mason@oracle.com>
 +M:    Chris Mason <chris.mason@fusionio.com>
  L:    linux-btrfs@vger.kernel.org
  W:    http://btrfs.wiki.kernel.org/
  Q:    http://patchwork.kernel.org/project/linux-btrfs/list/
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git
  S:    Maintained
  F:    Documentation/filesystems/btrfs.txt
  F:    fs/btrfs/
@@@ -1743,10 -1744,10 +1744,10 @@@ F:   include/linux/can/platform
  CAPABILITIES
  M:    Serge Hallyn <serge.hallyn@canonical.com>
  L:    linux-security-module@vger.kernel.org
 -S:    Supported       
 +S:    Supported
  F:    include/linux/capability.h
  F:    security/capability.c
 -F:    security/commoncap.c 
 +F:    security/commoncap.c
  F:    kernel/capability.c
  
  CELL BROADBAND ENGINE ARCHITECTURE
@@@ -2149,11 -2150,11 +2150,11 @@@ S:   Orpha
  F:    drivers/net/wan/pc300*
  
  CYTTSP TOUCHSCREEN DRIVER
 -M:      Javier Martinez Canillas <javier@dowhile0.org>
 -L:      linux-input@vger.kernel.org
 -S:      Maintained
 -F:      drivers/input/touchscreen/cyttsp*
 -F:      include/linux/input/cyttsp.h
 +M:    Javier Martinez Canillas <javier@dowhile0.org>
 +L:    linux-input@vger.kernel.org
 +S:    Maintained
 +F:    drivers/input/touchscreen/cyttsp*
 +F:    include/linux/input/cyttsp.h
  
  DAMA SLAVE for AX.25
  M:    Joerg Reuter <jreuter@yaina.de>
@@@ -2273,7 -2274,7 +2274,7 @@@ F:      include/linux/device-mapper.
  F:    include/linux/dm-*.h
  
  DIOLAN U2C-12 I2C DRIVER
 -M:    Guenter Roeck <guenter.roeck@ericsson.com>
 +M:    Guenter Roeck <linux@roeck-us.net>
  L:    linux-i2c@vger.kernel.org
  S:    Maintained
  F:    drivers/i2c/busses/i2c-diolan-u2c.c
@@@ -2933,13 -2934,6 +2934,13 @@@ F:    Documentation/power/freezing-of-task
  F:    include/linux/freezer.h
  F:    kernel/freezer.c
  
 +FRONTSWAP API
 +M:    Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 +L:    linux-kernel@vger.kernel.org
 +S:    Maintained
 +F:    mm/frontswap.c
 +F:    include/linux/frontswap.h
 +
  FS-CACHE: LOCAL CACHING FOR NETWORK FILESYSTEMS
  M:    David Howells <dhowells@redhat.com>
  L:    linux-cachefs@redhat.com
@@@ -3148,7 -3142,7 +3149,7 @@@ F:      drivers/tty/hvc
  
  HARDWARE MONITORING
  M:    Jean Delvare <khali@linux-fr.org>
 -M:    Guenter Roeck <guenter.roeck@ericsson.com>
 +M:    Guenter Roeck <linux@roeck-us.net>
  L:    lm-sensors@lm-sensors.org
  W:    http://www.lm-sensors.org/
  T:    quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/
@@@ -4106,8 -4100,6 +4107,8 @@@ F:      drivers/scsi/53c700
  LED SUBSYSTEM
  M:    Bryan Wu <bryan.wu@canonical.com>
  M:    Richard Purdie <rpurdie@rpsys.net>
 +L:    linux-leds@vger.kernel.org
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds.git
  S:    Maintained
  F:    drivers/leds/
  F:    include/linux/leds.h
@@@ -4425,13 -4417,6 +4426,13 @@@ S:    Orpha
  F:    drivers/video/matrox/matroxfb_*
  F:    include/linux/matroxfb.h
  
 +MAX16065 HARDWARE MONITOR DRIVER
 +M:    Guenter Roeck <linux@roeck-us.net>
 +L:    lm-sensors@lm-sensors.org
 +S:    Maintained
 +F:    Documentation/hwmon/max16065
 +F:    drivers/hwmon/max16065.c
 +
  MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
  M:    "Hans J. Koch" <hjk@hansjkoch.de>
  L:    lm-sensors@lm-sensors.org
@@@ -5170,7 -5155,7 +5171,7 @@@ F:      drivers/leds/leds-pca9532.
  F:    include/linux/leds-pca9532.h
  
  PCA9541 I2C BUS MASTER SELECTOR DRIVER
 -M:    Guenter Roeck <guenter.roeck@ericsson.com>
 +M:    Guenter Roeck <linux@roeck-us.net>
  L:    linux-i2c@vger.kernel.org
  S:    Maintained
  F:    drivers/i2c/muxes/i2c-mux-pca9541.c
@@@ -5190,7 -5175,7 +5191,7 @@@ S:      Maintaine
  F:    drivers/firmware/pcdp.*
  
  PCI ERROR RECOVERY
 -M:     Linas Vepstas <linasvepstas@gmail.com>
 +M:    Linas Vepstas <linasvepstas@gmail.com>
  L:    linux-pci@vger.kernel.org
  S:    Supported
  F:    Documentation/PCI/pci-error-recovery.txt
@@@ -5296,7 -5281,7 +5297,7 @@@ S:      Maintaine
  F:    drivers/pinctrl/
  
  PIN CONTROLLER - ST SPEAR
 -M:    Viresh Kumar <viresh.kumar@st.com>
 +M:     Viresh Kumar <viresh.linux@gmail.com>
  L:    spear-devel@list.st.com
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  W:    http://www.st.com/spear
@@@ -5320,7 -5305,7 +5321,7 @@@ F:      drivers/video/fb-puv3.
  F:    drivers/rtc/rtc-puv3.c
  
  PMBUS HARDWARE MONITORING DRIVERS
 -M:    Guenter Roeck <guenter.roeck@ericsson.com>
 +M:    Guenter Roeck <linux@roeck-us.net>
  L:    lm-sensors@lm-sensors.org
  W:    http://www.lm-sensors.org/
  W:    http://www.roeck-us.net/linux/drivers/
@@@ -5873,7 -5858,7 +5874,7 @@@ S:      Maintaine
  F:    drivers/tty/serial
  
  SYNOPSYS DESIGNWARE DMAC DRIVER
 -M:    Viresh Kumar <viresh.kumar@st.com>
 +M:     Viresh Kumar <viresh.linux@gmail.com>
  S:    Maintained
  F:    include/linux/dw_dmac.h
  F:    drivers/dma/dw_dmac_regs.h
@@@ -6021,7 -6006,7 +6022,7 @@@ S:      Maintaine
  F:    drivers/mmc/host/sdhci-s3c.c
  
  SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER
 -M:    Viresh Kumar <viresh.kumar@st.com>
 +M:     Viresh Kumar <viresh.linux@gmail.com>
  L:    spear-devel@list.st.com
  L:    linux-mmc@vger.kernel.org
  S:    Maintained
@@@ -6377,7 -6362,7 +6378,7 @@@ S:      Maintaine
  F:    include/linux/compiler.h
  
  SPEAR PLATFORM SUPPORT
 -M:    Viresh Kumar <viresh.kumar@st.com>
 +M:     Viresh Kumar <viresh.linux@gmail.com>
  M:    Shiraz Hashim <shiraz.hashim@st.com>
  L:    spear-devel@list.st.com
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -6386,7 -6371,7 +6387,7 @@@ S:      Maintaine
  F:    arch/arm/plat-spear/
  
  SPEAR13XX MACHINE SUPPORT
 -M:    Viresh Kumar <viresh.kumar@st.com>
 +M:     Viresh Kumar <viresh.linux@gmail.com>
  M:    Shiraz Hashim <shiraz.hashim@st.com>
  L:    spear-devel@list.st.com
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -6395,7 -6380,7 +6396,7 @@@ S:      Maintaine
  F:    arch/arm/mach-spear13xx/
  
  SPEAR3XX MACHINE SUPPORT
 -M:    Viresh Kumar <viresh.kumar@st.com>
 +M:     Viresh Kumar <viresh.linux@gmail.com>
  M:    Shiraz Hashim <shiraz.hashim@st.com>
  L:    spear-devel@list.st.com
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@@ -6406,7 -6391,7 +6407,7 @@@ F:      arch/arm/mach-spear3xx
  SPEAR6XX MACHINE SUPPORT
  M:    Rajeev Kumar <rajeev-dlh.kumar@st.com>
  M:    Shiraz Hashim <shiraz.hashim@st.com>
 -M:    Viresh Kumar <viresh.kumar@st.com>
 +M:     Viresh Kumar <viresh.linux@gmail.com>
  L:    spear-devel@list.st.com
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  W:    http://www.st.com/spear
@@@ -6414,7 -6399,7 +6415,7 @@@ S:      Maintaine
  F:    arch/arm/mach-spear6xx/
  
  SPEAR CLOCK FRAMEWORK SUPPORT
 -M:    Viresh Kumar <viresh.kumar@st.com>
 +M:     Viresh Kumar <viresh.linux@gmail.com>
  L:    spear-devel@list.st.com
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  W:    http://www.st.com/spear
@@@ -7315,11 -7300,11 +7316,11 @@@ F:   Documentation/DocBook/uio-howto.tmp
  F:    drivers/uio/
  F:    include/linux/uio*.h
  
 -UTIL-LINUX-NG PACKAGE
 +UTIL-LINUX PACKAGE
  M:    Karel Zak <kzak@redhat.com>
 -L:    util-linux-ng@vger.kernel.org
 -W:    http://kernel.org/~kzak/util-linux-ng/
 -T:    git git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git
 +L:    util-linux@vger.kernel.org
 +W:    http://en.wikipedia.org/wiki/Util-linux
 +T:    git git://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
  S:    Maintained
  
  UVESAFB DRIVER
@@@ -7421,7 -7406,7 +7422,7 @@@ F:      include/linux/vlynq.
  
  VME SUBSYSTEM
  M:    Martyn Welch <martyn.welch@ge.com>
 -M:    Manohar Vanga <manohar.vanga@cern.ch>
 +M:    Manohar Vanga <manohar.vanga@gmail.com>
  M:    Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  L:    devel@driverdev.osuosl.org
  S:    Maintained
index b023766954a6147eb7859310746f197a2b565689,5c868bac1c1c86a1c5b730fc549a4bbd92a98996..472f2ef5c65237b9bb52f577723a3fed734a5041
@@@ -31,6 -31,8 +31,8 @@@
  #include <linux/firmware.h>
  #include <linux/module.h>
  #include <linux/bcma/bcma.h>
+ #include <linux/debugfs.h>
+ #include <linux/vmalloc.h>
  #include <asm/unaligned.h>
  #include <defs.h>
  #include <brcmu_wifi.h>
@@@ -48,6 -50,9 +50,9 @@@
  
  #define CBUF_LEN      (128)
  
+ /* Device console log buffer state */
+ #define CONSOLE_BUFFER_MAX    2024
  struct rte_log_le {
        __le32 buf;             /* Can't be pointer on (64-bit) hosts */
        __le32 buf_size;
@@@ -281,7 -286,7 +286,7 @@@ struct rte_console 
   * Shared structure between dongle and the host.
   * The structure contains pointers to trap or assert information.
   */
- #define SDPCM_SHARED_VERSION       0x0002
+ #define SDPCM_SHARED_VERSION       0x0003
  #define SDPCM_SHARED_VERSION_MASK  0x00FF
  #define SDPCM_SHARED_ASSERT_BUILT  0x0100
  #define SDPCM_SHARED_ASSERT        0x0200
@@@ -428,6 -433,29 +433,29 @@@ struct brcmf_console 
        u8 *buf;                /* Log buffer (host copy) */
        uint last;              /* Last buffer read index */
  };
+ struct brcmf_trap_info {
+       __le32          type;
+       __le32          epc;
+       __le32          cpsr;
+       __le32          spsr;
+       __le32          r0;     /* a1 */
+       __le32          r1;     /* a2 */
+       __le32          r2;     /* a3 */
+       __le32          r3;     /* a4 */
+       __le32          r4;     /* v1 */
+       __le32          r5;     /* v2 */
+       __le32          r6;     /* v3 */
+       __le32          r7;     /* v4 */
+       __le32          r8;     /* v5 */
+       __le32          r9;     /* sb/v6 */
+       __le32          r10;    /* sl/v7 */
+       __le32          r11;    /* fp/v8 */
+       __le32          r12;    /* ip */
+       __le32          r13;    /* sp */
+       __le32          r14;    /* lr */
+       __le32          pc;     /* r15 */
+ };
  #endif                                /* DEBUG */
  
  struct sdpcm_shared {
        u32 console_addr;       /* Address of struct rte_console */
        u32 msgtrace_addr;
        u8 tag[32];
+       u32 brpt_addr;
  };
  
  struct sdpcm_shared_le {
        __le32 console_addr;    /* Address of struct rte_console */
        __le32 msgtrace_addr;
        u8 tag[32];
+       __le32 brpt_addr;
  };
  
  
@@@ -2471,7 -2501,7 +2501,7 @@@ clkwait
                int ret, i;
  
                ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
 -                      SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf,
 +                      SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf,
                        (u32) bus->ctrl_frame_len);
  
                if (ret < 0) {
@@@ -2953,13 -2983,311 +2983,311 @@@ brcmf_sdbrcm_bus_txctl(struct device *d
  }
  
  #ifdef DEBUG
+ static inline bool brcmf_sdio_valid_shared_address(u32 addr)
+ {
+       return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
+ }
+ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
+                                struct sdpcm_shared *sh)
+ {
+       u32 addr;
+       int rv;
+       u32 shaddr = 0;
+       struct sdpcm_shared_le sh_le;
+       __le32 addr_le;
+       shaddr = bus->ramsize - 4;
+       /*
+        * Read last word in socram to determine
+        * address of sdpcm_shared structure
+        */
+       rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
+                                  (u8 *)&addr_le, 4);
+       if (rv < 0)
+               return rv;
+       addr = le32_to_cpu(addr_le);
+       brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr);
+       /*
+        * Check if addr is valid.
+        * NVRAM length at the end of memory should have been overwritten.
+        */
+       if (!brcmf_sdio_valid_shared_address(addr)) {
+                       brcmf_dbg(ERROR, "invalid sdpcm_shared address 0x%08X\n",
+                                 addr);
+                       return -EINVAL;
+       }
+       /* Read hndrte_shared structure */
+       rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le,
+                                  sizeof(struct sdpcm_shared_le));
+       if (rv < 0)
+               return rv;
+       /* Endianness */
+       sh->flags = le32_to_cpu(sh_le.flags);
+       sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
+       sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
+       sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
+       sh->assert_line = le32_to_cpu(sh_le.assert_line);
+       sh->console_addr = le32_to_cpu(sh_le.console_addr);
+       sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
+       if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) {
+               brcmf_dbg(ERROR,
+                         "sdpcm_shared version mismatch: dhd %d dongle %d\n",
+                         SDPCM_SHARED_VERSION,
+                         sh->flags & SDPCM_SHARED_VERSION_MASK);
+               return -EPROTO;
+       }
+       return 0;
+ }
+ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
+                                  struct sdpcm_shared *sh, char __user *data,
+                                  size_t count)
+ {
+       u32 addr, console_ptr, console_size, console_index;
+       char *conbuf = NULL;
+       __le32 sh_val;
+       int rv;
+       loff_t pos = 0;
+       int nbytes = 0;
+       /* obtain console information from device memory */
+       addr = sh->console_addr + offsetof(struct rte_console, log_le);
+       rv = brcmf_sdbrcm_membytes(bus, false, addr,
+                       (u8 *)&sh_val, sizeof(u32));
+       if (rv < 0)
+               return rv;
+       console_ptr = le32_to_cpu(sh_val);
+       addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size);
+       rv = brcmf_sdbrcm_membytes(bus, false, addr,
+                       (u8 *)&sh_val, sizeof(u32));
+       if (rv < 0)
+               return rv;
+       console_size = le32_to_cpu(sh_val);
+       addr = sh->console_addr + offsetof(struct rte_console, log_le.idx);
+       rv = brcmf_sdbrcm_membytes(bus, false, addr,
+                       (u8 *)&sh_val, sizeof(u32));
+       if (rv < 0)
+               return rv;
+       console_index = le32_to_cpu(sh_val);
+       /* allocate buffer for console data */
+       if (console_size <= CONSOLE_BUFFER_MAX)
+               conbuf = vzalloc(console_size+1);
+       if (!conbuf)
+               return -ENOMEM;
+       /* obtain the console data from device */
+       conbuf[console_size] = '\0';
+       rv = brcmf_sdbrcm_membytes(bus, false, console_ptr, (u8 *)conbuf,
+                                  console_size);
+       if (rv < 0)
+               goto done;
+       rv = simple_read_from_buffer(data, count, &pos,
+                                    conbuf + console_index,
+                                    console_size - console_index);
+       if (rv < 0)
+               goto done;
+       nbytes = rv;
+       if (console_index > 0) {
+               pos = 0;
+               rv = simple_read_from_buffer(data+nbytes, count, &pos,
+                                            conbuf, console_index - 1);
+               if (rv < 0)
+                       goto done;
+               rv += nbytes;
+       }
+ done:
+       vfree(conbuf);
+       return rv;
+ }
+ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
+                               char __user *data, size_t count)
+ {
+       int error, res;
+       char buf[350];
+       struct brcmf_trap_info tr;
+       int nbytes;
+       loff_t pos = 0;
+       if ((sh->flags & SDPCM_SHARED_TRAP) == 0)
+               return 0;
+       error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
+                                     sizeof(struct brcmf_trap_info));
+       if (error < 0)
+               return error;
+       nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
+       if (nbytes < 0)
+               return nbytes;
+       res = scnprintf(buf, sizeof(buf),
+                       "dongle trap info: type 0x%x @ epc 0x%08x\n"
+                       "  cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
+                       "  lr   0x%08x pc   0x%08x offset 0x%x\n"
+                       "  r0   0x%08x r1   0x%08x r2 0x%08x r3 0x%08x\n"
+                       "  r4   0x%08x r5   0x%08x r6 0x%08x r7 0x%08x\n",
+                       le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
+                       le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
+                       le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
+                       le32_to_cpu(tr.pc), sh->trap_addr,
+                       le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
+                       le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
+                       le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
+                       le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
+       error = simple_read_from_buffer(data+nbytes, count, &pos, buf, res);
+       if (error < 0)
+               return error;
+       nbytes += error;
+       return nbytes;
+ }
+ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
+                                 struct sdpcm_shared *sh, char __user *data,
+                                 size_t count)
+ {
+       int error = 0;
+       char buf[200];
+       char file[80] = "?";
+       char expr[80] = "<???>";
+       int res;
+       loff_t pos = 0;
+       if ((sh->flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
+               brcmf_dbg(INFO, "firmware not built with -assert\n");
+               return 0;
+       } else if ((sh->flags & SDPCM_SHARED_ASSERT) == 0) {
+               brcmf_dbg(INFO, "no assert in dongle\n");
+               return 0;
+       }
+       if (sh->assert_file_addr != 0) {
+               error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr,
+                                             (u8 *)file, 80);
+               if (error < 0)
+                       return error;
+       }
+       if (sh->assert_exp_addr != 0) {
+               error = brcmf_sdbrcm_membytes(bus, false, sh->assert_exp_addr,
+                                             (u8 *)expr, 80);
+               if (error < 0)
+                       return error;
+       }
+       res = scnprintf(buf, sizeof(buf),
+                       "dongle assert: %s:%d: assert(%s)\n",
+                       file, sh->assert_line, expr);
+       return simple_read_from_buffer(data, count, &pos, buf, res);
+ }
+ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus)
+ {
+       int error;
+       struct sdpcm_shared sh;
+       down(&bus->sdsem);
+       error = brcmf_sdio_readshared(bus, &sh);
+       up(&bus->sdsem);
+       if (error < 0)
+               return error;
+       if ((sh.flags & SDPCM_SHARED_ASSERT_BUILT) == 0)
+               brcmf_dbg(INFO, "firmware not built with -assert\n");
+       else if (sh.flags & SDPCM_SHARED_ASSERT)
+               brcmf_dbg(ERROR, "assertion in dongle\n");
+       if (sh.flags & SDPCM_SHARED_TRAP)
+               brcmf_dbg(ERROR, "firmware trap in dongle\n");
+       return 0;
+ }
+ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data,
+                                 size_t count, loff_t *ppos)
+ {
+       int error = 0;
+       struct sdpcm_shared sh;
+       int nbytes = 0;
+       loff_t pos = *ppos;
+       if (pos != 0)
+               return 0;
+       down(&bus->sdsem);
+       error = brcmf_sdio_readshared(bus, &sh);
+       if (error < 0)
+               goto done;
+       error = brcmf_sdio_assert_info(bus, &sh, data, count);
+       if (error < 0)
+               goto done;
+       nbytes = error;
+       error = brcmf_sdio_trap_info(bus, &sh, data, count);
+       if (error < 0)
+               goto done;
+       error += nbytes;
+       *ppos += error;
+ done:
+       up(&bus->sdsem);
+       return error;
+ }
+ static ssize_t brcmf_sdio_forensic_read(struct file *f, char __user *data,
+                                       size_t count, loff_t *ppos)
+ {
+       struct brcmf_sdio *bus = f->private_data;
+       int res;
+       res = brcmf_sdbrcm_died_dump(bus, data, count, ppos);
+       if (res > 0)
+               *ppos += res;
+       return (ssize_t)res;
+ }
+ static const struct file_operations brcmf_sdio_forensic_ops = {
+       .owner = THIS_MODULE,
+       .open = simple_open,
+       .read = brcmf_sdio_forensic_read
+ };
  static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
  {
        struct brcmf_pub *drvr = bus->sdiodev->bus_if->drvr;
+       struct dentry *dentry = brcmf_debugfs_get_devdir(drvr);
  
+       if (IS_ERR_OR_NULL(dentry))
+               return;
+       debugfs_create_file("forensics", S_IRUGO, dentry, bus,
+                           &brcmf_sdio_forensic_ops);
        brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
  }
  #else
+ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus)
+ {
+       return 0;
+ }
  static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
  {
  }
@@@ -2991,11 -3319,13 +3319,13 @@@ brcmf_sdbrcm_bus_rxctl(struct device *d
                          rxlen, msglen);
        } else if (timeleft == 0) {
                brcmf_dbg(ERROR, "resumed on timeout\n");
+               brcmf_sdbrcm_checkdied(bus);
        } else if (pending) {
                brcmf_dbg(CTL, "cancelled\n");
                return -ERESTARTSYS;
        } else {
                brcmf_dbg(CTL, "resumed for unknown reason?\n");
+               brcmf_sdbrcm_checkdied(bus);
        }
  
        if (rxlen)
        return rxlen ? (int)rxlen : -ETIMEDOUT;
  }
  
- static int brcmf_sdbrcm_downloadvars(struct brcmf_sdio *bus, void *arg, int len)
- {
-       int bcmerror = 0;
-       brcmf_dbg(TRACE, "Enter\n");
-       /* Basic sanity checks */
-       if (bus->sdiodev->bus_if->drvr_up) {
-               bcmerror = -EISCONN;
-               goto err;
-       }
-       if (!len) {
-               bcmerror = -EOVERFLOW;
-               goto err;
-       }
-       /* Free the old ones and replace with passed variables */
-       kfree(bus->vars);
-       bus->vars = kmalloc(len, GFP_ATOMIC);
-       bus->varsz = bus->vars ? len : 0;
-       if (bus->vars == NULL) {
-               bcmerror = -ENOMEM;
-               goto err;
-       }
-       /* Copy the passed variables, which should include the
-                terminating double-null */
-       memcpy(bus->vars, arg, bus->varsz);
- err:
-       return bcmerror;
- }
  static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
  {
        int bcmerror = 0;
-       u32 varsize;
        u32 varaddr;
-       u8 *vbuffer;
        u32 varsizew;
        __le32 varsizew_le;
  #ifdef DEBUG
  
        /* Even if there are no vars are to be written, we still
                 need to set the ramsize. */
-       varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
-       varaddr = (bus->ramsize - 4) - varsize;
+       varaddr = (bus->ramsize - 4) - bus->varsz;
  
        if (bus->vars) {
-               vbuffer = kzalloc(varsize, GFP_ATOMIC);
-               if (!vbuffer)
-                       return -ENOMEM;
-               memcpy(vbuffer, bus->vars, bus->varsz);
                /* Write the vars list */
-               bcmerror =
-                   brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
+               bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr,
+                                                bus->vars, bus->varsz);
  #ifdef DEBUG
                /* Verify NVRAM bytes */
-               brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
-               nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
-               if (!nvram_ularray) {
-                       kfree(vbuffer);
+               brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n",
+                         bus->varsz);
+               nvram_ularray = kmalloc(bus->varsz, GFP_ATOMIC);
+               if (!nvram_ularray)
                        return -ENOMEM;
-               }
  
                /* Upload image to verify downloaded contents. */
-               memset(nvram_ularray, 0xaa, varsize);
+               memset(nvram_ularray, 0xaa, bus->varsz);
  
                /* Read the vars list to temp buffer for comparison */
-               bcmerror =
-                   brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray,
-                                    varsize);
+               bcmerror = brcmf_sdbrcm_membytes(bus, false, varaddr,
+                                                nvram_ularray, bus->varsz);
                if (bcmerror) {
                        brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n",
-                                 bcmerror, varsize, varaddr);
+                                 bcmerror, bus->varsz, varaddr);
                }
                /* Compare the org NVRAM with the one read from RAM */
-               if (memcmp(vbuffer, nvram_ularray, varsize))
+               if (memcmp(bus->vars, nvram_ularray, bus->varsz))
                        brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n");
                else
                        brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
  
                kfree(nvram_ularray);
  #endif                                /* DEBUG */
-               kfree(vbuffer);
        }
  
        /* adjust to the user specified RAM */
        brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize);
        brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n",
-                 varaddr, varsize);
-       varsize = ((bus->ramsize - 4) - varaddr);
+                 varaddr, bus->varsz);
  
        /*
         * Determine the length token:
                varsizew = 0;
                varsizew_le = cpu_to_le32(0);
        } else {
-               varsizew = varsize / 4;
+               varsizew = bus->varsz / 4;
                varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
                varsizew_le = cpu_to_le32(varsizew);
        }
  
        brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n",
-                 varsize, varsizew);
+                 bus->varsz, varsizew);
  
        /* Write the length token to the last word */
        bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4),
   * by two NULs.
  */
  
- static uint brcmf_process_nvram_vars(char *varbuf, uint len)
+ static int brcmf_process_nvram_vars(struct brcmf_sdio *bus)
  {
+       char *varbuf;
        char *dp;
        bool findNewline;
        int column;
-       uint buf_len, n;
+       int ret = 0;
+       uint buf_len, n, len;
+       len = bus->firmware->size;
+       varbuf = vmalloc(len);
+       if (!varbuf)
+               return -ENOMEM;
  
+       memcpy(varbuf, bus->firmware->data, len);
        dp = varbuf;
  
        findNewline = false;
                column++;
        }
        buf_len = dp - varbuf;
        while (dp < varbuf + n)
                *dp++ = 0;
  
-       return buf_len;
+       kfree(bus->vars);
+       /* roundup needed for download to device */
+       bus->varsz = roundup(buf_len + 1, 4);
+       bus->vars = kmalloc(bus->varsz, GFP_KERNEL);
+       if (bus->vars == NULL) {
+               bus->varsz = 0;
+               ret = -ENOMEM;
+               goto err;
+       }
+       /* copy the processed variables and add null termination */
+       memcpy(bus->vars, varbuf, buf_len);
+       bus->vars[buf_len] = 0;
+ err:
+       vfree(varbuf);
+       return ret;
  }
  
  static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
  {
-       uint len;
-       char *memblock = NULL;
-       char *bufp;
        int ret;
  
+       if (bus->sdiodev->bus_if->drvr_up)
+               return -EISCONN;
        ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
                               &bus->sdiodev->func[2]->dev);
        if (ret) {
                brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
                return ret;
        }
-       bus->fw_ptr = 0;
  
-       memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
-       if (memblock == NULL) {
-               ret = -ENOMEM;
-               goto err;
-       }
-       len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus);
-       if (len > 0 && len < MEMBLOCK) {
-               bufp = memblock;
-               bufp[len] = 0;
-               len = brcmf_process_nvram_vars(bufp, len);
-               bufp += len;
-               *bufp++ = 0;
-               if (len)
-                       ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1);
-               if (ret)
-                       brcmf_dbg(ERROR, "error downloading vars: %d\n", ret);
-       } else {
-               brcmf_dbg(ERROR, "error reading nvram file: %d\n", len);
-               ret = -EIO;
-       }
- err:
-       kfree(memblock);
+       ret = brcmf_process_nvram_vars(bus);
  
        release_firmware(bus->firmware);
-       bus->fw_ptr = 0;
  
        return ret;
  }
@@@ -3606,6 -3885,8 +3885,8 @@@ static bool brcmf_sdbrcm_chipmatch(u16 
                return true;
        if (chipid == BCM4330_CHIP_ID)
                return true;
+       if (chipid == BCM4334_CHIP_ID)
+               return true;
        return false;
  }
  
@@@ -3817,6 -4098,7 +4098,7 @@@ static void brcmf_sdbrcm_release_dongle
  static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
  {
        brcmf_dbg(TRACE, "Enter\n");
        if (bus) {
                /* De-register interrupt handler */
                brcmf_sdio_intr_unregister(bus->sdiodev);
@@@ -3838,6 -4120,10 +4120,10 @@@ void *brcmf_sdbrcm_probe(u32 regsva, st
  {
        int ret;
        struct brcmf_sdio *bus;
+       struct brcmf_bus_dcmd *dlst;
+       u32 dngl_txglom;
+       u32 dngl_txglomalign;
+       u8 idx;
  
        brcmf_dbg(TRACE, "Enter\n");
  
        brcmf_sdio_debugfs_create(bus);
        brcmf_dbg(INFO, "completed!!\n");
  
+       /* sdio bus core specific dcmd */
+       idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
+       dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL);
+       if (dlst) {
+               if (bus->ci->c_inf[idx].rev < 12) {
+                       /* for sdio core rev < 12, disable txgloming */
+                       dngl_txglom = 0;
+                       dlst->name = "bus:txglom";
+                       dlst->param = (char *)&dngl_txglom;
+                       dlst->param_len = sizeof(u32);
+               } else {
+                       /* otherwise, set txglomalign */
+                       dngl_txglomalign = bus->sdiodev->bus_if->align;
+                       dlst->name = "bus:txglomalign";
+                       dlst->param = (char *)&dngl_txglomalign;
+                       dlst->param_len = sizeof(u32);
+               }
+               list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list);
+       }
        /* if firmware path present try to download and bring up bus */
        ret = brcmf_bus_start(bus->sdiodev->dev);
        if (ret != 0) {
index e67556780a316d77b8d1e2ae820cf36c9f12cf72,8776fbc8dcf1de7cf3dfd1e8da0764a6dec15862..bb00b6528d8f3bbb01925650f77d3bed50aa34c6
@@@ -18,6 -18,7 +18,7 @@@
  
  #include <linux/pci_ids.h>
  #include <linux/if_ether.h>
+ #include <net/cfg80211.h>
  #include <net/mac80211.h>
  #include <brcm_hw_ids.h>
  #include <aiutils.h>
@@@ -3139,20 -3140,6 +3140,6 @@@ void brcms_c_reset(struct brcms_c_info 
        brcms_b_reset(wlc->hw);
  }
  
- /* Return the channel the driver should initialize during brcms_c_init.
-  * the channel may have to be changed from the currently configured channel
-  * if other configurations are in conflict (bandlocked, 11n mode disabled,
-  * invalid channel for current country, etc.)
-  */
- static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc)
- {
-       u16 chanspec =
-           1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
-           WL_CHANSPEC_BAND_2G;
-       return chanspec;
- }
  void brcms_c_init_scb(struct scb *scb)
  {
        int i;
@@@ -5129,6 -5116,8 +5116,8 @@@ static void brcms_c_wme_retries_write(s
  /* make interface operational */
  int brcms_c_up(struct brcms_c_info *wlc)
  {
+       struct ieee80211_channel *ch;
        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
  
        /* HW is turned off so don't try to access it */
        wlc->pub->up = true;
  
        if (wlc->bandinit_pending) {
+               ch = wlc->pub->ieee_hw->conf.channel;
                brcms_c_suspend_mac_and_wait(wlc);
-               brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec);
+               brcms_c_set_chanspec(wlc, ch20mhz_chspec(ch->hw_value));
                wlc->bandinit_pending = false;
                brcms_c_enable_mac(wlc);
        }
@@@ -5397,11 -5387,6 +5387,6 @@@ int brcms_c_set_gmode(struct brcms_c_in
        else
                return -EINVAL;
  
-       /* Legacy or bust when no OFDM is supported by regulatory */
-       if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
-            BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B))
-               return -EINVAL;
        /* update configuration value */
        if (config)
                brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
@@@ -8201,19 -8186,12 +8186,12 @@@ bool brcms_c_dpc(struct brcms_c_info *w
  void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
  {
        struct bcma_device *core = wlc->hw->d11core;
+       struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
        u16 chanspec;
  
        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
  
-       /*
-        * This will happen if a big-hammer was executed. In
-        * that case, we want to go back to the channel that
-        * we were on and not new channel
-        */
-       if (wlc->pub->associated)
-               chanspec = wlc->home_chanspec;
-       else
-               chanspec = brcms_c_init_chanspec(wlc);
+       chanspec = ch20mhz_chspec(ch->hw_value);
  
        brcms_b_init(wlc->hw, chanspec);
  
@@@ -8318,7 -8296,7 +8296,7 @@@ brcms_c_attach(struct brcms_info *wl, s
        struct brcms_pub *pub;
  
        /* allocate struct brcms_c_info state and its substructures */
 -      wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, 0);
 +      wlc = brcms_c_attach_malloc(unit, &err, 0);
        if (wlc == NULL)
                goto fail;
        wlc->wiphy = wl->wiphy;
index 32ab8ea56135c0138e5b498eb013259dbc1f99a1,42f369d15f48146ed543d6430394d6281d742542..d1950838f17f3b5bf910a4850c8610ae5ac2c55d
@@@ -296,6 -296,7 +296,7 @@@ static void iwlagn_free_dma_ptr(struct 
  static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
  {
        struct iwl_tx_queue *txq = (void *)data;
+       struct iwl_queue *q = &txq->q;
        struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
        struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
        u32 scd_sram_addr = trans_pcie->scd_base_addr +
                        iwl_read_prph(trans, SCD_QUEUE_WRPTR(i)));
        }
  
+       for (i = q->read_ptr; i != q->write_ptr;
+            i = iwl_queue_inc_wrap(i, q->n_bd)) {
+               struct iwl_tx_cmd *tx_cmd =
+                       (struct iwl_tx_cmd *)txq->entries[i].cmd->payload;
+               IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
+                       get_unaligned_le32(&tx_cmd->scratch));
+       }
        iwl_op_mode_nic_error(trans->op_mode);
  }
  
@@@ -1037,15 -1046,12 +1046,12 @@@ static int iwl_trans_pcie_start_fw(stru
  
  /*
   * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
-  * must be called under the irq lock and with MAC access
   */
  static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
  {
        struct iwl_trans_pcie __maybe_unused *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
  
-       lockdep_assert_held(&trans_pcie->irq_lock);
        iwl_write_prph(trans, SCD_TXFACT, mask);
  }
  
@@@ -1053,12 -1059,9 +1059,9 @@@ static void iwl_tx_start(struct iwl_tra
  {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        u32 a;
-       unsigned long flags;
        int i, chan;
        u32 reg_val;
  
-       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        /* make sure all queue are not stopped/used */
        memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped));
        memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used));
        iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG,
                           reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
  
-       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        /* Enable L1-Active */
        iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
                            APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
@@@ -1366,7 -1367,7 +1367,7 @@@ static int iwl_trans_pcie_tx(struct iwl
                                   DMA_BIDIRECTIONAL);
  
        trace_iwlwifi_dev_tx(trans->dev,
 -                           &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
 +                           &txq->tfds[txq->q.write_ptr],
                             sizeof(struct iwl_tfd),
                             &dev_cmd->hdr, firstlen,
                             skb->data + hdr_len, secondlen);
@@@ -2017,7 -2018,9 +2018,9 @@@ static ssize_t iwl_dbgfs_fw_restart_wri
        if (!trans->op_mode)
                return -EAGAIN;
  
+       local_bh_disable();
        iwl_op_mode_nic_error(trans->op_mode);
+       local_bh_enable();
  
        return count;
  }
index a9ba3f7ea62bbd8c998c02689ad215e3925e5998,5bddf53ece1d2d667708e98b7aee2e10b5939329..f578d0b2172dcceb34c0cbe92295158877df4d8d
@@@ -571,7 -571,7 +571,7 @@@ static void mac80211_hwsim_tx_frame_nl(
                        skb_dequeue(&data->pending);
        }
  
 -      skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
 +      skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC);
        if (skb == NULL)
                goto nla_put_failure;
  
@@@ -678,8 -678,7 +678,7 @@@ static bool mac80211_hwsim_tx_frame_no_
                        continue;
  
                if (data2->idle || !data2->started ||
-                   !hwsim_ps_rx_ok(data2, skb) ||
-                   !data->channel || !data2->channel ||
+                   !hwsim_ps_rx_ok(data2, skb) || !data2->channel ||
                    data->channel->center_freq != data2->channel->center_freq ||
                    !(data->group & data2->group))
                        continue;
@@@ -1486,7 -1485,7 +1485,7 @@@ static int hwsim_tx_info_frame_received
        struct mac80211_hwsim_data *data2;
        struct ieee80211_tx_info *txi;
        struct hwsim_tx_rate *tx_attempts;
-       struct sk_buff __user *ret_skb;
+       unsigned long ret_skb_ptr;
        struct sk_buff *skb, *tmp;
        struct mac_address *src;
        unsigned int hwsim_flags;
                                   info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
        hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]);
  
-       ret_skb = (struct sk_buff __user *)
-                 (unsigned long) nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
+       ret_skb_ptr = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
  
        data2 = get_hwsim_data_ref_from_addr(src);
  
  
        /* look for the skb matching the cookie passed back from user */
        skb_queue_walk_safe(&data2->pending, skb, tmp) {
-               if (skb == ret_skb) {
+               if ((unsigned long)skb == ret_skb_ptr) {
                        skb_unlink(skb, &data2->pending);
                        found = true;
                        break;
index 80e9b2a39058d5e0d14a3b4fae773669c8539b9e,e241f8d6a2c0ae348cd26234756f1b7fcb53245d..4b2733af1a0eaa1481ae98b3a2bf7548a6c15f0a
@@@ -170,7 -170,9 +170,9 @@@ mwifiex_cfg80211_set_default_key(struc
        if (!priv->sec_info.wep_enabled)
                return 0;
  
-       if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) {
+       if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
+               priv->wep_key_curr_index = key_index;
+       } else if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) {
                wiphy_err(wiphy, "set default Tx key index\n");
                return -EFAULT;
        }
@@@ -187,9 -189,25 +189,25 @@@ mwifiex_cfg80211_add_key(struct wiphy *
                         struct key_params *params)
  {
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
+       struct mwifiex_wep_key *wep_key;
        const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
        const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
  
+       if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
+           (params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+            params->cipher == WLAN_CIPHER_SUITE_WEP104)) {
+               if (params->key && params->key_len) {
+                       wep_key = &priv->wep_key[key_index];
+                       memset(wep_key, 0, sizeof(struct mwifiex_wep_key));
+                       memcpy(wep_key->key_material, params->key,
+                              params->key_len);
+                       wep_key->key_index = key_index;
+                       wep_key->key_length = params->key_len;
+                       priv->sec_info.wep_enabled = 1;
+               }
+               return 0;
+       }
        if (mwifiex_set_encode(priv, params->key, params->key_len,
                               key_index, peer_mac, 0)) {
                wiphy_err(wiphy, "crypto keys added\n");
@@@ -242,13 -260,13 +260,13 @@@ static int mwifiex_send_domain_info_cmd
                        flag = 1;
                        first_chan = (u32) ch->hw_value;
                        next_chan = first_chan;
-                       max_pwr = ch->max_power;
+                       max_pwr = ch->max_reg_power;
                        no_of_parsed_chan = 1;
                        continue;
                }
  
                if (ch->hw_value == next_chan + 1 &&
-                   ch->max_power == max_pwr) {
+                   ch->max_reg_power == max_pwr) {
                        next_chan++;
                        no_of_parsed_chan++;
                } else {
                        no_of_triplet++;
                        first_chan = (u32) ch->hw_value;
                        next_chan = first_chan;
-                       max_pwr = ch->max_power;
+                       max_pwr = ch->max_reg_power;
                        no_of_parsed_chan = 1;
                }
        }
@@@ -384,13 -402,13 +402,13 @@@ mwifiex_set_rf_channel(struct mwifiex_p
        cfp.freq = chan->center_freq;
        cfp.channel = ieee80211_frequency_to_channel(chan->center_freq);
  
-       if (mwifiex_bss_set_channel(priv, &cfp))
-               return -EFAULT;
-       if (priv->bss_type == MWIFIEX_BSS_TYPE_STA)
+       if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
+               if (mwifiex_bss_set_channel(priv, &cfp))
+                       return -EFAULT;
                return mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
-       else
-               return mwifiex_uap_set_channel(priv, cfp.channel);
+       }
+       return 0;
  }
  
  /*
@@@ -961,12 -979,25 +979,25 @@@ static int mwifiex_cfg80211_start_ap(st
                return -EINVAL;
        }
  
+       bss_cfg->channel =
+           (u8)ieee80211_frequency_to_channel(params->channel->center_freq);
+       bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
+       if (mwifiex_set_rf_channel(priv, params->channel,
+                                  params->channel_type)) {
+               kfree(bss_cfg);
+               wiphy_err(wiphy, "Failed to set band config information!\n");
+               return -1;
+       }
        if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
                kfree(bss_cfg);
                wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
                return -1;
        }
  
+       mwifiex_set_ht_params(priv, bss_cfg, params);
        if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
                                  HostCmd_ACT_GEN_SET, 0, NULL)) {
                wiphy_err(wiphy, "Failed to stop the BSS\n");
                return -1;
        }
  
+       if (priv->sec_info.wep_enabled)
+               priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
+       else
+               priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
+       if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL,
+                                 HostCmd_ACT_GEN_SET, 0,
+                                 &priv->curr_pkt_filter))
+               return -1;
        return 0;
  }
  
@@@ -1381,7 -1422,7 +1422,7 @@@ mwifiex_cfg80211_scan(struct wiphy *wip
  
                priv->user_scan_cfg->chan_list[i].scan_time = 0;
        }
-       if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg))
+       if (mwifiex_scan_networks(priv, priv->user_scan_cfg))
                return -EFAULT;
  
        if (request->ie && request->ie_len) {
@@@ -1702,7 -1743,7 +1743,7 @@@ int mwifiex_register_cfg80211(struct mw
  
        memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
        wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-       wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY;
+       wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
  
        /* Reserve space for mwifiex specific private data for BSS */
        wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
        wdev_priv = wiphy_priv(wiphy);
        *(unsigned long *)wdev_priv = (unsigned long)adapter;
  
 -      set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev);
 +      set_wiphy_dev(wiphy, priv->adapter->dev);
  
        ret = wiphy_register(wiphy);
        if (ret < 0) {
index 98c6aabd5a48429e2a9985c8826584ec51f145a2,884ed6377003664488ca6b55ef7a9bc1cc703041..04dc7ca4ac221a3b2c54d644f2b04fed8c180852
@@@ -1034,12 -1034,14 +1034,12 @@@ mwifiex_ret_802_11_scan_get_tlv_ptrs(st
                        case TLV_TYPE_TSFTIMESTAMP:
                                dev_dbg(adapter->dev, "info: SCAN_RESP: TSF "
                                        "timestamp TLV, len = %d\n", tlv_len);
 -                              *tlv_data = (struct mwifiex_ie_types_data *)
 -                                      current_tlv;
 +                              *tlv_data = current_tlv;
                                break;
                        case TLV_TYPE_CHANNELBANDLIST:
                                dev_dbg(adapter->dev, "info: SCAN_RESP: channel"
                                        " band list TLV, len = %d\n", tlv_len);
 -                              *tlv_data = (struct mwifiex_ie_types_data *)
 -                                      current_tlv;
 +                              *tlv_data = current_tlv;
                                break;
                        default:
                                dev_err(adapter->dev,
@@@ -1244,15 -1246,15 +1244,15 @@@ int mwifiex_update_bss_desc_with_ie(str
                                        bss_entry->beacon_buf);
                        break;
                case WLAN_EID_BSS_COEX_2040:
 -                      bss_entry->bcn_bss_co_2040 = (u8 *) (current_ptr +
 -                                      sizeof(struct ieee_types_header));
 +                      bss_entry->bcn_bss_co_2040 = current_ptr +
 +                              sizeof(struct ieee_types_header);
                        bss_entry->bss_co_2040_offset = (u16) (current_ptr +
                                        sizeof(struct ieee_types_header) -
                                                bss_entry->beacon_buf);
                        break;
                case WLAN_EID_EXT_CAPABILITY:
 -                      bss_entry->bcn_ext_cap = (u8 *) (current_ptr +
 -                                      sizeof(struct ieee_types_header));
 +                      bss_entry->bcn_ext_cap = current_ptr +
 +                              sizeof(struct ieee_types_header);
                        bss_entry->ext_cap_offset = (u16) (current_ptr +
                                        sizeof(struct ieee_types_header) -
                                        bss_entry->beacon_buf);
@@@ -1294,8 -1296,8 +1294,8 @@@ mwifiex_radio_type_to_band(u8 radio_typ
   * order to send the appropriate scan commands to firmware to populate or
   * update the internal driver scan table.
   */
static int mwifiex_scan_networks(struct mwifiex_private *priv,
-               const struct mwifiex_user_scan_cfg *user_scan_in)
+ int mwifiex_scan_networks(struct mwifiex_private *priv,
+                         const struct mwifiex_user_scan_cfg *user_scan_in)
  {
        int ret = 0;
        struct mwifiex_adapter *adapter = priv->adapter;
                        adapter->cmd_queued = cmd_node;
                        mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
                                                        true);
+                       queue_work(adapter->workqueue, &adapter->main_work);
                } else {
                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
                                               flags);
        return ret;
  }
  
- /*
-  * Sends IOCTL request to start a scan with user configurations.
-  *
-  * This function allocates the IOCTL request buffer, fills it
-  * with requisite parameters and calls the IOCTL handler.
-  *
-  * Upon completion, it also generates a wireless event to notify
-  * applications.
-  */
- int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
-                               struct mwifiex_user_scan_cfg *scan_req)
- {
-       int status;
-       status = mwifiex_scan_networks(priv, scan_req);
-       queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
-       return status;
- }
  /*
   * This function prepares a scan command to be sent to the firmware.
   *
@@@ -1701,7 -1684,8 +1682,7 @@@ int mwifiex_ret_802_11_scan(struct mwif
                                goto done;
                        }
                        if (element_id == WLAN_EID_DS_PARAMS) {
 -                              channel = *(u8 *) (current_ptr +
 -                                      sizeof(struct ieee_types_header));
 +                              channel = *(current_ptr + sizeof(struct ieee_types_header));
                                break;
                        }
  
@@@ -2036,11 -2020,12 +2017,11 @@@ mwifiex_save_curr_bcn(struct mwifiex_pr
  
        if (curr_bss->bcn_bss_co_2040)
                curr_bss->bcn_bss_co_2040 =
 -                      (u8 *) (curr_bss->beacon_buf +
 -                                      curr_bss->bss_co_2040_offset);
 +                      (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset);
  
        if (curr_bss->bcn_ext_cap)
 -              curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf +
 -                              curr_bss->ext_cap_offset);
 +              curr_bss->bcn_ext_cap = curr_bss->beacon_buf +
 +                      curr_bss->ext_cap_offset;
  }
  
  /*
index 1ff1362d8cdf4f8b2dd0cb161a67e969e53c6cb7,2d4319a8941f66a8d37d0594dd8f8f3225f70b38..b9cd9ed48c456f40bdede3cda839016c4548cfde
@@@ -259,6 -259,23 +259,23 @@@ static int mwifiex_cmd_tx_power_cfg(str
        return 0;
  }
  
+ /*
+  * This function prepares command to get RF Tx power.
+  */
+ static int mwifiex_cmd_rf_tx_power(struct mwifiex_private *priv,
+                                  struct host_cmd_ds_command *cmd,
+                                  u16 cmd_action, void *data_buf)
+ {
+       struct host_cmd_ds_rf_tx_pwr *txp = &cmd->params.txp;
+       cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_rf_tx_pwr)
+                               + S_DS_GEN);
+       cmd->command = cpu_to_le16(HostCmd_CMD_RF_TX_PWR);
+       txp->action = cpu_to_le16(cmd_action);
+       return 0;
+ }
  /*
   * This function prepares command to set Host Sleep configuration.
   *
@@@ -793,7 -810,8 +810,7 @@@ static int mwifiex_cmd_reg_access(struc
                struct host_cmd_ds_mac_reg_access *mac_reg;
  
                cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
 -              mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd->
 -                                                              params.mac_reg;
 +              mac_reg = &cmd->params.mac_reg;
                mac_reg->action = cpu_to_le16(cmd_action);
                mac_reg->offset =
                        cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
                struct host_cmd_ds_bbp_reg_access *bbp_reg;
  
                cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
 -              bbp_reg = (struct host_cmd_ds_bbp_reg_access *)
 -                                                      &cmd->params.bbp_reg;
 +              bbp_reg = &cmd->params.bbp_reg;
                bbp_reg->action = cpu_to_le16(cmd_action);
                bbp_reg->offset =
                        cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
                struct host_cmd_ds_rf_reg_access *rf_reg;
  
                cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
 -              rf_reg = (struct host_cmd_ds_rf_reg_access *)
 -                                                      &cmd->params.rf_reg;
 +              rf_reg = &cmd->params.rf_reg;
                rf_reg->action = cpu_to_le16(cmd_action);
                rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
                rf_reg->value = (u8) le32_to_cpu(reg_rw->value);
                struct host_cmd_ds_pmic_reg_access *pmic_reg;
  
                cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN);
 -              pmic_reg = (struct host_cmd_ds_pmic_reg_access *) &cmd->
 -                              params.pmic_reg;
 +              pmic_reg = &cmd->params.pmic_reg;
                pmic_reg->action = cpu_to_le16(cmd_action);
                pmic_reg->offset =
                                cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
                struct host_cmd_ds_rf_reg_access *cau_reg;
  
                cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
 -              cau_reg = (struct host_cmd_ds_rf_reg_access *)
 -                                                      &cmd->params.rf_reg;
 +              cau_reg = &cmd->params.rf_reg;
                cau_reg->action = cpu_to_le16(cmd_action);
                cau_reg->offset =
                                cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
        {
                struct mwifiex_ds_read_eeprom *rd_eeprom = data_buf;
                struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom =
 -                      (struct host_cmd_ds_802_11_eeprom_access *)
                        &cmd->params.eeprom;
  
                cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN);
@@@ -1049,6 -1072,10 +1066,10 @@@ int mwifiex_sta_prepare_cmd(struct mwif
                ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action,
                                               data_buf);
                break;
+       case HostCmd_CMD_RF_TX_PWR:
+               ret = mwifiex_cmd_rf_tx_power(priv, cmd_ptr, cmd_action,
+                                             data_buf);
+               break;
        case HostCmd_CMD_802_11_PS_MODE_ENH:
                ret = mwifiex_cmd_enh_power_mode(priv, cmd_ptr, cmd_action,
                                                 (uint16_t)cmd_oid, data_buf);
@@@ -1277,7 -1304,7 +1298,7 @@@ int mwifiex_sta_init_cmd(struct mwifiex
        priv->data_rate = 0;
  
        /* get tx power */
-       ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG,
+       ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_RF_TX_PWR,
                                     HostCmd_ACT_GEN_GET, 0, NULL);
        if (ret)
                return -1;
index bd40541ebd5afeecdeb07011a1736c9976ae0fed,4cb2c1c783971a2424c3efd7a9ddca836d06f8ce..78fc352c85c4812d40bbe5e4a1f0e676aac6a0ac
@@@ -227,7 -227,7 +227,7 @@@ static int mwifiex_ret_get_log(struct m
                               struct mwifiex_ds_get_stats *stats)
  {
        struct host_cmd_ds_802_11_get_log *get_log =
 -              (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log;
 +              &resp->params.get_log;
  
        if (stats) {
                stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame);
@@@ -282,7 -282,7 +282,7 @@@ static int mwifiex_ret_tx_rate_cfg(stru
        u32 i;
        int ret = 0;
  
 -      tlv_buf = (u8 *) ((u8 *) rate_cfg) +
 +      tlv_buf = ((u8 *)rate_cfg) +
                        sizeof(struct host_cmd_ds_tx_rate_cfg);
        tlv_buf_len = *(u16 *) (tlv_buf + sizeof(u16));
  
@@@ -450,6 -450,30 +450,30 @@@ static int mwifiex_ret_tx_power_cfg(str
        return 0;
  }
  
+ /*
+  * This function handles the command response of get RF Tx power.
+  */
+ static int mwifiex_ret_rf_tx_power(struct mwifiex_private *priv,
+                                  struct host_cmd_ds_command *resp)
+ {
+       struct host_cmd_ds_rf_tx_pwr *txp = &resp->params.txp;
+       u16 action = le16_to_cpu(txp->action);
+       priv->tx_power_level = le16_to_cpu(txp->cur_level);
+       if (action == HostCmd_ACT_GEN_GET) {
+               priv->max_tx_power_level = txp->max_power;
+               priv->min_tx_power_level = txp->min_power;
+       }
+       dev_dbg(priv->adapter->dev,
+               "Current TxPower Level=%d, Max Power=%d, Min Power=%d\n",
+               priv->tx_power_level, priv->max_tx_power_level,
+               priv->min_tx_power_level);
+       return 0;
+ }
  /*
   * This function handles the command response of set/get MAC address.
   *
@@@ -679,33 -703,39 +703,33 @@@ static int mwifiex_ret_reg_access(u16 t
        eeprom = data_buf;
        switch (type) {
        case HostCmd_CMD_MAC_REG_ACCESS:
 -              r.mac = (struct host_cmd_ds_mac_reg_access *)
 -                      &resp->params.mac_reg;
 +              r.mac = &resp->params.mac_reg;
                reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset));
                reg_rw->value = r.mac->value;
                break;
        case HostCmd_CMD_BBP_REG_ACCESS:
 -              r.bbp = (struct host_cmd_ds_bbp_reg_access *)
 -                      &resp->params.bbp_reg;
 +              r.bbp = &resp->params.bbp_reg;
                reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset));
                reg_rw->value = cpu_to_le32((u32) r.bbp->value);
                break;
  
        case HostCmd_CMD_RF_REG_ACCESS:
 -              r.rf = (struct host_cmd_ds_rf_reg_access *)
 -                     &resp->params.rf_reg;
 +              r.rf = &resp->params.rf_reg;
                reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset));
                reg_rw->value = cpu_to_le32((u32) r.bbp->value);
                break;
        case HostCmd_CMD_PMIC_REG_ACCESS:
 -              r.pmic = (struct host_cmd_ds_pmic_reg_access *)
 -                       &resp->params.pmic_reg;
 +              r.pmic = &resp->params.pmic_reg;
                reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset));
                reg_rw->value = cpu_to_le32((u32) r.pmic->value);
                break;
        case HostCmd_CMD_CAU_REG_ACCESS:
 -              r.rf = (struct host_cmd_ds_rf_reg_access *)
 -                     &resp->params.rf_reg;
 +              r.rf = &resp->params.rf_reg;
                reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset));
                reg_rw->value = cpu_to_le32((u32) r.rf->value);
                break;
        case HostCmd_CMD_802_11_EEPROM_ACCESS:
 -              r.eeprom = (struct host_cmd_ds_802_11_eeprom_access *)
 -                         &resp->params.eeprom;
 +              r.eeprom = &resp->params.eeprom;
                pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count);
                if (le16_to_cpu(eeprom->byte_count) <
                    le16_to_cpu(r.eeprom->byte_count)) {
@@@ -781,7 -811,7 +805,7 @@@ static int mwifiex_ret_subsc_evt(struc
                                 struct mwifiex_ds_misc_subsc_evt *sub_event)
  {
        struct host_cmd_ds_802_11_subsc_evt *cmd_sub_event =
 -              (struct host_cmd_ds_802_11_subsc_evt *)&resp->params.subsc_evt;
 +              &resp->params.subsc_evt;
  
        /* For every subscribe event command (Get/Set/Clear), FW reports the
         * current set of subscribed events*/
@@@ -841,6 -871,9 +865,9 @@@ int mwifiex_process_sta_cmdresp(struct 
        case HostCmd_CMD_TXPWR_CFG:
                ret = mwifiex_ret_tx_power_cfg(priv, resp);
                break;
+       case HostCmd_CMD_RF_TX_PWR:
+               ret = mwifiex_ret_rf_tx_power(priv, resp);
+               break;
        case HostCmd_CMD_802_11_PS_MODE_ENH:
                ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf);
                break;
index 2d1a8220d5c07d7c24cf67aaa4f112cfd1c997b2,6a2d72beb00d2d552d07e8524d79c9ee837e81e0..5b4b4d4eaf9e9273916131eba6830955a17da5b6
@@@ -128,7 -128,7 +128,7 @@@ u8 rtl_cam_add_one_entry(struct ieee802
        u32 us_config;
        struct rtl_priv *rtlpriv = rtl_priv(hw);
  
-       RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
                 "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n",
                 ul_entry_idx, ul_key_id, ul_enc_alg,
                 ul_default_key, mac_addr);
        }
  
        rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
 -                            (u8 *) key_content, us_config);
 +                            key_content, us_config);
  
        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "<===\n");
  
@@@ -342,7 -342,8 +342,8 @@@ void rtl_cam_del_entry(struct ieee80211
                        /* Remove from HW Security CAM */
                        memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN);
                        rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
-                       pr_info("&&&&&&&&&del entry %d\n", i);
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+                                "del CAM entry %d\n", i);
                }
        }
        return;
index 82d3afcfecd109abacea7200a5b8f636fdd72504,36bffbc4519eaa4d8c2a639d68c36fa5ffbe3f0e..31138fdad1f7aeba2ed9ca35407feac13246e3c2
@@@ -756,10 -756,10 +756,10 @@@ done
                if (index == rtlpci->rxringcount - 1)
                        rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
                                                    HW_DESC_RXERO,
 -                                                  (u8 *)&tmp_one);
 +                                                  &tmp_one);
  
                rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
 -                                          (u8 *)&tmp_one);
 +                                          &tmp_one);
  
                index = (index + 1) % rtlpci->rxringcount;
        }
@@@ -934,7 -934,7 +934,7 @@@ static void _rtl_pci_prepare_bcn_taskle
        __skb_queue_tail(&ring->queue, pskb);
  
        rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, HW_DESC_OWN,
 -                                  (u8 *)&temp_one);
 +                                  &temp_one);
  
        return;
  }
@@@ -1126,11 -1126,11 +1126,11 @@@ static int _rtl_pci_init_rx_ring(struc
                                                    rxbuffersize);
                        rtlpriv->cfg->ops->set_desc((u8 *) entry, false,
                                                    HW_DESC_RXOWN,
 -                                                  (u8 *)&tmp_one);
 +                                                  &tmp_one);
                }
  
                rtlpriv->cfg->ops->set_desc((u8 *) entry, false,
 -                                          HW_DESC_RXERO, (u8 *)&tmp_one);
 +                                          HW_DESC_RXERO, &tmp_one);
        }
        return 0;
  }
@@@ -1263,7 -1263,7 +1263,7 @@@ int rtl_pci_reset_trx_ring(struct ieee8
                                rtlpriv->cfg->ops->set_desc((u8 *) entry,
                                                            false,
                                                            HW_DESC_RXOWN,
 -                                                          (u8 *)&tmp_one);
 +                                                          &tmp_one);
                        }
                        rtlpci->rx_ring[rx_queue_idx].idx = 0;
                }
         *after reset, release previous pending packet,
         *and force the  tx idx to the first one
         */
-       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
        for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
                if (rtlpci->tx_ring[i].desc) {
                        struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[i];
  
                        while (skb_queue_len(&ring->queue)) {
-                               struct rtl_tx_desc *entry =
-                                   &ring->desc[ring->idx];
-                               struct sk_buff *skb =
-                                   __skb_dequeue(&ring->queue);
+                               struct rtl_tx_desc *entry;
+                               struct sk_buff *skb;
  
+                               spin_lock_irqsave(&rtlpriv->locks.irq_th_lock,
+                                                 flags);
+                               entry = &ring->desc[ring->idx];
+                               skb = __skb_dequeue(&ring->queue);
                                pci_unmap_single(rtlpci->pdev,
                                                 rtlpriv->cfg->ops->
                                                         get_desc((u8 *)
                                                         true,
                                                         HW_DESC_TXBUFF_ADDR),
                                                 skb->len, PCI_DMA_TODEVICE);
-                               kfree_skb(skb);
                                ring->idx = (ring->idx + 1) % ring->entries;
+                               spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
+                                                 flags);
+                               kfree_skb(skb);
                        }
                        ring->idx = 0;
                }
        }
  
-       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
        return 0;
  }
  
@@@ -1422,7 -1423,7 +1423,7 @@@ static int rtl_pci_tx(struct ieee80211_
        __skb_queue_tail(&ring->queue, skb);
  
        rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true,
 -                                  HW_DESC_OWN, (u8 *)&temp_one);
 +                                  HW_DESC_OWN, &temp_one);
  
  
        if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
index 9273fdb3aaec1ff34ac7c719f0145aa8986bd0ee,6a28aeecf004db4c9fb553ca33197f0951ae4cd8..8038a5026933125adcc17063bddcc4d9a6e296dd
@@@ -305,11 -305,15 +305,15 @@@ static void wl1271_tx_fill_hdr(struct w
        if (is_dummy || !wlvif)
                rate_idx = 0;
        else if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
-               /* if the packets are destined for AP (have a STA entry)
-                  send them with AP rate policies, otherwise use default
-                  basic rates */
+               /*
+                * if the packets are destined for AP (have a STA entry)
+                * send them with AP rate policies (EAPOLs are an exception),
+                * otherwise use default basic rates
+                */
                if (control->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
                        rate_idx = wlvif->sta.p2p_rate_idx;
+               else if (skb->protocol == cpu_to_be16(ETH_P_PAE))
+                       rate_idx = wlvif->sta.basic_rate_idx;
                else if (control->control.sta)
                        rate_idx = wlvif->sta.ap_rate_idx;
                else
@@@ -348,8 -352,10 +352,10 @@@ static int wl1271_prepare_tx_frame(stru
        bool is_dummy;
        bool is_gem = false;
  
-       if (!skb)
+       if (!skb) {
+               wl1271_error("discarding null skb");
                return -EINVAL;
+       }
  
        info = IEEE80211_SKB_CB(skb);
  
@@@ -658,7 -664,17 +664,17 @@@ void wl12xx_rearm_rx_streaming(struct w
        }
  }
  
- void wl1271_tx_work_locked(struct wl1271 *wl)
+ /*
+  * Returns failure values only in case of failed bus ops within this function.
+  * wl1271_prepare_tx_frame retvals won't be returned in order to avoid
+  * triggering recovery by higher layers when not necessary.
+  * In case a FW command fails within wl1271_prepare_tx_frame fails a recovery
+  * will be queued in wl1271_cmd_send. -EAGAIN/-EBUSY from prepare_tx_frame
+  * can occur and are legitimate so don't propagate. -EINVAL will emit a WARNING
+  * within prepare_tx_frame code but there's nothing we should do about those
+  * as well.
+  */
+ int wlcore_tx_work_locked(struct wl1271 *wl)
  {
        struct wl12xx_vif *wlvif;
        struct sk_buff *skb;
        u32 buf_offset = 0, last_len = 0;
        bool sent_packets = false;
        unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
-       int ret;
+       int ret = 0;
+       int bus_ret = 0;
  
        if (unlikely(wl->state == WL1271_STATE_OFF))
-               return;
+               return 0;
  
        while ((skb = wl1271_skb_dequeue(wl))) {
                struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  
                        buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset,
                                                            last_len);
-                       wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
-                                         buf_offset, true);
+                       bus_ret = wlcore_write_data(wl, REG_SLV_MEM_DATA,
+                                            wl->aggr_buf, buf_offset, true);
+                       if (bus_ret < 0)
+                               goto out;
                        sent_packets = true;
                        buf_offset = 0;
                        continue;
  out_ack:
        if (buf_offset) {
                buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, last_len);
-               wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
-                                 buf_offset, true);
+               bus_ret = wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
+                                            buf_offset, true);
+               if (bus_ret < 0)
+                       goto out;
                sent_packets = true;
        }
        if (sent_packets) {
                 * Interrupt the firmware with the new packets. This is only
                 * required for older hardware revisions
                 */
-               if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION)
-                       wl1271_write32(wl, WL12XX_HOST_WR_ACCESS,
-                                      wl->tx_packets_count);
+               if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) {
+                       bus_ret = wlcore_write32(wl, WL12XX_HOST_WR_ACCESS,
+                                            wl->tx_packets_count);
+                       if (bus_ret < 0)
+                               goto out;
+               }
  
                wl1271_handle_tx_low_watermark(wl);
        }
        wl12xx_rearm_rx_streaming(wl, active_hlids);
+ out:
+       return bus_ret;
  }
  
  void wl1271_tx_work(struct work_struct *work)
        if (ret < 0)
                goto out;
  
-       wl1271_tx_work_locked(wl);
+       ret = wlcore_tx_work_locked(wl);
+       if (ret < 0) {
+               wl12xx_queue_recovery_work(wl);
+               goto out;
+       }
  
        wl1271_ps_elp_sleep(wl);
  out:
@@@ -877,21 -910,28 +910,27 @@@ static void wl1271_tx_complete_packet(s
  }
  
  /* Called upon reception of a TX complete interrupt */
void wl1271_tx_complete(struct wl1271 *wl)
int wlcore_tx_complete(struct wl1271 *wl)
  {
 -      struct wl1271_acx_mem_map *memmap =
 -              (struct wl1271_acx_mem_map *)wl->target_mem_map;
 +      struct wl1271_acx_mem_map *memmap = wl->target_mem_map;
        u32 count, fw_counter;
        u32 i;
+       int ret;
  
        /* read the tx results from the chipset */
-       wl1271_read(wl, le32_to_cpu(memmap->tx_result),
-                   wl->tx_res_if, sizeof(*wl->tx_res_if), false);
+       ret = wlcore_read(wl, le32_to_cpu(memmap->tx_result),
+                         wl->tx_res_if, sizeof(*wl->tx_res_if), false);
+       if (ret < 0)
+               goto out;
        fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter);
  
        /* write host counter to chipset (to ack) */
-       wl1271_write32(wl, le32_to_cpu(memmap->tx_result) +
-                      offsetof(struct wl1271_tx_hw_res_if,
-                               tx_result_host_counter), fw_counter);
+       ret = wlcore_write32(wl, le32_to_cpu(memmap->tx_result) +
+                            offsetof(struct wl1271_tx_hw_res_if,
+                                     tx_result_host_counter), fw_counter);
+       if (ret < 0)
+               goto out;
  
        count = fw_counter - wl->tx_results_count;
        wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
  
                wl->tx_results_count++;
        }
+ out:
+       return ret;
  }
- EXPORT_SYMBOL(wl1271_tx_complete);
+ EXPORT_SYMBOL(wlcore_tx_complete);
  
  void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
  {
diff --combined net/wireless/nl80211.c
index cbdc0fd67a14b92973d6d5ef70fdefae4ada4979,234ff3bbd104c9f8538e5225dfb1be2f7831b89a..3b508eaf2d072e094f8aee5dd433ab013bed3439
@@@ -70,6 -70,94 +70,94 @@@ static int get_rdev_dev_by_ifindex(stru
        return 0;
  }
  
+ static struct cfg80211_registered_device *
+ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
+ {
+       struct cfg80211_registered_device *rdev = NULL, *tmp;
+       struct net_device *netdev;
+       assert_cfg80211_lock();
+       if (!attrs[NL80211_ATTR_WIPHY] &&
+           !attrs[NL80211_ATTR_IFINDEX])
+               return ERR_PTR(-EINVAL);
+       if (attrs[NL80211_ATTR_WIPHY])
+               rdev = cfg80211_rdev_by_wiphy_idx(
+                               nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
+       if (attrs[NL80211_ATTR_IFINDEX]) {
+               int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
+               netdev = dev_get_by_index(netns, ifindex);
+               if (netdev) {
+                       if (netdev->ieee80211_ptr)
+                               tmp = wiphy_to_dev(
+                                               netdev->ieee80211_ptr->wiphy);
+                       else
+                               tmp = NULL;
+                       dev_put(netdev);
+                       /* not wireless device -- return error */
+                       if (!tmp)
+                               return ERR_PTR(-EINVAL);
+                       /* mismatch -- return error */
+                       if (rdev && tmp != rdev)
+                               return ERR_PTR(-EINVAL);
+                       rdev = tmp;
+               }
+       }
+       if (!rdev)
+               return ERR_PTR(-ENODEV);
+       if (netns != wiphy_net(&rdev->wiphy))
+               return ERR_PTR(-ENODEV);
+       return rdev;
+ }
+ /*
+  * This function returns a pointer to the driver
+  * that the genl_info item that is passed refers to.
+  * If successful, it returns non-NULL and also locks
+  * the driver's mutex!
+  *
+  * This means that you need to call cfg80211_unlock_rdev()
+  * before being allowed to acquire &cfg80211_mutex!
+  *
+  * This is necessary because we need to lock the global
+  * mutex to get an item off the list safely, and then
+  * we lock the rdev mutex so it doesn't go away under us.
+  *
+  * We don't want to keep cfg80211_mutex locked
+  * for all the time in order to allow requests on
+  * other interfaces to go through at the same time.
+  *
+  * The result of this can be a PTR_ERR and hence must
+  * be checked with IS_ERR() for errors.
+  */
+ static struct cfg80211_registered_device *
+ cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
+ {
+       struct cfg80211_registered_device *rdev;
+       mutex_lock(&cfg80211_mutex);
+       rdev = __cfg80211_rdev_from_attrs(netns, info->attrs);
+       /* if it is not an error we grab the lock on
+        * it to assure it won't be going away while
+        * we operate on it */
+       if (!IS_ERR(rdev))
+               mutex_lock(&rdev->mtx);
+       mutex_unlock(&cfg80211_mutex);
+       return rdev;
+ }
  /* policy for the attributes */
  static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
        [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
        [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
        [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
        [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
-                               .len = IEEE80211_MAX_MESH_ID_LEN },
+                                  .len = IEEE80211_MAX_MESH_ID_LEN },
        [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
  
        [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
@@@ -250,8 -338,9 +338,9 @@@ nl80211_rekey_policy[NUM_NL80211_REKEY_
  
  static const struct nla_policy
  nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
-       [NL80211_ATTR_SCHED_SCAN_MATCH_SSID] = { .type = NLA_BINARY,
+       [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
                                                 .len = IEEE80211_MAX_SSID_LEN },
+       [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
  };
  
  /* ifidx get helper */
@@@ -1334,7 -1423,8 +1423,8 @@@ static int nl80211_set_wiphy(struct sk_
        }
  
        if (!netdev) {
-               rdev = __cfg80211_rdev_from_info(info);
+               rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
+                                                 info->attrs);
                if (IS_ERR(rdev)) {
                        mutex_unlock(&cfg80211_mutex);
                        return PTR_ERR(rdev);
@@@ -2246,6 -2336,33 +2336,33 @@@ static int nl80211_parse_beacon(struct 
        return 0;
  }
  
+ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
+                                  struct cfg80211_ap_settings *params)
+ {
+       struct wireless_dev *wdev;
+       bool ret = false;
+       mutex_lock(&rdev->devlist_mtx);
+       list_for_each_entry(wdev, &rdev->netdev_list, list) {
+               if (wdev->iftype != NL80211_IFTYPE_AP &&
+                   wdev->iftype != NL80211_IFTYPE_P2P_GO)
+                       continue;
+               if (!wdev->preset_chan)
+                       continue;
+               params->channel = wdev->preset_chan;
+               params->channel_type = wdev->preset_chantype;
+               ret = true;
+               break;
+       }
+       mutex_unlock(&rdev->devlist_mtx);
+       return ret;
+ }
  static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
  {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
        } else if (wdev->preset_chan) {
                params.channel = wdev->preset_chan;
                params.channel_type = wdev->preset_chantype;
-       } else
+       } else if (!nl80211_get_ap_channel(rdev, &params))
                return -EINVAL;
  
        if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel,
                return -EINVAL;
  
        err = rdev->ops->start_ap(&rdev->wiphy, dev, &params);
-       if (!err)
+       if (!err) {
+               wdev->preset_chan = params.channel;
+               wdev->preset_chantype = params.channel_type;
                wdev->beacon_interval = params.beacon_interval;
+       }
        return err;
  }
  
@@@ -3469,7 -3589,13 +3589,13 @@@ static int nl80211_get_mesh_config(stru
            nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
                        cur_params.rssi_threshold) ||
            nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
-                       cur_params.ht_opmode))
+                       cur_params.ht_opmode) ||
+           nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
+                       cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
+           nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
+                       cur_params.dot11MeshHWMProotInterval) ||
+           nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
+                       cur_params.dot11MeshHWMPconfirmationInterval))
                goto nla_put_failure;
        nla_nest_end(msg, pinfoattr);
        genlmsg_end(msg, hdr);
@@@ -3492,7 -3618,6 +3618,6 @@@ static const struct nla_policy nl80211_
        [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
        [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
        [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
        [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
        [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
        [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
        [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
        [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
        [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
-       [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32},
-       [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16},
+       [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
+       [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
+       [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
+       [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
+       [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
  };
  
  static const struct nla_policy
        [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
        [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
        [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
-               .len = IEEE80211_MAX_DATA_LEN },
+                                   .len = IEEE80211_MAX_DATA_LEN },
        [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
  };
  
@@@ -3548,63 -3676,82 +3676,82 @@@ do {
  
        /* Fill in the params struct */
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
-                       mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
+                                 mask, NL80211_MESHCONF_RETRY_TIMEOUT,
+                                 nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
-                       mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16);
+                                 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
+                                 nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
-                       mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16);
+                                 mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
+                                 nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
-                       mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16);
+                                 mask, NL80211_MESHCONF_MAX_PEER_LINKS,
+                                 nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
-                       mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
+                                 mask, NL80211_MESHCONF_MAX_RETRIES,
+                                 nla_get_u8);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
-                       mask, NL80211_MESHCONF_TTL, nla_get_u8);
+                                 mask, NL80211_MESHCONF_TTL, nla_get_u8);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl,
-                       mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
+                                 mask, NL80211_MESHCONF_ELEMENT_TTL,
+                                 nla_get_u8);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
-                       mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
-                       mask, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
-                       nla_get_u32);
+                                 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
+                                 nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, mask,
+                                 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
+                                 nla_get_u32);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
-                       mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
-                       nla_get_u8);
+                                 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
+                                 nla_get_u8);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
-                       mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32);
+                                 mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
+                                 nla_get_u32);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
-                       mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
-                       nla_get_u16);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
-                       mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
-                       nla_get_u32);
+                                 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
+                                 nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, mask,
+                                 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+                                 nla_get_u32);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
-                       mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
-                       nla_get_u16);
+                                 mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+                                 nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
-                       mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
-                       nla_get_u16);
+                                 mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
+                                 nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
-                       dot11MeshHWMPnetDiameterTraversalTime,
-                       mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
-                       nla_get_u16);
+                                 dot11MeshHWMPnetDiameterTraversalTime, mask,
+                                 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+                                 nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
+                                 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
+                                 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
+                                 nla_get_u16);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
-                       dot11MeshHWMPRootMode, mask,
-                       NL80211_MESHCONF_HWMP_ROOTMODE,
-                       nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
-                       dot11MeshHWMPRannInterval, mask,
-                       NL80211_MESHCONF_HWMP_RANN_INTERVAL,
-                       nla_get_u16);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
-                       dot11MeshGateAnnouncementProtocol, mask,
-                       NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
-                       nla_get_u8);
+                                 dot11MeshGateAnnouncementProtocol, mask,
+                                 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
+                                 nla_get_u8);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
-                       mask, NL80211_MESHCONF_FORWARDING, nla_get_u8);
+                                 mask, NL80211_MESHCONF_FORWARDING,
+                                 nla_get_u8);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold,
-                       mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32);
+                                 mask, NL80211_MESHCONF_RSSI_THRESHOLD,
+                                 nla_get_u32);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode,
-                       mask, NL80211_MESHCONF_HT_OPMODE, nla_get_u16);
+                                 mask, NL80211_MESHCONF_HT_OPMODE,
+                                 nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
+                                 mask,
+                                 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
+                                 nla_get_u32);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval,
+                                 mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
+                                 nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
+                                 dot11MeshHWMPconfirmationInterval, mask,
+                                 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
+                                 nla_get_u16);
        if (mask_out)
                *mask_out = mask;
  
@@@ -4241,12 -4388,12 +4388,12 @@@ static int nl80211_start_sched_scan(str
                nla_for_each_nested(attr,
                                    info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
                                    tmp) {
-                       struct nlattr *ssid;
+                       struct nlattr *ssid, *rssi;
  
                        nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
                                  nla_data(attr), nla_len(attr),
                                  nl80211_match_policy);
-                       ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID];
+                       ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
                        if (ssid) {
                                if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
                                        err = -EINVAL;
                                request->match_sets[i].ssid.ssid_len =
                                        nla_len(ssid);
                        }
+                       rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
+                       if (rssi)
+                               request->rssi_thold = nla_get_u32(rssi);
+                       else
+                               request->rssi_thold =
+                                                  NL80211_SCAN_RSSI_THOLD_OFF;
                        i++;
                }
        }
@@@ -5114,21 -5267,18 +5267,18 @@@ static int nl80211_testmode_dump(struc
                                  nl80211_policy);
                if (err)
                        return err;
-               if (nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) {
-                       phy_idx = nla_get_u32(
-                               nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
-               } else {
-                       struct net_device *netdev;
  
-                       err = get_rdev_dev_by_ifindex(sock_net(skb->sk),
-                                                     nl80211_fam.attrbuf,
-                                                     &rdev, &netdev);
-                       if (err)
-                               return err;
-                       dev_put(netdev);
-                       phy_idx = rdev->wiphy_idx;
-                       cfg80211_unlock_rdev(rdev);
+               mutex_lock(&cfg80211_mutex);
+               rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
+                                                 nl80211_fam.attrbuf);
+               if (IS_ERR(rdev)) {
+                       mutex_unlock(&cfg80211_mutex);
+                       return PTR_ERR(rdev);
                }
+               phy_idx = rdev->wiphy_idx;
+               rdev = NULL;
+               mutex_unlock(&cfg80211_mutex);
                if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
                        cb->args[1] =
                                (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
@@@ -6511,7 -6661,7 +6661,7 @@@ static int nl80211_pre_doit(struct genl
                rtnl_lock();
  
        if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
-               rdev = cfg80211_get_dev_from_info(info);
+               rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
                if (IS_ERR(rdev)) {
                        if (rtnl)
                                rtnl_unlock();
@@@ -7210,7 -7360,7 +7360,7 @@@ void nl80211_send_scan_start(struct cfg
  {
        struct sk_buff *msg;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return;
  
@@@ -7286,7 -7436,7 +7436,7 @@@ void nl80211_send_sched_scan(struct cfg
  {
        struct sk_buff *msg;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return;
  
@@@ -7502,7 -7652,7 +7652,7 @@@ void nl80211_send_connect_result(struc
        struct sk_buff *msg;
        void *hdr;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
        if (!msg)
                return;
  
@@@ -7542,7 -7692,7 +7692,7 @@@ void nl80211_send_roamed(struct cfg8021
        struct sk_buff *msg;
        void *hdr;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
        if (!msg)
                return;
  
@@@ -7580,7 -7730,7 +7730,7 @@@ void nl80211_send_disconnected(struct c
        struct sk_buff *msg;
        void *hdr;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return;
  
@@@ -7842,7 -7992,7 +7992,7 @@@ void nl80211_send_sta_event(struct cfg8
  {
        struct sk_buff *msg;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
        if (!msg)
                return;
  
@@@ -7863,7 -8013,7 +8013,7 @@@ void nl80211_send_sta_del_event(struct 
        struct sk_buff *msg;
        void *hdr;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
        if (!msg)
                return;
  
@@@ -8026,7 -8176,7 +8176,7 @@@ nl80211_send_cqm_rssi_notify(struct cfg
        struct nlattr *pinfoattr;
        void *hdr;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
        if (!msg)
                return;
  
@@@ -8069,7 -8219,7 +8219,7 @@@ void nl80211_gtk_rekey_notify(struct cf
        struct nlattr *rekey_attr;
        void *hdr;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
        if (!msg)
                return;
  
@@@ -8113,7 -8263,7 +8263,7 @@@ void nl80211_pmksa_candidate_notify(str
        struct nlattr *attr;
        void *hdr;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
        if (!msg)
                return;
  
@@@ -8157,7 -8307,7 +8307,7 @@@ void nl80211_ch_switch_notify(struct cf
        struct sk_buff *msg;
        void *hdr;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
        if (!msg)
                return;
  
@@@ -8192,7 -8342,7 +8342,7 @@@ nl80211_send_cqm_pktloss_notify(struct 
        struct nlattr *pinfoattr;
        void *hdr;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
        if (!msg)
                return;
  
@@@ -8236,7 -8386,7 +8386,7 @@@ void cfg80211_probe_status(struct net_d
        void *hdr;
        int err;
  
 -      msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
 +      msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
        if (!msg)
                return;