]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
authorJohn W. Linville <linville@tuxdriver.com>
Wed, 15 Feb 2012 21:24:37 +0000 (16:24 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 15 Feb 2012 21:24:37 +0000 (16:24 -0500)
Conflicts:
net/mac80211/debugfs_sta.c
net/mac80211/sta_info.h

12 files changed:
1  2 
MAINTAINERS
drivers/bcma/main.c
drivers/bcma/scan.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/rt2x00/rt2800lib.c
net/mac80211/main.c
net/mac80211/rx.c

diff --combined MAINTAINERS
index bcb668c0af71bd767ac7a4b6a6c2cc824286c40a,93c68d5f1cf4dc0623c501e85d6f8c86ab1a472d..48418c8475f09cb8ed4e384c67ae26720466e1e6
@@@ -745,6 -745,7 +745,7 @@@ M: Barry Song <baohua.song@csr.com
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/mach-prima2/
+ F:    drivers/dma/sirf-dma*
  
  ARM/EBSA110 MACHINE SUPPORT
  M:    Russell King <linux@arm.linux.org.uk>
@@@ -1411,7 -1412,7 +1412,7 @@@ F:      net/ax25
  B43 WIRELESS DRIVER
  M:    Stefano Brivio <stefano.brivio@polimi.it>
  L:    linux-wireless@vger.kernel.org
 -L:    b43-dev@lists.infradead.org (moderated for non-subscribers)
 +L:    b43-dev@lists.infradead.org
  W:    http://linuxwireless.org/en/users/Drivers/b43
  S:    Maintained
  F:    drivers/net/wireless/b43/
@@@ -1420,7 -1421,6 +1421,7 @@@ B43LEGACY WIRELESS DRIVE
  M:    Larry Finger <Larry.Finger@lwfinger.net>
  M:    Stefano Brivio <stefano.brivio@polimi.it>
  L:    linux-wireless@vger.kernel.org
 +L:    b43-dev@lists.infradead.org
  W:    http://linuxwireless.org/en/users/Drivers/b43
  S:    Maintained
  F:    drivers/net/wireless/b43legacy/
@@@ -2246,6 -2246,17 +2247,17 @@@ T:    git git://git.kernel.org/pub/scm/lin
  S:    Supported
  F:    fs/dlm/
  
+ DMA BUFFER SHARING FRAMEWORK
+ M:    Sumit Semwal <sumit.semwal@linaro.org>
+ S:    Maintained
+ L:    linux-media@vger.kernel.org
+ L:    dri-devel@lists.freedesktop.org
+ L:    linaro-mm-sig@lists.linaro.org
+ F:    drivers/base/dma-buf*
+ F:    include/linux/dma-buf*
+ F:    Documentation/dma-buf-sharing.txt
+ T:    git git://git.linaro.org/people/sumitsemwal/linux-dma-buf.git
  DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
  M:    Vinod Koul <vinod.koul@intel.com>
  M:    Dan Williams <dan.j.williams@intel.com>
@@@ -2830,6 -2841,14 +2842,14 @@@ L:    platform-driver-x86@vger.kernel.or
  S:    Maintained
  F:    drivers/platform/x86/fujitsu-laptop.c
  
+ FUJITSU M-5MO LS CAMERA ISP DRIVER
+ M:    Kyungmin Park <kyungmin.park@samsung.com>
+ M:    Heungjun Kim <riverful.kim@samsung.com>
+ L:    linux-media@vger.kernel.org
+ S:    Maintained
+ F:    drivers/media/video/m5mols/
+ F:    include/media/m5mols.h
  FUSE: FILESYSTEM IN USERSPACE
  M:    Miklos Szeredi <miklos@szeredi.hu>
  L:    fuse-devel@lists.sourceforge.net
@@@ -3202,6 -3221,7 +3222,7 @@@ F:      drivers/i2c/busses/i2c-stub.
  I2C SUBSYSTEM
  M:    "Jean Delvare (PC drivers, core)" <khali@linux-fr.org>
  M:    "Ben Dooks (embedded platforms)" <ben-linux@fluff.org>
+ M:    "Wolfram Sang (embedded platforms)" <w.sang@pengutronix.de>
  L:    linux-i2c@vger.kernel.org
  W:    http://i2c.wiki.kernel.org/
  T:    quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/
@@@ -3783,7 -3803,6 +3804,6 @@@ S:      Odd Fixe
  
  KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
  M:    "J. Bruce Fields" <bfields@fieldses.org>
- M:    Neil Brown <neilb@suse.de>
  L:    linux-nfs@vger.kernel.org
  W:    http://nfs.sourceforge.net/
  S:    Supported
@@@ -4692,6 -4711,8 +4712,8 @@@ Q:      http://patchwork.kernel.org/project/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
  S:    Maintained
  F:    arch/arm/*omap*/
+ F:    drivers/i2c/busses/i2c-omap.c
+ F:    include/linux/i2c-omap.h
  
  OMAP CLOCK FRAMEWORK SUPPORT
  M:    Paul Walmsley <paul@pwsan.com>
@@@ -4894,6 -4915,8 +4916,6 @@@ F:      fs/ocfs2
  
  ORINOCO DRIVER
  L:    linux-wireless@vger.kernel.org
 -L:    orinoco-users@lists.sourceforge.net
 -L:    orinoco-devel@lists.sourceforge.net
  W:    http://linuxwireless.org/en/users/Drivers/orinoco
  W:    http://www.nongnu.org/orinoco/
  S:    Orphan
@@@ -5674,6 -5697,12 +5696,12 @@@ L:    alsa-devel@alsa-project.org (moderat
  S:    Supported
  F:    sound/soc/samsung
  
+ SAMSUNG FRAMEBUFFER DRIVER
+ M:    Jingoo Han <jg1.han@samsung.com>
+ L:    linux-fbdev@vger.kernel.org
+ S:    Maintained
+ F:    drivers/video/s3c-fb.c
  SERIAL DRIVERS
  M:    Alan Cox <alan@linux.intel.com>
  L:    linux-serial@vger.kernel.org
@@@ -5837,7 -5866,7 +5865,7 @@@ F:      drivers/mmc/host/sdhci-spear.
  SECURITY SUBSYSTEM
  M:    James Morris <jmorris@namei.org>
  L:    linux-security-module@vger.kernel.org (suggested Cc:)
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git
  W:    http://security.wiki.kernel.org/
  S:    Supported
  F:    security/
@@@ -5963,6 -5992,7 +5991,7 @@@ L:      davinci-linux-open-source@linux.davi
  Q:    http://patchwork.kernel.org/project/linux-davinci/list/
  S:    Supported
  F:    arch/arm/mach-davinci
+ F:    drivers/i2c/busses/i2c-davinci.c
  
  SIS 190 ETHERNET DRIVER
  M:    Francois Romieu <romieu@fr.zoreil.com>
@@@ -7181,7 -7211,7 +7210,7 @@@ S:      Maintaine
  F:    drivers/net/vmxnet3/
  
  VMware PVSCSI driver
- M:    Alok Kataria <akataria@vmware.com>
+ M:    Arvind Kumar <arvindkumar@vmware.com>
  M:    VMware PV-Drivers <pv-drivers@vmware.com>
  L:    linux-scsi@vger.kernel.org
  S:    Maintained
diff --combined drivers/bcma/main.c
index bcd1c01cde9e0bde6012a786537a8949bf557878,ec31f7dd55491aeaea79b071c8aebc7065a8452a..b8379b90d045c85b1581e3b97b9f4bcb42aff2e1
  MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
  MODULE_LICENSE("GPL");
  
 +/* contains the number the next bus should get. */
 +static unsigned int bcma_bus_next_num = 0;
 +
 +/* bcma_buses_mutex locks the bcma_bus_next_num */
 +static DEFINE_MUTEX(bcma_buses_mutex);
 +
  static int bcma_bus_match(struct device *dev, struct device_driver *drv);
  static int bcma_device_probe(struct device *dev);
  static int bcma_device_remove(struct device *dev);
@@@ -99,7 -93,7 +99,7 @@@ static int bcma_register_cores(struct b
  
                core->dev.release = bcma_release_core_dev;
                core->dev.bus = &bcma_bus_type;
 -              dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
 +              dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
  
                switch (bus->hosttype) {
                case BCMA_HOSTTYPE_PCI:
@@@ -138,15 -132,11 +138,15 @@@ static void bcma_unregister_cores(struc
        }
  }
  
 -int bcma_bus_register(struct bcma_bus *bus)
 +int __devinit bcma_bus_register(struct bcma_bus *bus)
  {
        int err;
        struct bcma_device *core;
  
 +      mutex_lock(&bcma_buses_mutex);
 +      bus->num = bcma_bus_next_num++;
 +      mutex_unlock(&bcma_buses_mutex);
 +
        /* Scan for devices (cores) */
        err = bcma_bus_scan(bus);
        if (err) {
        err = bcma_sprom_get(bus);
        if (err == -ENOENT) {
                pr_err("No SPROM available\n");
-       } else if (err) {
+       } else if (err)
                pr_err("Failed to get SPROM: %d\n", err);
-               return -ENOENT;
-       }
  
        /* Register found cores */
        bcma_register_cores(bus);
diff --combined drivers/bcma/scan.c
index 6621b2221b4084d8ecbbfc275a2231bd8a74f554,3a2f672db9ad217c264cf7a2203e4d96aa0910d7..f94cccccfa56fc94a2e0b2cf454b30afd3864855
@@@ -212,17 -212,6 +212,17 @@@ static struct bcma_device *bcma_find_co
        return NULL;
  }
  
 +static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
 +{
 +      struct bcma_device *core;
 +
 +      list_for_each_entry_reverse(core, &bus->cores, list) {
 +              if (core->id.id == coreid)
 +                      return core;
 +      }
 +      return NULL;
 +}
 +
  static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
                              struct bcma_device_id *match, int core_num,
                              struct bcma_device *core)
  void bcma_init_bus(struct bcma_bus *bus)
  {
        s32 tmp;
 +      struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
  
        if (bus->init_done)
                return;
        bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
  
        tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
 -      bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
 -      bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
 -      bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
 +      chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
 +      chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
 +      chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
 +      pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
 +              chipinfo->id, chipinfo->rev, chipinfo->pkg);
 +
        bus->init_done = true;
  }
  
@@@ -407,7 -392,6 +407,7 @@@ int bcma_bus_scan(struct bcma_bus *bus
        bcma_scan_switch_core(bus, erombase);
  
        while (eromptr < eromend) {
 +              struct bcma_device *other_core;
                struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
                if (!core)
                        return -ENOMEM;
                core->bus = bus;
  
                err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
-               if (err == -ENODEV) {
-                       core_num++;
-                       continue;
-               } else if (err == -ENXIO)
-                       continue;
-               else if (err == -ESPIPE)
-                       break;
-               else if (err < 0)
+               if (err < 0) {
+                       kfree(core);
+                       if (err == -ENODEV) {
+                               core_num++;
+                               continue;
+                       } else if (err == -ENXIO) {
+                               continue;
+                       } else if (err == -ESPIPE) {
+                               break;
+                       }
                        return err;
+               }
  
                core->core_index = core_num++;
                bus->nr_cores++;
 +              other_core = bcma_find_core_reverse(bus, core->id.id);
 +              core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
  
                pr_info("Core %d found: %s "
                        "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
index a8c6880af34be6bfc7ac691abc13db5ea4c2d4d1,63bbc60be28e461ada4e173b5caafbd43f243c31..64f8db685dc50fbdf72a5927331fc93d344a9f10
@@@ -2,7 -2,7 +2,7 @@@
   *
   * GPL LICENSE SUMMARY
   *
 - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
 + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -91,6 -91,7 +91,7 @@@ static void iwlagn_tx_cmd_build_basic(s
                tx_cmd->tid_tspec = qc[0] & 0xf;
                tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
        } else {
+               tx_cmd->tid_tspec = IWL_TID_NON_QOS;
                if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
                        tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
                else
@@@ -620,7 -621,7 +621,7 @@@ int iwlagn_tx_agg_oper(struct iwl_priv 
        sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit =
                sta_priv->max_agg_bufsize;
  
-       IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n",
+       IWL_DEBUG_HT(priv, "Tx aggregation enabled on ra = %pM tid = %d\n",
                 sta->addr, tid);
  
        return iwl_send_lq_cmd(priv, ctx,
@@@ -808,6 -809,8 +809,8 @@@ static void iwl_rx_reply_tx_agg(struct 
        u32 status = le16_to_cpu(tx_resp->status.status);
        int i;
  
+       WARN_ON(tid == IWL_TID_NON_QOS);
        if (agg->wait_for_ba)
                IWL_DEBUG_TX_REPLY(priv,
                        "got tx response w/o block-ack\n");
@@@ -1035,10 -1038,13 +1038,13 @@@ int iwlagn_rx_reply_tx(struct iwl_priv 
                }
  
                __skb_queue_head_init(&skbs);
-               priv->tid_data[sta_id][tid].next_reclaimed = next_reclaimed;
  
-               IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d",
-                                         next_reclaimed);
+               if (tid != IWL_TID_NON_QOS) {
+                       priv->tid_data[sta_id][tid].next_reclaimed =
+                               next_reclaimed;
+                       IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d",
+                                                 next_reclaimed);
+               }
  
                /*we can free until ssn % q.n_bd not inclusive */
                WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id,
index b4779c25a4b315924640b9a3f814aa5ba15c597d,f822ac447c3bcd484979d9ce5179a6064bb2e2f9..c20618d9226813d2e1b75654c2000522e181eebc
@@@ -5,7 -5,7 +5,7 @@@
   *
   * GPL LICENSE SUMMARY
   *
 - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
 + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -30,7 -30,7 +30,7 @@@
   *
   * BSD LICENSE
   *
 - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
 + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -815,6 -815,7 +815,7 @@@ struct iwl_qosparam_cmd 
  
  #define       IWL_INVALID_STATION     255
  #define IWL_MAX_TID_COUNT     8
+ #define IWL_TID_NON_QOS IWL_MAX_TID_COUNT
  
  #define STA_FLG_TX_RATE_MSK           cpu_to_le32(1 << 2)
  #define STA_FLG_PWR_SAVE_MSK          cpu_to_le32(1 << 8)
index 836caf9c68b35c387ce5061912a725f0d82677ef,324d06dfb69003ca14ac5ab024d800a750057568..f5cb5d3cd92641826cb12c33248184e56c8c1b16
@@@ -5,7 -5,7 +5,7 @@@
   *
   * GPL LICENSE SUMMARY
   *
 - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
 + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -30,7 -30,7 +30,7 @@@
   *
   * BSD LICENSE
   *
 - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
 + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   *****************************************************************************/
 +#include <linux/pci.h>
 +#include <linux/pci-aspm.h>
  #include <linux/interrupt.h>
  #include <linux/debugfs.h>
 +#include <linux/sched.h>
  #include <linux/bitops.h>
  #include <linux/gfp.h>
  
  #include "iwl-shared.h"
  #include "iwl-eeprom.h"
  #include "iwl-agn-hw.h"
 +#include "iwl-core.h"
  
  static int iwl_trans_rx_alloc(struct iwl_trans *trans)
  {
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_rx_queue *rxq = &trans_pcie->rxq;
 -      struct device *dev = bus(trans)->dev;
 +      struct device *dev = trans->dev;
  
        memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq));
  
@@@ -126,7 -122,7 +126,7 @@@ static void iwl_trans_rxq_free_rx_bufs(
                /* In the reset function, these buffers may have been allocated
                 * to an SKB, so we need to unmap and free potential storage */
                if (rxq->pool[i].page != NULL) {
 -                      dma_unmap_page(bus(trans)->dev, rxq->pool[i].page_dma,
 +                      dma_unmap_page(trans->dev, rxq->pool[i].page_dma,
                                PAGE_SIZE << hw_params(trans).rx_page_order,
                                DMA_FROM_DEVICE);
                        __free_pages(rxq->pool[i].page,
@@@ -150,17 -146,17 +150,17 @@@ static void iwl_trans_rx_hw_init(struc
                rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
  
        /* Stop Rx DMA */
 -      iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
 +      iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
  
        /* Reset driver's Rx queue write index */
 -      iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
 +      iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
  
        /* Tell device where to find RBD circular buffer in DRAM */
 -      iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_BASE_REG,
 +      iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
                           (u32)(rxq->bd_dma >> 8));
  
        /* Tell device where in DRAM to update its Rx status */
 -      iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_STTS_WPTR_REG,
 +      iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG,
                           rxq->rb_stts_dma >> 4);
  
        /* Enable Rx DMA
         * RB timeout 0x10
         * 256 RBDs
         */
 -      iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG,
 +      iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG,
                           FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
                           FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
                           FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
                           (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
  
        /* Set interrupt coalescing timer to default (2048 usecs) */
 -      iwl_write8(bus(trans), CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
 +      iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
  }
  
  static int iwl_rx_init(struct iwl_trans *trans)
@@@ -246,13 -242,13 +246,13 @@@ static void iwl_trans_pcie_rx_free(stru
        iwl_trans_rxq_free_rx_bufs(trans);
        spin_unlock_irqrestore(&rxq->lock, flags);
  
 -      dma_free_coherent(bus(trans)->dev, sizeof(__le32) * RX_QUEUE_SIZE,
 +      dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE,
                          rxq->bd, rxq->bd_dma);
        memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
        rxq->bd = NULL;
  
        if (rxq->rb_stts)
 -              dma_free_coherent(bus(trans)->dev,
 +              dma_free_coherent(trans->dev,
                                  sizeof(struct iwl_rb_status),
                                  rxq->rb_stts, rxq->rb_stts_dma);
        else
@@@ -265,8 -261,8 +265,8 @@@ static int iwl_trans_rx_stop(struct iwl
  {
  
        /* stop Rx DMA */
 -      iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
 -      return iwl_poll_direct_bit(bus(trans), FH_MEM_RSSR_RX_STATUS_REG,
 +      iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
 +      return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG,
                            FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
  }
  
@@@ -276,7 -272,7 +276,7 @@@ static inline int iwlagn_alloc_dma_ptr(
        if (WARN_ON(ptr->addr))
                return -EINVAL;
  
 -      ptr->addr = dma_alloc_coherent(bus(trans)->dev, size,
 +      ptr->addr = dma_alloc_coherent(trans->dev, size,
                                       &ptr->dma, GFP_KERNEL);
        if (!ptr->addr)
                return -ENOMEM;
@@@ -290,7 -286,7 +290,7 @@@ static inline void iwlagn_free_dma_ptr(
        if (unlikely(!ptr->addr))
                return;
  
 -      dma_free_coherent(bus(trans)->dev, ptr->size, ptr->addr, ptr->dma);
 +      dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma);
        memset(ptr, 0, sizeof(*ptr));
  }
  
@@@ -337,7 -333,7 +337,7 @@@ static int iwl_trans_txq_alloc(struct i
  
        /* Circular buffer of transmit frame descriptors (TFDs),
         * shared with device */
 -      txq->tfds = dma_alloc_coherent(bus(trans)->dev, tfd_sz,
 +      txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz,
                                       &txq->q.dma_addr, GFP_KERNEL);
        if (!txq->tfds) {
                IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
@@@ -393,7 -389,7 +393,7 @@@ static int iwl_trans_txq_init(struct iw
         * Tell nic where to find circular buffer of Tx Frame Descriptors for
         * given Tx queue, and enable the DMA channel used for that queue.
         * Circular buffer (TFD queue in DRAM) physical base address */
 -      iwl_write_direct32(bus(trans), FH_MEM_CBBC_QUEUE(txq_id),
 +      iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id),
                             txq->q.dma_addr >> 8);
  
        return 0;
@@@ -447,7 -443,7 +447,7 @@@ static void iwl_tx_queue_free(struct iw
  {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
 -      struct device *dev = bus(trans)->dev;
 +      struct device *dev = trans->dev;
        int i;
        if (WARN_ON(!txq))
                return;
@@@ -588,10 -584,10 +588,10 @@@ static int iwl_tx_init(struct iwl_tran
        spin_lock_irqsave(&trans->shrd->lock, flags);
  
        /* Turn off all Tx DMA fifos */
 -      iwl_write_prph(bus(trans), SCD_TXFACT, 0);
 +      iwl_write_prph(trans, SCD_TXFACT, 0);
  
        /* Tell NIC where to find the "keep warm" buffer */
 -      iwl_write_direct32(bus(trans), FH_KW_MEM_ADDR_REG,
 +      iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
                           trans_pcie->kw.dma >> 4);
  
        spin_unlock_irqrestore(&trans->shrd->lock, flags);
@@@ -623,194 -619,26 +623,194 @@@ static void iwl_set_pwr_vmain(struct iw
   * to set power to V_AUX, do:
  
                if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
 -                      iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG,
 +                      iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG,
                                               APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
                                               ~APMG_PS_CTRL_MSK_PWR_SRC);
   */
  
 -      iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG,
 +      iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG,
                               APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
                               ~APMG_PS_CTRL_MSK_PWR_SRC);
  }
  
 +/* PCI registers */
 +#define PCI_CFG_RETRY_TIMEOUT 0x041
 +#define PCI_CFG_LINK_CTRL_VAL_L0S_EN  0x01
 +#define PCI_CFG_LINK_CTRL_VAL_L1_EN   0x02
 +
 +static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans)
 +{
 +      int pos;
 +      u16 pci_lnk_ctl;
 +      struct iwl_trans_pcie *trans_pcie =
 +              IWL_TRANS_GET_PCIE_TRANS(trans);
 +
 +      struct pci_dev *pci_dev = trans_pcie->pci_dev;
 +
 +      pos = pci_pcie_cap(pci_dev);
 +      pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
 +      return pci_lnk_ctl;
 +}
 +
 +static void iwl_apm_config(struct iwl_trans *trans)
 +{
 +      /*
 +       * HW bug W/A for instability in PCIe bus L0S->L1 transition.
 +       * Check if BIOS (or OS) enabled L1-ASPM on this device.
 +       * If so (likely), disable L0S, so device moves directly L0->L1;
 +       *    costs negligible amount of power savings.
 +       * If not (unlikely), enable L0S, so there is at least some
 +       *    power savings, even without L1.
 +       */
 +      u16 lctl = iwl_pciexp_link_ctrl(trans);
 +
 +      if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
 +                              PCI_CFG_LINK_CTRL_VAL_L1_EN) {
 +              /* L1-ASPM enabled; disable(!) L0S */
 +              iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
 +              dev_printk(KERN_INFO, trans->dev,
 +                         "L1 Enabled; Disabling L0S\n");
 +      } else {
 +              /* L1-ASPM disabled; enable(!) L0S */
 +              iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
 +              dev_printk(KERN_INFO, trans->dev,
 +                         "L1 Disabled; Enabling L0S\n");
 +      }
 +      trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
 +}
 +
 +/*
 + * Start up NIC's basic functionality after it has been reset
 + * (e.g. after platform boot, or shutdown via iwl_apm_stop())
 + * NOTE:  This does not load uCode nor start the embedded processor
 + */
 +static int iwl_apm_init(struct iwl_trans *trans)
 +{
 +      int ret = 0;
 +      IWL_DEBUG_INFO(trans, "Init card's basic functions\n");
 +
 +      /*
 +       * Use "set_bit" below rather than "write", to preserve any hardware
 +       * bits already set by default after reset.
 +       */
 +
 +      /* Disable L0S exit timer (platform NMI Work/Around) */
 +      iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS,
 +                        CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
 +
 +      /*
 +       * Disable L0s without affecting L1;
 +       *  don't wait for ICH L0s (ICH bug W/A)
 +       */
 +      iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS,
 +                        CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
 +
 +      /* Set FH wait threshold to maximum (HW error during stress W/A) */
 +      iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
 +
 +      /*
 +       * Enable HAP INTA (interrupt from management bus) to
 +       * wake device's PCI Express link L1a -> L0s
 +       */
 +      iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
 +                                  CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
 +
 +      iwl_apm_config(trans);
 +
 +      /* Configure analog phase-lock-loop before activating to D0A */
 +      if (cfg(trans)->base_params->pll_cfg_val)
 +              iwl_set_bit(trans, CSR_ANA_PLL_CFG,
 +                          cfg(trans)->base_params->pll_cfg_val);
 +
 +      /*
 +       * Set "initialization complete" bit to move adapter from
 +       * D0U* --> D0A* (powered-up active) state.
 +       */
 +      iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 +
 +      /*
 +       * Wait for clock stabilization; once stabilized, access to
 +       * device-internal resources is supported, e.g. iwl_write_prph()
 +       * and accesses to uCode SRAM.
 +       */
 +      ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
 +                      CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
 +                      CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 +      if (ret < 0) {
 +              IWL_DEBUG_INFO(trans, "Failed to init the card\n");
 +              goto out;
 +      }
 +
 +      /*
 +       * Enable DMA clock and wait for it to stabilize.
 +       *
 +       * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
 +       * do not disable clocks.  This preserves any hardware bits already
 +       * set by default in "CLK_CTRL_REG" after reset.
 +       */
 +      iwl_write_prph(trans, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
 +      udelay(20);
 +
 +      /* Disable L1-Active */
 +      iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG,
 +                        APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 +
 +      set_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status);
 +
 +out:
 +      return ret;
 +}
 +
 +static int iwl_apm_stop_master(struct iwl_trans *trans)
 +{
 +      int ret = 0;
 +
 +      /* stop device's busmaster DMA activity */
 +      iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 +
 +      ret = iwl_poll_bit(trans, CSR_RESET,
 +                      CSR_RESET_REG_FLAG_MASTER_DISABLED,
 +                      CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
 +      if (ret)
 +              IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n");
 +
 +      IWL_DEBUG_INFO(trans, "stop master\n");
 +
 +      return ret;
 +}
 +
 +static void iwl_apm_stop(struct iwl_trans *trans)
 +{
 +      IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
 +
 +      clear_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status);
 +
 +      /* Stop device's DMA activity */
 +      iwl_apm_stop_master(trans);
 +
 +      /* Reset the entire device */
 +      iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 +
 +      udelay(10);
 +
 +      /*
 +       * Clear "initialization complete" bit to move adapter from
 +       * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
 +       */
 +      iwl_clear_bit(trans, CSR_GP_CNTRL,
 +                    CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 +}
 +
  static int iwl_nic_init(struct iwl_trans *trans)
  {
        unsigned long flags;
  
        /* nic_init */
        spin_lock_irqsave(&trans->shrd->lock, flags);
 -      iwl_apm_init(priv(trans));
 +      iwl_apm_init(trans);
  
        /* Set interrupt coalescing calibration timer to default (512 usecs) */
 -      iwl_write8(bus(trans), CSR_INT_COALESCING,
 +      iwl_write8(trans, CSR_INT_COALESCING,
                IWL_HOST_INT_CALIB_TIMEOUT_DEF);
  
        spin_unlock_irqrestore(&trans->shrd->lock, flags);
  
        iwl_nic_config(priv(trans));
  
 +#ifndef CONFIG_IWLWIFI_IDI
        /* Allocate the RX queue, or reset if it is already allocated */
        iwl_rx_init(trans);
 +#endif
  
        /* Allocate or reset and init all Tx and Command queues */
        if (iwl_tx_init(trans))
  
        if (hw_params(trans).shadow_reg_enable) {
                /* enable shadow regs in HW */
 -              iwl_set_bit(bus(trans), CSR_MAC_SHADOW_REG_CTRL,
 +              iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL,
                        0x800FFFFF);
        }
  
@@@ -846,11 -672,11 +846,11 @@@ static int iwl_set_hw_ready(struct iwl_
  {
        int ret;
  
 -      iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
 +      iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
                CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
  
        /* See if we got it */
 -      ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
 +      ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG,
                                CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
                                CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
                                HW_READY_TIMEOUT);
  }
  
  /* Note: returns standard 0/-ERROR code */
 -static int iwl_trans_pcie_prepare_card_hw(struct iwl_trans *trans)
 +static int iwl_prepare_card_hw(struct iwl_trans *trans)
  {
        int ret;
  
        IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n");
  
        ret = iwl_set_hw_ready(trans);
 +      /* If the card is ready, exit 0 */
        if (ret >= 0)
                return 0;
  
        /* If HW is not ready, prepare the conditions to check again */
 -      iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
 +      iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
                        CSR_HW_IF_CONFIG_REG_PREPARE);
  
 -      ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
 +      ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG,
                        ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
                        CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
  
@@@ -942,79 -767,7 +942,79 @@@ static const u8 iwlagn_pan_ac_to_queue[
        7, 6, 5, 4,
  };
  
 -static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
 +/*
 + * ucode
 + */
 +static int iwl_load_section(struct iwl_trans *trans, const char *name,
 +                              struct fw_desc *image, u32 dst_addr)
 +{
 +      dma_addr_t phy_addr = image->p_addr;
 +      u32 byte_cnt = image->len;
 +      int ret;
 +
 +      trans->ucode_write_complete = 0;
 +
 +      iwl_write_direct32(trans,
 +              FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
 +              FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
 +
 +      iwl_write_direct32(trans,
 +              FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
 +
 +      iwl_write_direct32(trans,
 +              FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
 +              phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
 +
 +      iwl_write_direct32(trans,
 +              FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
 +              (iwl_get_dma_hi_addr(phy_addr)
 +                      << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
 +
 +      iwl_write_direct32(trans,
 +              FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
 +              1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
 +              1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
 +              FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
 +
 +      iwl_write_direct32(trans,
 +              FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
 +              FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE       |
 +              FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE    |
 +              FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
 +
 +      IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name);
 +      ret = wait_event_timeout(trans->shrd->wait_command_queue,
 +                               trans->ucode_write_complete, 5 * HZ);
 +      if (!ret) {
 +              IWL_ERR(trans, "Could not load the %s uCode section\n",
 +                      name);
 +              return -ETIMEDOUT;
 +      }
 +
 +      return 0;
 +}
 +
 +static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image)
 +{
 +      int ret = 0;
 +
 +      ret = iwl_load_section(trans, "INST", &image->code,
 +                                 IWLAGN_RTC_INST_LOWER_BOUND);
 +      if (ret)
 +              return ret;
 +
 +      ret = iwl_load_section(trans, "DATA", &image->data,
 +                                  IWLAGN_RTC_DATA_LOWER_BOUND);
 +      if (ret)
 +              return ret;
 +
 +      /* Remove all resets to allow NIC to operate */
 +      iwl_write32(trans, CSR_RESET, 0);
 +
 +      return 0;
 +}
 +
 +static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
  {
        int ret;
        struct iwl_trans_pcie *trans_pcie =
        trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE;
  
        if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
 -           iwl_trans_pcie_prepare_card_hw(trans)) {
 +           iwl_prepare_card_hw(trans)) {
                IWL_WARN(trans, "Exit HW not ready\n");
                return -EIO;
        }
  
        /* If platform's RF_KILL switch is NOT set to KILL */
 -      if (iwl_read32(bus(trans), CSR_GP_CNTRL) &
 +      if (iwl_read32(trans, CSR_GP_CNTRL) &
                        CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
                clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
        else
                return -ERFKILL;
        }
  
 -      iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF);
 +      iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
  
        ret = iwl_nic_init(trans);
        if (ret) {
        }
  
        /* make sure rfkill handshake bits are cleared */
 -      iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 -      iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR,
 +      iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 +      iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
  
        /* clear (again), then enable host interrupts */
 -      iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF);
 +      iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
        iwl_enable_interrupts(trans);
  
        /* really make sure rfkill handshake bits are cleared */
 -      iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 -      iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 +      iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 +      iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 +
 +      /* Load the given image to the HW */
 +      iwl_load_given_ucode(trans, fw);
  
        return 0;
  }
   */
  static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
  {
 -      iwl_write_prph(bus(trans), SCD_TXFACT, mask);
 +      iwl_write_prph(trans, SCD_TXFACT, mask);
  }
  
 -static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
 +static void iwl_tx_start(struct iwl_trans *trans)
  {
        const struct queue_to_fifo_ac *queue_to_fifo;
        struct iwl_trans_pcie *trans_pcie =
        spin_lock_irqsave(&trans->shrd->lock, flags);
  
        trans_pcie->scd_base_addr =
 -              iwl_read_prph(bus(trans), SCD_SRAM_BASE_ADDR);
 +              iwl_read_prph(trans, SCD_SRAM_BASE_ADDR);
        a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND;
        /* reset conext data memory */
        for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND;
                a += 4)
 -              iwl_write_targ_mem(bus(trans), a, 0);
 +              iwl_write_targ_mem(trans, a, 0);
        /* reset tx status memory */
        for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND;
                a += 4)
 -              iwl_write_targ_mem(bus(trans), a, 0);
 +              iwl_write_targ_mem(trans, a, 0);
        for (; a < trans_pcie->scd_base_addr +
               SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num);
               a += 4)
 -              iwl_write_targ_mem(bus(trans), a, 0);
 +              iwl_write_targ_mem(trans, a, 0);
  
 -      iwl_write_prph(bus(trans), SCD_DRAM_BASE_ADDR,
 +      iwl_write_prph(trans, SCD_DRAM_BASE_ADDR,
                       trans_pcie->scd_bc_tbls.dma >> 10);
  
        /* Enable DMA channel */
        for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++)
 -              iwl_write_direct32(bus(trans), FH_TCSR_CHNL_TX_CONFIG_REG(chan),
 +              iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
                                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
                                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
  
        /* Update FH chicken bits */
 -      reg_val = iwl_read_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG);
 -      iwl_write_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG,
 +      reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG);
 +      iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG,
                           reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
  
 -      iwl_write_prph(bus(trans), SCD_QUEUECHAIN_SEL,
 +      iwl_write_prph(trans, SCD_QUEUECHAIN_SEL,
                SCD_QUEUECHAIN_SEL_ALL(trans));
 -      iwl_write_prph(bus(trans), SCD_AGGR_SEL, 0);
 +      iwl_write_prph(trans, SCD_AGGR_SEL, 0);
  
        /* initiate the queues */
        for (i = 0; i < hw_params(trans).max_txq_num; i++) {
 -              iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(i), 0);
 -              iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, 0 | (i << 8));
 -              iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr +
 +              iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0);
 +              iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8));
 +              iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
                                SCD_CONTEXT_QUEUE_OFFSET(i), 0);
 -              iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr +
 +              iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
                                SCD_CONTEXT_QUEUE_OFFSET(i) +
                                sizeof(u32),
                                ((SCD_WIN_SIZE <<
                                SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
        }
  
 -      iwl_write_prph(bus(trans), SCD_INTERRUPT_MASK,
 +      iwl_write_prph(trans, SCD_INTERRUPT_MASK,
                        IWL_MASK(0, hw_params(trans).max_txq_num));
  
        /* Activate all Tx DMA/FIFO channels */
        spin_unlock_irqrestore(&trans->shrd->lock, flags);
  
        /* Enable L1-Active */
 -      iwl_clear_bits_prph(bus(trans), APMG_PCIDEV_STT_REG,
 +      iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
                          APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
  }
  
 +static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans)
 +{
 +      iwl_reset_ict(trans);
 +      iwl_tx_start(trans);
 +}
 +
  /**
   * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
   */
@@@ -1220,14 -964,14 +1220,14 @@@ static int iwl_trans_tx_stop(struct iwl
  
        /* Stop each Tx DMA channel, and wait for it to be idle */
        for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
 -              iwl_write_direct32(bus(trans),
 +              iwl_write_direct32(trans,
                                   FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
 -              if (iwl_poll_direct_bit(bus(trans), FH_TSSR_TX_STATUS_REG,
 +              if (iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG,
                                    FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
                                    1000))
                        IWL_ERR(trans, "Failing on timeout while stopping"
                            " DMA channel %d [0x%08x]", ch,
 -                          iwl_read_direct32(bus(trans),
 +                          iwl_read_direct32(trans,
                                              FH_TSSR_TX_STATUS_REG));
        }
        spin_unlock_irqrestore(&trans->shrd->lock, flags);
@@@ -1266,21 -1010,20 +1266,21 @@@ static void iwl_trans_pcie_stop_device(
         */
        if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) {
                iwl_trans_tx_stop(trans);
 +#ifndef CONFIG_IWLWIFI_IDI
                iwl_trans_rx_stop(trans);
 -
 +#endif
                /* Power-down device's busmaster DMA clocks */
 -              iwl_write_prph(bus(trans), APMG_CLK_DIS_REG,
 +              iwl_write_prph(trans, APMG_CLK_DIS_REG,
                               APMG_CLK_VAL_DMA_CLK_RQT);
                udelay(5);
        }
  
        /* Make sure (redundant) we've released our request to stay awake */
 -      iwl_clear_bit(bus(trans), CSR_GP_CNTRL,
 +      iwl_clear_bit(trans, CSR_GP_CNTRL,
                        CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
  
        /* Stop the device, and put it in low power state */
 -      iwl_apm_stop(priv(trans));
 +      iwl_apm_stop(trans);
  
        /* Upon stop, the APM issues an interrupt if HW RF kill is set.
         * Clean again the interrupt here
        spin_unlock_irqrestore(&trans->shrd->lock, flags);
  
        /* wait to make sure we flush pending tasklet*/
 -      synchronize_irq(bus(trans)->irq);
 +      synchronize_irq(trans->irq);
        tasklet_kill(&trans_pcie->irq_tasklet);
  
        /* stop and reset the on-board processor */
 -      iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 +      iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
  }
  
  static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
  
        /* Physical address of this Tx command's header (not MAC header!),
         * within command buffer array. */
 -      txcmd_phys = dma_map_single(bus(trans)->dev,
 +      txcmd_phys = dma_map_single(trans->dev,
                                    &dev_cmd->hdr, firstlen,
                                    DMA_BIDIRECTIONAL);
 -      if (unlikely(dma_mapping_error(bus(trans)->dev, txcmd_phys)))
 +      if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
                return -1;
        dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
        dma_unmap_len_set(out_meta, len, firstlen);
         * if any (802.11 null frames have no payload). */
        secondlen = skb->len - hdr_len;
        if (secondlen > 0) {
 -              phys_addr = dma_map_single(bus(trans)->dev, skb->data + hdr_len,
 +              phys_addr = dma_map_single(trans->dev, skb->data + hdr_len,
                                           secondlen, DMA_TO_DEVICE);
 -              if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) {
 -                      dma_unmap_single(bus(trans)->dev,
 +              if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
 +                      dma_unmap_single(trans->dev,
                                         dma_unmap_addr(out_meta, mapping),
                                         dma_unmap_len(out_meta, len),
                                         DMA_BIDIRECTIONAL);
                                offsetof(struct iwl_tx_cmd, scratch);
  
        /* take back ownership of DMA buffer to enable update */
 -      dma_sync_single_for_cpu(bus(trans)->dev, txcmd_phys, firstlen,
 +      dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,
                        DMA_BIDIRECTIONAL);
        tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
        tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
        /* Set up entry for this TFD in Tx byte-count array */
        iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
  
 -      dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen,
 +      dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
                        DMA_BIDIRECTIONAL);
  
        trace_iwlwifi_dev_tx(priv(trans),
        return 0;
  }
  
 -static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans)
 -{
 -      /* Remove all resets to allow NIC to operate */
 -      iwl_write32(bus(trans), CSR_RESET, 0);
 -}
 -
 -static int iwl_trans_pcie_request_irq(struct iwl_trans *trans)
 +static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
  {
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
  
        trans_pcie->inta_mask = CSR_INI_SET_MASK;
  
 -      tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long))
 -              iwl_irq_tasklet, (unsigned long)trans);
 +      if (!trans_pcie->irq_requested) {
 +              tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long))
 +                      iwl_irq_tasklet, (unsigned long)trans);
  
 -      iwl_alloc_isr_ict(trans);
 +              iwl_alloc_isr_ict(trans);
 +
 +              err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED,
 +                      DRV_NAME, trans);
 +              if (err) {
 +                      IWL_ERR(trans, "Error allocating IRQ %d\n",
 +                              trans->irq);
 +                      goto error;
 +              }
  
 -      err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED,
 -              DRV_NAME, trans);
 +              INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish);
 +              trans_pcie->irq_requested = true;
 +      }
 +
 +      err = iwl_prepare_card_hw(trans);
        if (err) {
 -              IWL_ERR(trans, "Error allocating IRQ %d\n", bus(trans)->irq);
 -              iwl_free_isr_ict(trans);
 -              return err;
 +              IWL_ERR(trans, "Error while preparing HW: %d", err);
 +              goto err_free_irq;
        }
  
 -      INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish);
 -      return 0;
 +      iwl_apm_init(trans);
 +
 +      /* If platform's RF_KILL switch is NOT set to KILL */
 +      if (iwl_read32(trans,
 +                      CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
 +              clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
 +      else
 +              set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
 +
 +      iwl_set_hw_rfkill_state(priv(trans),
 +                              test_bit(STATUS_RF_KILL_HW,
 +                                       &trans->shrd->status));
 +
 +      return err;
 +
 +err_free_irq:
 +      free_irq(trans->irq, trans);
 +error:
 +      iwl_free_isr_ict(trans);
 +      tasklet_kill(&trans_pcie->irq_tasklet);
 +      return err;
 +}
 +
 +static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans)
 +{
 +      iwl_apm_stop(trans);
 +
 +      iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
 +
 +      /* Even if we stop the HW, we still want the RF kill interrupt */
 +      IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
 +      iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
  }
  
  static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
        txq->time_stamp = jiffies;
  
        if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE &&
+                    tid != IWL_TID_NON_QOS &&
                     txq_id != trans_pcie->agg_txq[sta_id][tid])) {
                /*
                 * FIXME: this is a uCode bug which need to be addressed,
        return 0;
  }
  
 +static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val)
 +{
 +      iowrite8(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
 +}
 +
 +static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val)
 +{
 +      iowrite32(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
 +}
 +
 +static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs)
 +{
 +      u32 val = ioread32(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
 +      return val;
 +}
 +
  static void iwl_trans_pcie_free(struct iwl_trans *trans)
  {
 +      struct iwl_trans_pcie *trans_pcie =
 +              IWL_TRANS_GET_PCIE_TRANS(trans);
 +
        iwl_calib_free_results(trans);
        iwl_trans_pcie_tx_free(trans);
 +#ifndef CONFIG_IWLWIFI_IDI
        iwl_trans_pcie_rx_free(trans);
 -      free_irq(bus(trans)->irq, trans);
 -      iwl_free_isr_ict(trans);
 +#endif
 +      if (trans_pcie->irq_requested == true) {
 +              free_irq(trans->irq, trans);
 +              iwl_free_isr_ict(trans);
 +      }
 +
 +      pci_disable_msi(trans_pcie->pci_dev);
 +      pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base);
 +      pci_release_regions(trans_pcie->pci_dev);
 +      pci_disable_device(trans_pcie->pci_dev);
 +
        trans->shrd->trans = NULL;
        kfree(trans);
  }
@@@ -1635,10 -1315,10 +1636,10 @@@ static int iwl_trans_pcie_suspend(struc
         * things already :-)
         */
        if (!trans->shrd->wowlan) {
 -              iwl_apm_stop(priv(trans));
 +              iwl_apm_stop(trans);
        } else {
                iwl_disable_interrupts(trans);
 -              iwl_clear_bit(bus(trans), CSR_GP_CNTRL,
 +              iwl_clear_bit(trans, CSR_GP_CNTRL,
                              CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
        }
  
@@@ -1651,7 -1331,7 +1652,7 @@@ static int iwl_trans_pcie_resume(struc
  
        iwl_enable_interrupts(trans);
  
 -      if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) &
 +      if (!(iwl_read32(trans, CSR_GP_CNTRL) &
                                CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
                hw_rfkill = true;
  
@@@ -1684,6 -1364,25 +1685,6 @@@ static void iwl_trans_pcie_wake_any_que
        }
  }
  
 -const struct iwl_trans_ops trans_ops_pcie;
 -
 -static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd)
 -{
 -      struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) +
 -                                            sizeof(struct iwl_trans_pcie),
 -                                            GFP_KERNEL);
 -      if (iwl_trans) {
 -              struct iwl_trans_pcie *trans_pcie =
 -                      IWL_TRANS_GET_PCIE_TRANS(iwl_trans);
 -              iwl_trans->ops = &trans_ops_pcie;
 -              iwl_trans->shrd = shrd;
 -              trans_pcie->trans = iwl_trans;
 -              spin_lock_init(&iwl_trans->hcmd_lock);
 -      }
 -
 -      return iwl_trans;
 -}
 -
  static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id,
                                      const char *msg)
  {
@@@ -1747,9 -1446,9 +1748,9 @@@ static int iwl_trans_pcie_check_stuck_q
                IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
                        q->read_ptr, q->write_ptr);
                IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n",
 -                      iwl_read_prph(bus(trans), SCD_QUEUE_RDPTR(cnt))
 +                      iwl_read_prph(trans, SCD_QUEUE_RDPTR(cnt))
                                & (TFD_QUEUE_SIZE_MAX - 1),
 -                      iwl_read_prph(bus(trans), SCD_QUEUE_WRPTR(cnt)));
 +                      iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt)));
                return 1;
        }
  
@@@ -1803,7 -1502,7 +1804,7 @@@ int iwl_dump_fh(struct iwl_trans *trans
                        pos += scnprintf(*buf + pos, bufsz - pos,
                                "  %34s: 0X%08x\n",
                                get_fh_string(fh_tbl[i]),
 -                              iwl_read_direct32(bus(trans), fh_tbl[i]));
 +                              iwl_read_direct32(trans, fh_tbl[i]));
                }
                return pos;
        }
        for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) {
                IWL_ERR(trans, "  %34s: 0X%08x\n",
                        get_fh_string(fh_tbl[i]),
 -                      iwl_read_direct32(bus(trans), fh_tbl[i]));
 +                      iwl_read_direct32(trans, fh_tbl[i]));
        }
        return 0;
  }
@@@ -1882,7 -1581,7 +1883,7 @@@ void iwl_dump_csr(struct iwl_trans *tra
        for (i = 0; i <  ARRAY_SIZE(csr_tbl); i++) {
                IWL_ERR(trans, "  %25s: 0X%08x\n",
                        get_csr_string(csr_tbl[i]),
 -                      iwl_read32(bus(trans), csr_tbl[i]));
 +                      iwl_read32(trans, csr_tbl[i]));
        }
  }
  
@@@ -2203,12 -1902,13 +2204,12 @@@ static int iwl_trans_pcie_dbgfs_registe
  #endif /*CONFIG_IWLWIFI_DEBUGFS */
  
  const struct iwl_trans_ops trans_ops_pcie = {
 -      .alloc = iwl_trans_pcie_alloc,
 -      .request_irq = iwl_trans_pcie_request_irq,
 -      .start_device = iwl_trans_pcie_start_device,
 -      .prepare_card_hw = iwl_trans_pcie_prepare_card_hw,
 +      .start_hw = iwl_trans_pcie_start_hw,
 +      .stop_hw = iwl_trans_pcie_stop_hw,
 +      .fw_alive = iwl_trans_pcie_fw_alive,
 +      .start_fw = iwl_trans_pcie_start_fw,
        .stop_device = iwl_trans_pcie_stop_device,
  
 -      .tx_start = iwl_trans_pcie_tx_start,
        .wake_any_queue = iwl_trans_pcie_wake_any_queue,
  
        .send_cmd = iwl_trans_pcie_send_cmd,
        .tx_agg_alloc = iwl_trans_pcie_tx_agg_alloc,
        .tx_agg_setup = iwl_trans_pcie_tx_agg_setup,
  
 -      .kick_nic = iwl_trans_pcie_kick_nic,
 -
        .free = iwl_trans_pcie_free,
        .stop_queue = iwl_trans_pcie_stop_queue,
  
        .suspend = iwl_trans_pcie_suspend,
        .resume = iwl_trans_pcie_resume,
  #endif
 +      .write8 = iwl_trans_pcie_write8,
 +      .write32 = iwl_trans_pcie_write32,
 +      .read32 = iwl_trans_pcie_read32,
  };
 +
 +struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
 +                                     struct pci_dev *pdev,
 +                                     const struct pci_device_id *ent)
 +{
 +      struct iwl_trans_pcie *trans_pcie;
 +      struct iwl_trans *trans;
 +      u16 pci_cmd;
 +      int err;
 +
 +      trans = kzalloc(sizeof(struct iwl_trans) +
 +                           sizeof(struct iwl_trans_pcie), GFP_KERNEL);
 +
 +      if (WARN_ON(!trans))
 +              return NULL;
 +
 +      trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 +
 +      trans->ops = &trans_ops_pcie;
 +      trans->shrd = shrd;
 +      trans_pcie->trans = trans;
 +      spin_lock_init(&trans->hcmd_lock);
 +
 +      /* W/A - seems to solve weird behavior. We need to remove this if we
 +       * don't want to stay in L1 all the time. This wastes a lot of power */
 +      pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
 +                              PCIE_LINK_STATE_CLKPM);
 +
 +      if (pci_enable_device(pdev)) {
 +              err = -ENODEV;
 +              goto out_no_pci;
 +      }
 +
 +      pci_set_master(pdev);
 +
 +      err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
 +      if (!err)
 +              err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
 +      if (err) {
 +              err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 +              if (!err)
 +                      err = pci_set_consistent_dma_mask(pdev,
 +                                                      DMA_BIT_MASK(32));
 +              /* both attempts failed: */
 +              if (err) {
 +                      dev_printk(KERN_ERR, &pdev->dev,
 +                                 "No suitable DMA available.\n");
 +                      goto out_pci_disable_device;
 +              }
 +      }
 +
 +      err = pci_request_regions(pdev, DRV_NAME);
 +      if (err) {
 +              dev_printk(KERN_ERR, &pdev->dev, "pci_request_regions failed");
 +              goto out_pci_disable_device;
 +      }
 +
 +      trans_pcie->hw_base = pci_iomap(pdev, 0, 0);
 +      if (!trans_pcie->hw_base) {
 +              dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed");
 +              err = -ENODEV;
 +              goto out_pci_release_regions;
 +      }
 +
 +      dev_printk(KERN_INFO, &pdev->dev,
 +              "pci_resource_len = 0x%08llx\n",
 +              (unsigned long long) pci_resource_len(pdev, 0));
 +      dev_printk(KERN_INFO, &pdev->dev,
 +              "pci_resource_base = %p\n", trans_pcie->hw_base);
 +
 +      dev_printk(KERN_INFO, &pdev->dev,
 +              "HW Revision ID = 0x%X\n", pdev->revision);
 +
 +      /* We disable the RETRY_TIMEOUT register (0x41) to keep
 +       * PCI Tx retries from interfering with C3 CPU state */
 +      pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
 +
 +      err = pci_enable_msi(pdev);
 +      if (err)
 +              dev_printk(KERN_ERR, &pdev->dev,
 +                      "pci_enable_msi failed(0X%x)", err);
 +
 +      trans->dev = &pdev->dev;
 +      trans->irq = pdev->irq;
 +      trans_pcie->pci_dev = pdev;
 +      trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
 +      trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
 +      snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
 +               "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
 +
 +      /* TODO: Move this away, not needed if not MSI */
 +      /* enable rfkill interrupt: hw bug w/a */
 +      pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
 +      if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
 +              pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
 +              pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
 +      }
 +
 +      return trans;
 +
 +out_pci_release_regions:
 +      pci_release_regions(pdev);
 +out_pci_disable_device:
 +      pci_disable_device(pdev);
 +out_no_pci:
 +      kfree(trans);
 +      return NULL;
 +}
 +
index 478d2f12c0244863cde480678c50b198791f0912,5b2972b43b0e23ee62e94d255146d6be1787634d..8d8ee639fe5607ccab8502678bc0f68598cbd85d
@@@ -79,7 -79,7 +79,7 @@@ static in
  mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
                         u8 key_index, bool pairwise, const u8 *mac_addr)
  {
 -      struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 +      struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
  
        if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) {
                wiphy_err(wiphy, "deleting the crypto keys\n");
@@@ -122,7 -122,7 +122,7 @@@ mwifiex_cfg80211_set_power_mgmt(struct 
                                struct net_device *dev,
                                bool enabled, int timeout)
  {
 -      struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 +      struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
        u32 ps_mode;
  
        if (timeout)
@@@ -143,7 -143,7 +143,7 @@@ mwifiex_cfg80211_set_default_key(struc
                                 u8 key_index, bool unicast,
                                 bool multicast)
  {
 -      struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 +      struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
  
        /* Return if WEP key not configured */
        if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED)
@@@ -165,7 -165,7 +165,7 @@@ mwifiex_cfg80211_add_key(struct wiphy *
                         u8 key_index, bool pairwise, const u8 *mac_addr,
                         struct key_params *params)
  {
 -      struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 +      struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
  
        if (mwifiex_set_encode(priv, params->key, params->key_len,
                                                        key_index, 0)) {
@@@ -376,12 -376,7 +376,12 @@@ mwifiex_cfg80211_set_channel(struct wip
                             struct ieee80211_channel *chan,
                             enum nl80211_channel_type channel_type)
  {
 -      struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 +      struct mwifiex_private *priv;
 +
 +      if (dev)
 +              priv = mwifiex_netdev_get_priv(dev);
 +      else
 +              priv = mwifiex_cfg80211_get_priv(wiphy);
  
        if (priv->media_connected) {
                wiphy_err(wiphy, "This setting is valid only when station "
@@@ -539,11 -534,6 +539,11 @@@ mwifiex_dump_station_info(struct mwifie
                ret = -EFAULT;
        }
  
 +      /* Get DTIM period information from firmware */
 +      mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
 +                            HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
 +                            &priv->dtim_period);
 +
        /*
         * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid
         * MCS index values for us are 0 to 7.
        /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */
        sinfo->txrate.legacy = rate.rate * 5;
  
 +      if (priv->bss_mode == NL80211_IFTYPE_STATION) {
 +              sinfo->filled |= STATION_INFO_BSS_PARAM;
 +              sinfo->bss_param.flags = 0;
 +              if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
 +                                              WLAN_CAPABILITY_SHORT_PREAMBLE)
 +                      sinfo->bss_param.flags |=
 +                                      BSS_PARAM_FLAGS_SHORT_PREAMBLE;
 +              if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
 +                                              WLAN_CAPABILITY_SHORT_SLOT_TIME)
 +                      sinfo->bss_param.flags |=
 +                                      BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
 +              sinfo->bss_param.dtim_period = priv->dtim_period;
 +              sinfo->bss_param.beacon_interval =
 +                      priv->curr_bss_params.bss_descriptor.beacon_period;
 +      }
 +
        return ret;
  }
  
@@@ -867,7 -841,12 +867,12 @@@ mwifiex_cfg80211_assoc(struct mwifiex_p
                ret = mwifiex_set_rf_channel(priv, channel,
                                                priv->adapter->channel_type);
  
-       ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);  /* Disable keys */
+       /* As this is new association, clear locally stored
+        * keys and security related flags */
+       priv->sec_info.wpa_enabled = false;
+       priv->sec_info.wpa2_enabled = false;
+       priv->wep_key_curr_index = 0;
+       ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);
  
        if (mode == NL80211_IFTYPE_ADHOC) {
                /* "privacy" is set only for ad-hoc mode */
                        dev_dbg(priv->adapter->dev,
                                "info: setting wep encryption"
                                " with key len %d\n", sme->key_len);
+                       priv->wep_key_curr_index = sme->key_idx;
                        ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
                                                        sme->key_idx, 0);
                }
@@@ -1030,7 -1010,7 +1036,7 @@@ static in
  mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
                           struct cfg80211_ibss_params *params)
  {
 -      struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 +      struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
        int ret = 0;
  
        if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
@@@ -1068,7 -1048,7 +1074,7 @@@ done
  static int
  mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
  {
 -      struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 +      struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
  
        wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
                        priv->cfg_bssid);
@@@ -1243,6 -1223,7 +1249,6 @@@ struct net_device *mwifiex_add_virtual_
                priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
                priv->bss_priority = 0;
                priv->bss_role = MWIFIEX_BSS_ROLE_STA;
 -              priv->bss_index = 0;
                priv->bss_num = 0;
  
                break;
@@@ -1306,7 -1287,10 +1312,7 @@@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_i
   */
  int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
  {
 -      struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 -
 -      if (!priv || !dev)
 -              return 0;
 +      struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
  
  #ifdef CONFIG_DEBUG_FS
        mwifiex_dev_debugfs_remove(priv);
index 83cc10fca4bd9911d11d4eb2ea69b4b289cbefde,1d0ec57a0143d8f0a2b15cfbb2220ba065171045..ca59cc0d013ef7785647a1c6fe075ecf9d5b7556
@@@ -280,7 -280,6 +280,7 @@@ static void mwifiex_init_adapter(struc
        adapter->adhoc_awake_period = 0;
        memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
        adapter->arp_filter_size = 0;
 +      adapter->channel_type = NL80211_CHAN_HT20;
  }
  
  /*
@@@ -383,7 -382,8 +383,8 @@@ mwifiex_free_adapter(struct mwifiex_ada
  
        adapter->if_ops.cleanup_if(adapter);
  
-       dev_kfree_skb_any(adapter->sleep_cfm);
+       if (adapter->sleep_cfm)
+               dev_kfree_skb_any(adapter->sleep_cfm);
  }
  
  /*
@@@ -527,9 -527,8 +528,9 @@@ static void mwifiex_delete_bss_prio_tbl
                cur = &adapter->bss_prio_tbl[i].bss_prio_cur;
                lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
                dev_dbg(adapter->dev, "info: delete BSS priority table,"
 -                              " index = %d, i = %d, head = %p, cur = %p\n",
 -                            priv->bss_index, i, head, *cur);
 +                              " bss_type = %d, bss_num = %d, i = %d,"
 +                              " head = %p, cur = %p\n",
 +                            priv->bss_type, priv->bss_num, i, head, *cur);
                if (*cur) {
                        spin_lock_irqsave(lock, flags);
                        if (list_empty(head)) {
index 80e44566bf6ecd15bf093ccb9c597088c6ed91c9,b728f54451e48e65bf4bef4841d0bd69f2e03492..790a3796483c9421a533033f591f6a9e4a43936a
@@@ -424,8 -424,8 +424,8 @@@ mwifiex_hard_start_xmit(struct sk_buff 
        struct sk_buff *new_skb;
        struct mwifiex_txinfo *tx_info;
  
 -      dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n",
 -                              jiffies, priv->bss_index);
 +      dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
 +                              jiffies, priv->bss_type, priv->bss_num);
  
        if (priv->adapter->surprise_removed) {
                kfree_skb(skb);
        }
  
        tx_info = MWIFIEX_SKB_TXCB(skb);
 -      tx_info->bss_index = priv->bss_index;
 +      tx_info->bss_num = priv->bss_num;
 +      tx_info->bss_type = priv->bss_type;
        mwifiex_fill_buffer(skb);
  
 -      mwifiex_wmm_add_buf_txqueue(priv->adapter, skb);
 +      mwifiex_wmm_add_buf_txqueue(priv, skb);
        atomic_inc(&priv->adapter->tx_pending);
  
        if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
@@@ -532,8 -531,8 +532,8 @@@ mwifiex_tx_timeout(struct net_device *d
  {
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
  
 -      dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n",
 -                              jiffies, priv->bss_index);
 +      dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n",
 +                              jiffies, priv->bss_type, priv->bss_num);
        mwifiex_set_trans_start(dev);
        priv->num_tx_timeout++;
  }
@@@ -605,6 -604,18 +605,6 @@@ int is_command_pending(struct mwifiex_a
        return !is_cmd_pend_q_empty;
  }
  
 -/*
 - * This function returns the correct private structure pointer based
 - * upon the BSS number.
 - */
 -struct mwifiex_private *
 -mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index)
 -{
 -      if (!adapter || (bss_index >= adapter->priv_num))
 -              return NULL;
 -      return adapter->priv[bss_index];
 -}
 -
  /*
   * This is the main work queue function.
   *
@@@ -811,7 -822,9 +811,9 @@@ int mwifiex_remove_card(struct mwifiex_
                        continue;
  
                rtnl_lock();
-               mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
+               if (priv->wdev && priv->netdev)
+                       mwifiex_del_virtual_intf(priv->wdev->wiphy,
+                                                priv->netdev);
                rtnl_unlock();
        }
  
        if (!priv)
                goto exit_remove;
  
-       wiphy_unregister(priv->wdev->wiphy);
-       wiphy_free(priv->wdev->wiphy);
-       kfree(priv->wdev);
+       if (priv->wdev) {
+               wiphy_unregister(priv->wdev->wiphy);
+               wiphy_free(priv->wdev->wiphy);
+               kfree(priv->wdev);
+       }
  
        mwifiex_terminate_workqueue(adapter);
  
index 52728be65271847b9b9e61fcd53183abe96e1b4f,7bef66def10c469166f6689adefbfe1d477bf034..772d4aec303ad9661588e661f36229ebb284a75d
@@@ -411,6 -411,18 +411,6 @@@ int rt2800_load_firmware(struct rt2x00_
                rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002);
        }
  
 -      /*
 -       * Disable DMA, will be reenabled later when enabling
 -       * the radio.
 -       */
 -      rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
 -      rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
 -      rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
 -      rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
 -      rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
 -      rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
 -      rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
 -
        /*
         * Write firmware to the device.
         */
                return -EBUSY;
        }
  
 +      /*
 +       * Disable DMA, will be reenabled later when enabling
 +       * the radio.
 +       */
 +      rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
 +      rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
 +      rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
 +      rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
 +
        /*
         * Initialize firmware.
         */
        rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
        rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
 +      if (rt2x00_is_usb(rt2x00dev))
 +              rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
        msleep(1);
  
        return 0;
@@@ -513,9 -514,9 +513,9 @@@ EXPORT_SYMBOL_GPL(rt2800_write_tx_data)
  
  static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2)
  {
-       int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
-       int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
-       int rssi2 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI2);
+       s8 rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0);
+       s8 rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1);
+       s8 rssi2 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI2);
        u16 eeprom;
        u8 offset0;
        u8 offset1;
         * which gives less energy...
         */
        rssi0 = max(rssi0, rssi1);
-       return max(rssi0, rssi2);
+       return (int)max(rssi0, rssi2);
  }
  
  void rt2800_process_rxwi(struct queue_entry *entry,
@@@ -1645,14 -1646,10 +1645,14 @@@ static void rt2800_config_channel_rf3xx
                                         struct rf_channel *rf,
                                         struct channel_info *info)
  {
 -      u8 rfcsr;
 +      struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
 +      u8 rfcsr, calib_tx, calib_rx;
  
        rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1);
 -      rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3);
 +
 +      rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
 +      rt2x00_set_field8(&rfcsr, RFCSR3_K, rf->rf3);
 +      rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
  
        rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
        rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2);
        rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2);
        rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
  
 +      rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
 +      rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
 +      rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
 +      if (rt2x00_rt(rt2x00dev, RT3390)) {
 +              rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD,
 +                                rt2x00dev->default_ant.rx_chain_num == 1);
 +              rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD,
 +                                rt2x00dev->default_ant.tx_chain_num == 1);
 +      } else {
 +              rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
 +              rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
 +              rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
 +              rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
 +
 +              switch (rt2x00dev->default_ant.tx_chain_num) {
 +              case 1:
 +                      rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
 +                      /* fall through */
 +              case 2:
 +                      rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
 +                      break;
 +              }
 +
 +              switch (rt2x00dev->default_ant.rx_chain_num) {
 +              case 1:
 +                      rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
 +                      /* fall through */
 +              case 2:
 +                      rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
 +                      break;
 +              }
 +      }
 +      rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
 +
 +      rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
 +      rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
 +      rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
 +      msleep(1);
 +      rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
 +      rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
 +
        rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
        rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
        rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
  
 -      rt2800_rfcsr_write(rt2x00dev, 24,
 -                            rt2x00dev->calibration[conf_is_ht40(conf)]);
 +      if (rt2x00_rt(rt2x00dev, RT3390)) {
 +              calib_tx = conf_is_ht40(conf) ? 0x68 : 0x4f;
 +              calib_rx = conf_is_ht40(conf) ? 0x6f : 0x4f;
 +      } else {
 +              if (conf_is_ht40(conf)) {
 +                      calib_tx = drv_data->calibration_bw40;
 +                      calib_rx = drv_data->calibration_bw40;
 +              } else {
 +                      calib_tx = drv_data->calibration_bw20;
 +                      calib_rx = drv_data->calibration_bw20;
 +              }
 +      }
 +
 +      rt2800_rfcsr_read(rt2x00dev, 24, &rfcsr);
 +      rt2x00_set_field8(&rfcsr, RFCSR24_TX_CALIB, calib_tx);
 +      rt2800_rfcsr_write(rt2x00dev, 24, rfcsr);
 +
 +      rt2800_rfcsr_read(rt2x00dev, 31, &rfcsr);
 +      rt2x00_set_field8(&rfcsr, RFCSR31_RX_CALIB, calib_rx);
 +      rt2800_rfcsr_write(rt2x00dev, 31, rfcsr);
  
        rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
        rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
        rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
 +
 +      rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
 +      rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
 +      rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
 +      msleep(1);
 +      rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
 +      rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
  }
  
  static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
                                         struct rf_channel *rf,
                                         struct channel_info *info)
  {
 +      struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
        u8 rfcsr;
        u32 reg;
  
        if (rf->channel <= 14) {
 -              rt2800_bbp_write(rt2x00dev, 25, 0x15);
 -              rt2800_bbp_write(rt2x00dev, 26, 0x85);
 +              rt2800_bbp_write(rt2x00dev, 25, drv_data->bbp25);
 +              rt2800_bbp_write(rt2x00dev, 26, drv_data->bbp26);
        } else {
                rt2800_bbp_write(rt2x00dev, 25, 0x09);
                rt2800_bbp_write(rt2x00dev, 26, 0xff);
        if (rf->channel <= 14) {
                rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3);
                rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
 -                              (info->default_power1 & 0x3) |
 -                              ((info->default_power1 & 0xC) << 1));
 +                                info->default_power1);
        } else {
                rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7);
                rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
        if (rf->channel <= 14) {
                rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3);
                rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
 -                              (info->default_power2 & 0x3) |
 -                              ((info->default_power2 & 0xC) << 1));
 +                                info->default_power2);
        } else {
                rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7);
                rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
        rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
  
        rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
 -      rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
        rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
        rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
        rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
        rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
 +      rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
 +      rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
        if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
                if (rf->channel <= 14) {
                        rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
        rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
        rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
  
 -      rt2800_rfcsr_write(rt2x00dev, 24,
 -                            rt2x00dev->calibration[conf_is_ht40(conf)]);
 -      rt2800_rfcsr_write(rt2x00dev, 31,
 -                            rt2x00dev->calibration[conf_is_ht40(conf)]);
 +      if (conf_is_ht40(conf)) {
 +              rt2800_rfcsr_write(rt2x00dev, 24, drv_data->calibration_bw40);
 +              rt2800_rfcsr_write(rt2x00dev, 31, drv_data->calibration_bw40);
 +      } else {
 +              rt2800_rfcsr_write(rt2x00dev, 24, drv_data->calibration_bw20);
 +              rt2800_rfcsr_write(rt2x00dev, 31, drv_data->calibration_bw20);
 +      }
  
        if (rf->channel <= 14) {
                rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
                rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
                rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
                rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
 -              rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
 +              rfcsr = 0x4c;
 +              rt2x00_set_field8(&rfcsr, RFCSR16_TXMIXER_GAIN,
 +                                drv_data->txmixer_gain_24g);
 +              rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
                rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
                rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
                rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
                rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
                rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
        } else {
 -              rt2800_rfcsr_write(rt2x00dev, 7, 0x14);
 +              rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
 +              rt2x00_set_field8(&rfcsr, RFCSR7_BIT2, 1);
 +              rt2x00_set_field8(&rfcsr, RFCSR7_BIT3, 0);
 +              rt2x00_set_field8(&rfcsr, RFCSR7_BIT4, 1);
 +              rt2x00_set_field8(&rfcsr, RFCSR7_BITS67, 0);
 +              rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
                rt2800_rfcsr_write(rt2x00dev, 9, 0xc0);
                rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
                rt2800_rfcsr_write(rt2x00dev, 11, 0x00);
                rt2800_rfcsr_write(rt2x00dev, 15, 0x43);
 -              rt2800_rfcsr_write(rt2x00dev, 16, 0x7a);
 +              rfcsr = 0x7a;
 +              rt2x00_set_field8(&rfcsr, RFCSR16_TXMIXER_GAIN,
 +                                drv_data->txmixer_gain_5g);
 +              rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
                rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
                if (rf->channel <= 64) {
                        rt2800_rfcsr_write(rt2x00dev, 19, 0xb7);
@@@ -3330,7 -3247,6 +3330,7 @@@ static u8 rt2800_init_rx_filter(struct 
  
  static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
  {
 +      struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
        u8 rfcsr;
        u8 bbp;
        u32 reg;
         * Set RX Filter calibration for 20MHz and 40MHz
         */
        if (rt2x00_rt(rt2x00dev, RT3070)) {
 -              rt2x00dev->calibration[0] =
 +              drv_data->calibration_bw20 =
                        rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
 -              rt2x00dev->calibration[1] =
 +              drv_data->calibration_bw40 =
                        rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
        } else if (rt2x00_rt(rt2x00dev, RT3071) ||
                   rt2x00_rt(rt2x00dev, RT3090) ||
                   rt2x00_rt(rt2x00dev, RT3390) ||
                   rt2x00_rt(rt2x00dev, RT3572)) {
 -              rt2x00dev->calibration[0] =
 +              drv_data->calibration_bw20 =
                        rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
 -              rt2x00dev->calibration[1] =
 +              drv_data->calibration_bw40 =
                        rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15);
        }
  
 +      /*
 +       * Save BBP 25 & 26 values for later use in channel switching
 +       */
 +      rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25);
 +      rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26);
 +
        if (!rt2x00_rt(rt2x00dev, RT5390)) {
                /*
                 * Set back to initial state
                                      &rt2x00dev->cap_flags))
                                rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
                }
 -              rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
 -              if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1)
 -                      rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
 -                                      rt2x00_get_field16(eeprom,
 -                                              EEPROM_TXMIXER_GAIN_BG_VAL));
 +              rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
 +                                drv_data->txmixer_gain_24g);
                rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
        }
  
@@@ -3887,7 -3800,6 +3887,7 @@@ EXPORT_SYMBOL_GPL(rt2800_read_eeprom_ef
  
  int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
  {
 +      struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
        u16 word;
        u8 *mac;
        u8 default_lna_gain;
                rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
        rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
  
 +      rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
 +      if ((word & 0x00ff) != 0x00ff) {
 +              drv_data->txmixer_gain_24g =
 +                      rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
 +      } else {
 +              drv_data->txmixer_gain_24g = 0;
 +      }
 +
        rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
        if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
                rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
                                   default_lna_gain);
        rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
  
 +      rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
 +      if ((word & 0x00ff) != 0x00ff) {
 +              drv_data->txmixer_gain_5g =
 +                      rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
 +      } else {
 +              drv_data->txmixer_gain_5g = 0;
 +      }
 +
        rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
        if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
                rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
diff --combined net/mac80211/main.c
index 831a5bd44fd0cf96210ac1b7533b0626e3a4ee05,b142bd4c239096f51fbf0e79e9b507a2bf35d1d0..2306d7514fff5bb2c82d609a859a3e826fdd6099
@@@ -155,8 -155,7 +155,8 @@@ int ieee80211_hw_config(struct ieee8021
                power = chan->max_power;
        else
                power = local->power_constr_level ?
 -                      (chan->max_power - local->power_constr_level) :
 +                      min(chan->max_power,
 +                              (chan->max_reg_power  - local->power_constr_level)) :
                        chan->max_power;
  
        if (local->user_power_level >= 0)
@@@ -199,7 -198,15 +199,7 @@@ void ieee80211_bss_info_change_notify(s
                return;
  
        if (sdata->vif.type == NL80211_IFTYPE_STATION) {
 -              /*
 -               * While not associated, claim a BSSID of all-zeroes
 -               * so that drivers don't do any weird things with the
 -               * BSSID at that time.
 -               */
 -              if (sdata->vif.bss_conf.assoc)
 -                      sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
 -              else
 -                      sdata->vif.bss_conf.bssid = zero;
 +              sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
        } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
                sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
        else if (sdata->vif.type == NL80211_IFTYPE_AP)
@@@ -527,9 -534,6 +527,9 @@@ struct ieee80211_hw *ieee80211_alloc_hw
        int priv_size, i;
        struct wiphy *wiphy;
  
 +      if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove)))
 +              return NULL;
 +
        /* Ensure 32-byte alignment of our private data and hw private data.
         * We use the wiphy priv data for both our ieee80211_local and for
         * the driver's private data
@@@ -697,9 -701,6 +697,9 @@@ int ieee80211_register_hw(struct ieee80
            )
                return -EINVAL;
  
 +      if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan)
 +              return -EINVAL;
 +
        if (hw->max_report_rates == 0)
                hw->max_report_rates = hw->max_rates;
  
                wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
                            result);
  
+       ieee80211_led_init(local);
        rtnl_lock();
  
        result = ieee80211_init_rate_ctrl_alg(local,
  
        rtnl_unlock();
  
-       ieee80211_led_init(local);
        local->network_latency_notifier.notifier_call =
                ieee80211_max_network_latency;
        result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
diff --combined net/mac80211/rx.c
index 2b5b1194dfc2324a7e6bda759d8d84c82462bcf0,5a5e504a8ffbc9cbf1d22bf8e35949311990406e..3ab85c02ef0403daacad61c3cd00d41fd2b6aadc
@@@ -611,7 -611,7 +611,7 @@@ static void ieee80211_sta_reorder_relea
        index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
                                                tid_agg_rx->buf_size;
        if (!tid_agg_rx->reorder_buf[index] &&
-           tid_agg_rx->stored_mpdu_num > 1) {
+           tid_agg_rx->stored_mpdu_num) {
                /*
                 * No buffers ready to be released, but check whether any
                 * frames in the reorder buffer have timed out.
@@@ -859,12 -859,7 +859,12 @@@ ieee80211_rx_h_check(struct ieee80211_r
                     rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
                     rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
                     (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) {
 -              if (rx->sta && rx->sta->dummy &&
 +              /*
 +               * accept port control frames from the AP even when it's not
 +               * yet marked ASSOC to prevent a race where we don't set the
 +               * assoc bit quickly enough before it sends the first frame
 +               */
 +              if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
                    ieee80211_is_data_present(hdr->frame_control)) {
                        u16 ethertype;
                        u8 *payload;
@@@ -1150,15 -1145,19 +1150,15 @@@ static void ap_sta_ps_start(struct sta_
  
  static void ap_sta_ps_end(struct sta_info *sta)
  {
 -      struct ieee80211_sub_if_data *sdata = sta->sdata;
 -
 -      atomic_dec(&sdata->bss->num_sta_ps);
 -
  #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
        printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
 -             sdata->name, sta->sta.addr, sta->sta.aid);
 +             sta->sdata->name, sta->sta.addr, sta->sta.aid);
  #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
  
        if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
  #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
                printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n",
 -                     sdata->name, sta->sta.addr, sta->sta.aid);
 +                     sta->sdata->name, sta->sta.addr, sta->sta.aid);
  #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
                return;
        }
@@@ -2181,6 -2180,9 +2181,6 @@@ ieee80211_rx_h_mgmt_check(struct ieee80
        if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
            ieee80211_is_beacon(mgmt->frame_control) &&
            !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
 -              struct ieee80211_rx_status *status;
 -
 -              status = IEEE80211_SKB_RXCB(rx->skb);
                cfg80211_report_obss_beacon(rx->local->hw.wiphy,
                                            rx->skb->data, rx->skb->len,
                                            status->freq, GFP_ATOMIC);
@@@ -2484,9 -2486,14 +2484,9 @@@ static ieee80211_rx_result debug_noinli
  ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
  {
        struct ieee80211_sub_if_data *sdata = rx->sdata;
 -      ieee80211_rx_result rxs;
        struct ieee80211_mgmt *mgmt = (void *)rx->skb->data;
        __le16 stype;
  
 -      rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb);
 -      if (rxs != RX_CONTINUE)
 -              return rxs;
 -
        stype = mgmt->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE);
  
        if (!ieee80211_vif_is_mesh(&sdata->vif) &&
                return RX_DROP_MONITOR;
  
        switch (stype) {
 +      case cpu_to_le16(IEEE80211_STYPE_AUTH):
        case cpu_to_le16(IEEE80211_STYPE_BEACON):
        case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
                /* process for all: mesh, mlme, ibss */
                break;
 +      case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
 +      case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
        case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
        case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
                if (is_multicast_ether_addr(mgmt->da) &&
                        return RX_DROP_MONITOR;
                break;
        case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
 -      case cpu_to_le16(IEEE80211_STYPE_AUTH):
                /* process only for ibss */
                if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
                        return RX_DROP_MONITOR;
@@@ -2951,7 -2956,7 +2951,7 @@@ static void __ieee80211_rx_handle_packe
        if (ieee80211_is_data(fc)) {
                prev_sta = NULL;
  
 -              for_each_sta_info_rx(local, hdr->addr2, sta, tmp) {
 +              for_each_sta_info(local, hdr->addr2, sta, tmp) {
                        if (!prev_sta) {
                                prev_sta = sta;
                                continue;
                        continue;
                }
  
 -              rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
 +              rx.sta = sta_info_get_bss(prev, hdr->addr2);
                rx.sdata = prev;
                ieee80211_prepare_and_rx_handle(&rx, skb, false);
  
        }
  
        if (prev) {
 -              rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
 +              rx.sta = sta_info_get_bss(prev, hdr->addr2);
                rx.sdata = prev;
  
                if (ieee80211_prepare_and_rx_handle(&rx, skb, true))