Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Tue, 28 Jun 2011 17:53:32 +0000 (13:53 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 28 Jun 2011 17:56:21 +0000 (13:56 -0400)
Conflicts:
drivers/net/wireless/iwlwifi/iwl-tx.c

1  2 
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/rtlwifi/pci.c
include/net/cfg80211.h
net/wireless/nl80211.c

@@@ -27,6 -27,8 +27,6 @@@
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
 -#include <linux/pci.h>
 -#include <linux/dma-mapping.h>
  #include <linux/delay.h>
  #include <linux/skbuff.h>
  #include <linux/netdevice.h>
@@@ -34,6 -36,7 +34,7 @@@
  #include <net/mac80211.h>
  #include <linux/etherdevice.h>
  #include <asm/unaligned.h>
+ #include <linux/stringify.h>
  
  #include "iwl-eeprom.h"
  #include "iwl-dev.h"
  #define IWL100_UCODE_API_MIN 5
  
  #define IWL1000_FW_PRE "iwlwifi-1000-"
- #define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
+ #define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode"
  
  #define IWL100_FW_PRE "iwlwifi-100-"
- #define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
+ #define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode"
  
  
  /*
@@@ -172,6 -175,7 +173,6 @@@ static struct iwl_lib_ops iwl1000_lib 
        .rx_handler_setup = iwlagn_rx_handler_setup,
        .setup_deferred_work = iwlagn_setup_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
 -      .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .apm_ops = {
                .init = iwl_apm_init,
        .temp_ops = {
                .temperature = iwlagn_temperature,
         },
 -      .txfifo_flush = iwlagn_txfifo_flush,
 -      .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
  };
  
  static const struct iwl_ops iwl1000_ops = {
@@@ -218,7 -224,6 +219,7 @@@ static struct iwl_base_params iwl1000_b
  static struct iwl_ht_params iwl1000_ht_params = {
        .ht_greenfield_support = true,
        .use_rts_for_aggregation = true, /* use rts/cts protection */
 +      .smps_mode = IEEE80211_SMPS_STATIC,
  };
  
  #define IWL_DEVICE_1000                                               \
@@@ -27,6 -27,8 +27,6 @@@
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
 -#include <linux/pci.h>
 -#include <linux/dma-mapping.h>
  #include <linux/delay.h>
  #include <linux/skbuff.h>
  #include <linux/netdevice.h>
@@@ -34,6 -36,7 +34,7 @@@
  #include <net/mac80211.h>
  #include <linux/etherdevice.h>
  #include <asm/unaligned.h>
+ #include <linux/stringify.h>
  
  #include "iwl-eeprom.h"
  #include "iwl-dev.h"
  #define IWL105_UCODE_API_MIN 5
  
  #define IWL2030_FW_PRE "iwlwifi-2030-"
- #define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode"
+ #define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode"
  
  #define IWL2000_FW_PRE "iwlwifi-2000-"
- #define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode"
+ #define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE __stringify(api) ".ucode"
  
  #define IWL105_FW_PRE "iwlwifi-105-"
- #define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE #api ".ucode"
+ #define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode"
  
  static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
  {
  /* NIC configuration for 2000 series */
  static void iwl2000_nic_config(struct iwl_priv *priv)
  {
 -      u16 radio_cfg;
 -
 -      radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
 -
 -      /* write radio config values to register */
 -      if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX)
 -      iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 -                      EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
 -                      EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
 -                      EEPROM_RF_CFG_DASH_MSK(radio_cfg));
 -
 -      /* set CSR_HW_CONFIG_REG for uCode use */
 -      iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 -                  CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
 -                  CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 +      iwl_rf_config(priv);
  
        if (priv->cfg->iq_invert)
                iwl_set_bit(priv, CSR_GP_DRIVER_REG,
@@@ -167,6 -184,7 +168,6 @@@ static struct iwl_lib_ops iwl2000_lib 
        .setup_deferred_work = iwlagn_bt_setup_deferred_work,
        .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
 -      .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .apm_ops = {
                .init = iwl_apm_init,
        .temp_ops = {
                .temperature = iwlagn_temperature,
        },
 -      .txfifo_flush = iwlagn_txfifo_flush,
 -      .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
  };
  
  static const struct iwl_ops iwl2000_ops = {
@@@ -27,6 -27,8 +27,6 @@@
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
 -#include <linux/pci.h>
 -#include <linux/dma-mapping.h>
  #include <linux/delay.h>
  #include <linux/sched.h>
  #include <linux/skbuff.h>
@@@ -35,6 -37,7 +35,7 @@@
  #include <net/mac80211.h>
  #include <linux/etherdevice.h>
  #include <asm/unaligned.h>
+ #include <linux/stringify.h>
  
  #include "iwl-eeprom.h"
  #include "iwl-dev.h"
  #define IWL5150_UCODE_API_MIN 1
  
  #define IWL5000_FW_PRE "iwlwifi-5000-"
- #define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode"
+ #define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode"
  
  #define IWL5150_FW_PRE "iwlwifi-5150-"
- #define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
+ #define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode"
  
  /* NIC configuration for 5000 series */
  static void iwl5000_nic_config(struct iwl_priv *priv)
  {
        unsigned long flags;
 -      u16 radio_cfg;
  
 -      spin_lock_irqsave(&priv->lock, flags);
 -
 -      radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
 +      iwl_rf_config(priv);
  
 -      /* write radio config values to register */
 -      if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_RF_CONFIG_TYPE_MAX)
 -              iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 -                          EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
 -                          EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
 -                          EEPROM_RF_CFG_DASH_MSK(radio_cfg));
 -
 -      /* set CSR_HW_CONFIG_REG for uCode use */
 -      iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 -                  CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
 -                  CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 +      spin_lock_irqsave(&priv->lock, flags);
  
        /* W/A : NIC is stuck in a reset state after Early PCIe power off
         * (PCIe power is lost before PERST# is asserted),
@@@ -325,6 -341,7 +326,6 @@@ static struct iwl_lib_ops iwl5000_lib 
        .rx_handler_setup = iwlagn_rx_handler_setup,
        .setup_deferred_work = iwlagn_setup_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
 -      .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .set_channel_switch = iwl5000_hw_channel_switch,
        .apm_ops = {
        .temp_ops = {
                .temperature = iwlagn_temperature,
         },
 -      .txfifo_flush = iwlagn_txfifo_flush,
 -      .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
  };
  
  static struct iwl_lib_ops iwl5150_lib = {
        .rx_handler_setup = iwlagn_rx_handler_setup,
        .setup_deferred_work = iwlagn_setup_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
 -      .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .set_channel_switch = iwl5000_hw_channel_switch,
        .apm_ops = {
        .temp_ops = {
                .temperature = iwl5150_temperature,
         },
 -      .txfifo_flush = iwlagn_txfifo_flush,
 -      .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
  };
  
  static const struct iwl_ops iwl5000_ops = {
@@@ -27,6 -27,8 +27,6 @@@
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
 -#include <linux/pci.h>
 -#include <linux/dma-mapping.h>
  #include <linux/delay.h>
  #include <linux/skbuff.h>
  #include <linux/netdevice.h>
@@@ -34,6 -36,7 +34,7 @@@
  #include <net/mac80211.h>
  #include <linux/etherdevice.h>
  #include <asm/unaligned.h>
+ #include <linux/stringify.h>
  
  #include "iwl-eeprom.h"
  #include "iwl-dev.h"
  #define IWL6000G2_UCODE_API_MIN 4
  
  #define IWL6000_FW_PRE "iwlwifi-6000-"
- #define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
+ #define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode"
  
  #define IWL6050_FW_PRE "iwlwifi-6050-"
- #define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
+ #define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE __stringify(api) ".ucode"
  
  #define IWL6005_FW_PRE "iwlwifi-6000g2a-"
- #define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode"
+ #define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE __stringify(api) ".ucode"
  
  #define IWL6030_FW_PRE "iwlwifi-6000g2b-"
- #define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode"
+ #define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
  
  static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
  {
@@@ -95,7 -98,21 +96,7 @@@ static void iwl6150_additional_nic_conf
  /* NIC configuration for 6000 series */
  static void iwl6000_nic_config(struct iwl_priv *priv)
  {
 -      u16 radio_cfg;
 -
 -      radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
 -
 -      /* write radio config values to register */
 -      if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX)
 -              iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 -                          EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
 -                          EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
 -                          EEPROM_RF_CFG_DASH_MSK(radio_cfg));
 -
 -      /* set CSR_HW_CONFIG_REG for uCode use */
 -      iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 -                  CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
 -                  CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 +      iwl_rf_config(priv);
  
        /* no locking required for register write */
        if (priv->cfg->pa_type == IWL_PA_INTERNAL) {
@@@ -263,6 -280,7 +264,6 @@@ static struct iwl_lib_ops iwl6000_lib 
        .rx_handler_setup = iwlagn_rx_handler_setup,
        .setup_deferred_work = iwlagn_setup_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
 -      .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .set_channel_switch = iwl6000_hw_channel_switch,
        .apm_ops = {
        .temp_ops = {
                .temperature = iwlagn_temperature,
         },
 -      .txfifo_flush = iwlagn_txfifo_flush,
 -      .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
  };
  
  static struct iwl_lib_ops iwl6030_lib = {
        .setup_deferred_work = iwlagn_bt_setup_deferred_work,
        .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
 -      .send_tx_power = iwlagn_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
        .set_channel_switch = iwl6000_hw_channel_switch,
        .apm_ops = {
        .temp_ops = {
                .temperature = iwlagn_temperature,
         },
 -      .txfifo_flush = iwlagn_txfifo_flush,
 -      .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
  };
  
  static struct iwl_nic_ops iwl6050_nic_ops = {
  #include "iwl-helpers.h"
  #include "iwl-agn.h"
  
 -
 -/*
 - * set bt_coex_active to true, uCode will do kill/defer
 - * every time the priority line is asserted (BT is sending signals on the
 - * priority line in the PCIx).
 - * set bt_coex_active to false, uCode will ignore the BT activity and
 - * perform the normal operation
 - *
 - * User might experience transmit issue on some platform due to WiFi/BT
 - * co-exist problem. The possible behaviors are:
 - *   Able to scan and finding all the available AP
 - *   Not able to associate with any AP
 - * On those platforms, WiFi communication can be restored by set
 - * "bt_coex_active" module parameter to "false"
 - *
 - * default: bt_coex_active = true (BT_COEX_ENABLE)
 - */
 -bool bt_coex_active = true;
 -module_param(bt_coex_active, bool, S_IRUGO);
 -MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
 -
  u32 iwl_debug_level;
  
  const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
@@@ -143,7 -164,7 +143,7 @@@ int iwlcore_init_geos(struct iwl_priv *
        sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
        sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE;
  
 -      if (priv->cfg->sku & IWL_SKU_N)
 +      if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)
                iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
                                         IEEE80211_BAND_5GHZ);
  
        sband->bitrates = rates;
        sband->n_bitrates = IWL_RATE_COUNT_LEGACY;
  
 -      if (priv->cfg->sku & IWL_SKU_N)
 +      if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)
                iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
                                         IEEE80211_BAND_2GHZ);
  
        priv->tx_power_next = max_tx_power;
  
        if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
 -           priv->cfg->sku & IWL_SKU_A) {
 +           priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) {
 +              char buf[32];
 +              priv->bus.ops->get_hw_id(&priv->bus, buf, sizeof(buf));
                IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
 -                      "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n",
 -                         priv->pci_dev->device,
 -                         priv->pci_dev->subsystem_device);
 -              priv->cfg->sku &= ~IWL_SKU_A;
 +                      "Please send your %s to maintainer.\n", buf);
 +              priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
        }
  
        IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
@@@ -526,6 -547,19 +526,6 @@@ int iwl_full_rxon_required(struct iwl_p
        return 0;
  }
  
 -u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
 -                          struct iwl_rxon_context *ctx)
 -{
 -      /*
 -       * Assign the lowest rate -- should really get this from
 -       * the beacon skb from mac80211.
 -       */
 -      if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK)
 -              return IWL_RATE_1M_PLCP;
 -      else
 -              return IWL_RATE_6M_PLCP;
 -}
 -
  static void _iwl_set_rxon_ht(struct iwl_priv *priv,
                             struct iwl_ht_config *ht_conf,
                             struct iwl_rxon_context *ctx)
@@@ -984,6 -1018,8 +984,6 @@@ void iwl_apm_stop(struct iwl_priv *priv
  int iwl_apm_init(struct iwl_priv *priv)
  {
        int ret = 0;
 -      u16 lctl;
 -
        IWL_DEBUG_INFO(priv, "Init card's basic functions\n");
  
        /*
        iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                                    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
  
 -      /*
 -       * HW bug W/A for instability in PCIe bus L0->L0S->L1 transition.
 -       * Check if BIOS (or OS) enabled L1-ASPM on this device.
 -       * If so (likely), disable L0S, so device moves directly L0->L1;
 -       *    costs negligible amount of power savings.
 -       * If not (unlikely), enable L0S, so there is at least some
 -       *    power savings, even without L1.
 -       */
 -      lctl = iwl_pcie_link_ctl(priv);
 -      if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
 -                              PCI_CFG_LINK_CTRL_VAL_L1_EN) {
 -              /* L1-ASPM enabled; disable(!) L0S  */
 -              iwl_set_bit(priv, CSR_GIO_REG,
 -                              CSR_GIO_REG_VAL_L0S_ENABLED);
 -              IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
 -      } else {
 -              /* L1-ASPM disabled; enable(!) L0S */
 -              iwl_clear_bit(priv, CSR_GIO_REG,
 -                              CSR_GIO_REG_VAL_L0S_ENABLED);
 -              IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
 -      }
 +      priv->bus.ops->apm_config(&priv->bus);
  
        /* Configure analog phase-lock-loop before activating to D0A */
        if (priv->cfg->base_params->pll_cfg_val)
@@@ -1071,6 -1127,9 +1071,6 @@@ int iwl_set_tx_power(struct iwl_priv *p
        if (priv->tx_power_user_lmt == tx_power && !force)
                return 0;
  
 -      if (!priv->cfg->ops->lib->send_tx_power)
 -              return -EOPNOTSUPP;
 -
        if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {
                IWL_WARN(priv,
                         "Requested user TXPOWER %d below lower limit %d.\n",
        prev_tx_power = priv->tx_power_user_lmt;
        priv->tx_power_user_lmt = tx_power;
  
 -      ret = priv->cfg->ops->lib->send_tx_power(priv);
 +      ret = iwlagn_send_tx_power(priv);
  
        /* if fail to set tx_power, restore the orig. tx power */
        if (ret) {
@@@ -1123,7 -1182,7 +1123,7 @@@ void iwl_send_bt_config(struct iwl_pri
                .kill_cts_mask = 0,
        };
  
 -      if (!bt_coex_active)
 +      if (!iwlagn_mod_params.bt_coex_active)
                bt_cmd.flags = BT_COEX_DISABLE;
        else
                bt_cmd.flags = BT_COEX_ENABLE;
@@@ -1219,7 -1278,7 +1219,7 @@@ static int iwl_set_mode(struct iwl_pri
        if (priv->cfg->ops->hcmd->set_rxon_chain)
                priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
  
 -      return iwlcore_commit_rxon(priv, ctx);
 +      return iwlagn_commit_rxon(priv, ctx);
  }
  
  static int iwl_setup_interface(struct iwl_priv *priv,
@@@ -1704,6 -1763,7 +1704,7 @@@ int iwl_mac_change_interface(struct iee
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
        struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct iwl_rxon_context *tmp;
+       enum nl80211_iftype newviftype = newtype;
        u32 interface_modes;
        int err;
  
  
        /* success */
        iwl_teardown_interface(priv, vif, true);
-       vif->type = newtype;
+       vif->type = newviftype;
        vif->p2p = newp2p;
        err = iwl_setup_interface(priv, ctx);
        WARN_ON(err);
@@@ -1913,8 -1973,11 +1914,8 @@@ __le32 iwl_add_beacon_time(struct iwl_p
  
  #ifdef CONFIG_PM
  
 -int iwl_pci_suspend(struct device *device)
 +int iwl_suspend(struct iwl_priv *priv)
  {
 -      struct pci_dev *pdev = to_pci_dev(device);
 -      struct iwl_priv *priv = pci_get_drvdata(pdev);
 -
        /*
         * This function is called when system goes into suspend state
         * mac80211 will call iwl_mac_stop() from the mac80211 suspend function
        return 0;
  }
  
 -int iwl_pci_resume(struct device *device)
 +int iwl_resume(struct iwl_priv *priv)
  {
 -      struct pci_dev *pdev = to_pci_dev(device);
 -      struct iwl_priv *priv = pci_get_drvdata(pdev);
        bool hw_rfkill = false;
  
 -      /*
 -       * 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);
 -
        iwl_enable_interrupts(priv);
  
        if (!(iwl_read32(priv, CSR_GP_CNTRL) &
        return 0;
  }
  
 -const struct dev_pm_ops iwl_pm_ops = {
 -      .suspend = iwl_pci_suspend,
 -      .resume = iwl_pci_resume,
 -      .freeze = iwl_pci_suspend,
 -      .thaw = iwl_pci_resume,
 -      .poweroff = iwl_pci_suspend,
 -      .restore = iwl_pci_resume,
 -};
 -
  #endif /* CONFIG_PM */
@@@ -126,8 -126,9 +126,8 @@@ static inline u8 iwl_tfd_get_num_tbs(st
  }
  
  static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
-                            struct iwl_tfd *tfd)
 -                           struct iwl_tfd *tfd, int dma_dir)
++                           struct iwl_tfd *tfd, enum dma_data_direction dma_dir)
  {
 -      struct pci_dev *dev = priv->pci_dev;
        int i;
        int num_tbs;
  
  
        /* Unmap tx_cmd */
        if (num_tbs)
 -              pci_unmap_single(dev,
 +              dma_unmap_single(priv->bus.dev,
                                dma_unmap_addr(meta, mapping),
                                dma_unmap_len(meta, len),
 -                              PCI_DMA_BIDIRECTIONAL);
 +                              DMA_BIDIRECTIONAL);
  
        /* Unmap chunks, if any. */
        for (i = 1; i < num_tbs; i++)
 -              pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
 +              dma_unmap_single(priv->bus.dev, iwl_tfd_tb_get_addr(tfd, i),
-                               iwl_tfd_tb_get_len(tfd, i), DMA_TO_DEVICE);
+                               iwl_tfd_tb_get_len(tfd, i), dma_dir);
  }
  
  /**
@@@ -166,7 -167,8 +166,8 @@@ void iwlagn_txq_free_tfd(struct iwl_pri
        struct iwl_tfd *tfd_tmp = txq->tfds;
        int index = txq->q.read_ptr;
  
-       iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index]);
+       iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index],
 -                       PCI_DMA_TODEVICE);
++                       DMA_TO_DEVICE);
  
        /* free SKB */
        if (txq->txb) {
@@@ -265,7 -267,7 +266,7 @@@ void iwl_tx_queue_unmap(struct iwl_pri
  void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
  {
        struct iwl_tx_queue *txq = &priv->txq[txq_id];
 -      struct device *dev = &priv->pci_dev->dev;
 +      struct device *dev = priv->bus.dev;
        int i;
  
        iwl_tx_queue_unmap(priv, txq_id);
@@@ -309,7 -311,8 +310,8 @@@ void iwl_cmd_queue_unmap(struct iwl_pri
                i = get_cmd_index(q, q->read_ptr);
  
                if (txq->meta[i].flags & CMD_MAPPED) {
-                       iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i]);
+                       iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i],
 -                                       PCI_DMA_BIDIRECTIONAL);
++                                       DMA_BIDIRECTIONAL);
                        txq->meta[i].flags = 0;
                }
  
  void iwl_cmd_queue_free(struct iwl_priv *priv)
  {
        struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
 -      struct device *dev = &priv->pci_dev->dev;
 +      struct device *dev = priv->bus.dev;
        int i;
  
        iwl_cmd_queue_unmap(priv);
@@@ -430,7 -433,7 +432,7 @@@ static int iwl_queue_init(struct iwl_pr
  static int iwl_tx_queue_alloc(struct iwl_priv *priv,
                              struct iwl_tx_queue *txq, u32 id)
  {
 -      struct device *dev = &priv->pci_dev->dev;
 +      struct device *dev = priv->bus.dev;
        size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
  
        /* Driver private data, only for Tx (not command) queues,
        txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr,
                                       GFP_KERNEL);
        if (!txq->tfds) {
 -              IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz);
 +              IWL_ERR(priv, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
                goto error;
        }
        txq->q.id = id;
@@@ -531,12 -534,7 +533,7 @@@ out_free_arrays
  void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
                        int slots_num, u32 txq_id)
  {
-       int actual_slots = slots_num;
-       if (txq_id == priv->cmd_queue)
-               actual_slots++;
-       memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
+       memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * slots_num);
  
        txq->need_update = 0;
  
@@@ -673,9 -671,9 +670,9 @@@ int iwl_enqueue_hcmd(struct iwl_priv *p
                        le16_to_cpu(out_cmd->hdr.sequence), cmd_size,
                        q->write_ptr, idx, priv->cmd_queue);
  
 -      phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
 -                                 copy_size, PCI_DMA_BIDIRECTIONAL);
 -      if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) {
 +      phys_addr = dma_map_single(priv->bus.dev, &out_cmd->hdr, copy_size,
 +                              DMA_BIDIRECTIONAL);
 +      if (unlikely(dma_mapping_error(priv->bus.dev, phys_addr))) {
                idx = -ENOMEM;
                goto out;
        }
                        continue;
                if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
                        continue;
 -              phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i],
 -                                         cmd->len[i], PCI_DMA_BIDIRECTIONAL);
 -              if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) {
 +              phys_addr = dma_map_single(priv->bus.dev, (void *)cmd->data[i],
-                                          cmd->len[i], DMA_TO_DEVICE);
++                                         cmd->len[i], DMA_BIDIRECTIONAL);
 +              if (dma_mapping_error(priv->bus.dev, phys_addr)) {
                        iwlagn_unmap_tfd(priv, out_meta,
-                                        &txq->tfds[q->write_ptr]);
+                                        &txq->tfds[q->write_ptr],
 -                                       PCI_DMA_BIDIRECTIONAL);
++                                       DMA_BIDIRECTIONAL);
                        idx = -ENOMEM;
                        goto out;
                }
@@@ -749,9 -748,9 +747,9 @@@ static void iwl_hcmd_queue_reclaim(stru
        int nfreed = 0;
  
        if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
 -              IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
 -                        "is out of range [0-%d] %d %d.\n", txq_id,
 -                        idx, q->n_bd, q->write_ptr, q->read_ptr);
 +              IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), "
 +                        "index %d is out of range [0-%d] %d %d.\n", __func__,
 +                        txq_id, idx, q->n_bd, q->write_ptr, q->read_ptr);
                return;
        }
  
@@@ -803,7 -802,7 +801,7 @@@ void iwl_tx_cmd_complete(struct iwl_pri
        cmd = txq->cmd[cmd_index];
        meta = &txq->meta[cmd_index];
  
-       iwlagn_unmap_tfd(priv, meta, &txq->tfds[index]);
 -      iwlagn_unmap_tfd(priv, meta, &txq->tfds[index], PCI_DMA_BIDIRECTIONAL);
++      iwlagn_unmap_tfd(priv, meta, &txq->tfds[index], DMA_BIDIRECTIONAL);
  
        /* Input error checking is done when commands are added to queue. */
        if (meta->flags & CMD_WANT_SKB) {
@@@ -581,7 -581,7 +581,7 @@@ static void _rtl_pci_tx_isr(struct ieee
                fc = rtl_get_fc(skb);
                if (ieee80211_is_nullfunc(fc)) {
                        if (ieee80211_has_pm(fc)) {
 -                              rtlpriv->mac80211.offchan_deley = true;
 +                              rtlpriv->mac80211.offchan_delay = true;
                                rtlpriv->psc.state_inap = 1;
                        } else {
                                rtlpriv->psc.state_inap = 0;
@@@ -622,60 -622,10 +622,60 @@@ tx_status_ok
        if (((rtlpriv->link_info.num_rx_inperiod +
                rtlpriv->link_info.num_tx_inperiod) > 8) ||
                (rtlpriv->link_info.num_rx_inperiod > 2)) {
 -              rtl_lps_leave(hw);
 +              tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
        }
  }
  
 +static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb,
 +                           struct ieee80211_rx_status rx_status)
 +{
 +      struct rtl_priv *rtlpriv = rtl_priv(hw);
 +      struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
 +      __le16 fc = rtl_get_fc(skb);
 +      bool unicast = false;
 +      struct sk_buff *uskb = NULL;
 +      u8 *pdata;
 +
 +
 +      memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
 +
 +      if (is_broadcast_ether_addr(hdr->addr1)) {
 +              ;/*TODO*/
 +      } else if (is_multicast_ether_addr(hdr->addr1)) {
 +              ;/*TODO*/
 +      } else {
 +              unicast = true;
 +              rtlpriv->stats.rxbytesunicast += skb->len;
 +      }
 +
 +      rtl_is_special_data(hw, skb, false);
 +
 +      if (ieee80211_is_data(fc)) {
 +              rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
 +
 +              if (unicast)
 +                      rtlpriv->link_info.num_rx_inperiod++;
 +      }
 +
 +      /* for sw lps */
 +      rtl_swlps_beacon(hw, (void *)skb->data, skb->len);
 +      rtl_recognize_peer(hw, (void *)skb->data, skb->len);
 +      if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) &&
 +          (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) &&
 +           (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)))
 +              return;
 +
 +      if (unlikely(!rtl_action_proc(hw, skb, false)))
 +              return;
 +
 +      uskb = dev_alloc_skb(skb->len + 128);
 +      memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status));
 +      pdata = (u8 *)skb_put(uskb, skb->len);
 +      memcpy(pdata, skb->data, skb->len);
 +
 +      ieee80211_rx_irqsafe(hw, uskb);
 +}
 +
  static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
  {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        u8 own;
        u8 tmp_one;
        u32 bufferaddress;
 -      bool unicast = false;
  
        struct rtl_stats stats = {
                .signal = 0,
                .noise = -98,
                .rate = 0,
        };
 +      int index = rtlpci->rx_ring[rx_queue_idx].idx;
  
        /*RX NORMAL PKT */
        while (count--) {
                /*rx descriptor */
                struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[
 -                              rtlpci->rx_ring[rx_queue_idx].idx];
 +                              index];
                /*rx pkt */
                struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[
 -                              rtlpci->rx_ring[rx_queue_idx].idx];
 +                              index];
 +              struct sk_buff *new_skb = NULL;
  
                own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
                                                       false, HW_DESC_OWN);
  
 -              if (own) {
 -                      /*wait data to be filled by hardware */
 -                      return;
 -              } else {
 -                      struct ieee80211_hdr *hdr;
 -                      __le16 fc;
 -                      struct sk_buff *new_skb = NULL;
 -
 -                      rtlpriv->cfg->ops->query_rx_desc(hw, &stats,
 -                                                       &rx_status,
 -                                                       (u8 *) pdesc, skb);
 -
 -                      new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
 -                      if (unlikely(!new_skb)) {
 -                              RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
 -                                       DBG_DMESG,
 -                                       ("can't alloc skb for rx\n"));
 -                              goto done;
 -                      }
 +              /*wait data to be filled by hardware */
 +              if (own)
 +                      break;
  
 -                      pci_unmap_single(rtlpci->pdev,
 -                                       *((dma_addr_t *) skb->cb),
 -                                       rtlpci->rxbuffersize,
 -                                       PCI_DMA_FROMDEVICE);
 +              rtlpriv->cfg->ops->query_rx_desc(hw, &stats,
 +                                               &rx_status,
 +                                               (u8 *) pdesc, skb);
  
 -                      skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
 -                                                       false,
 -                                                       HW_DESC_RXPKT_LEN));
 -                      skb_reserve(skb,
 -                                  stats.rx_drvinfo_size + stats.rx_bufshift);
 +              if (stats.crc || stats.hwerror)
 +                      goto done;
  
 -                      /*
 -                       *NOTICE This can not be use for mac80211,
 -                       *this is done in mac80211 code,
 -                       *if you done here sec DHCP will fail
 -                       *skb_trim(skb, skb->len - 4);
 -                       */
 +              new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
 +              if (unlikely(!new_skb)) {
 +                      RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
 +                               DBG_DMESG,
 +                               ("can't alloc skb for rx\n"));
 +                      goto done;
 +              }
  
 -                      hdr = rtl_get_hdr(skb);
 -                      fc = rtl_get_fc(skb);
 -
 -                      if (!stats.crc && !stats.hwerror) {
 -                              memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
 -                                     sizeof(rx_status));
 -
 -                              if (is_broadcast_ether_addr(hdr->addr1)) {
 -                                      ;/*TODO*/
 -                              } else if (is_multicast_ether_addr(hdr->addr1)) {
 -                                      ;/*TODO*/
 -                              } else {
 -                                      unicast = true;
 -                                      rtlpriv->stats.rxbytesunicast +=
 -                                          skb->len;
 -                              }
 -
 -                              rtl_is_special_data(hw, skb, false);
 -
 -                              if (ieee80211_is_data(fc)) {
 -                                      rtlpriv->cfg->ops->led_control(hw,
 -                                                             LED_CTL_RX);
 -
 -                                      if (unicast)
 -                                              rtlpriv->link_info.
 -                                                  num_rx_inperiod++;
 -                              }
 -
 -                              /* for sw lps */
 -                              rtl_swlps_beacon(hw, (void *)skb->data,
 -                                               skb->len);
 -                              rtl_recognize_peer(hw, (void *)skb->data,
 -                                                 skb->len);
 -                              if ((rtlpriv->mac80211.opmode ==
 -                                   NL80211_IFTYPE_AP) &&
 -                                  (rtlpriv->rtlhal.current_bandtype ==
 -                                   BAND_ON_2_4G) &&
 -                                   (ieee80211_is_beacon(fc) ||
 -                                   ieee80211_is_probe_resp(fc))) {
 -                                      dev_kfree_skb_any(skb);
 -                              } else {
 -                                      if (unlikely(!rtl_action_proc(hw, skb,
 -                                          false))) {
 -                                              dev_kfree_skb_any(skb);
 -                                      } else {
 -                                              struct sk_buff *uskb = NULL;
 -                                              u8 *pdata;
 -                                              uskb = dev_alloc_skb(skb->len
 -                                                                   + 128);
 -                                              memcpy(IEEE80211_SKB_RXCB(uskb),
 -                                                     &rx_status,
 -                                                     sizeof(rx_status));
 -                                              pdata = (u8 *)skb_put(uskb,
 -                                                      skb->len);
 -                                              memcpy(pdata, skb->data,
 -                                                     skb->len);
 -                                              dev_kfree_skb_any(skb);
 -
 -                                              ieee80211_rx_irqsafe(hw, uskb);
 -                                      }
 -                              }
 -                      } else {
 -                              dev_kfree_skb_any(skb);
 -                      }
 +              pci_unmap_single(rtlpci->pdev,
 +                               *((dma_addr_t *) skb->cb),
 +                               rtlpci->rxbuffersize,
 +                               PCI_DMA_FROMDEVICE);
  
 -                      if (((rtlpriv->link_info.num_rx_inperiod +
 -                              rtlpriv->link_info.num_tx_inperiod) > 8) ||
 -                              (rtlpriv->link_info.num_rx_inperiod > 2)) {
 -                              rtl_lps_leave(hw);
 -                      }
 +              skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, false,
 +                      HW_DESC_RXPKT_LEN));
 +              skb_reserve(skb, stats.rx_drvinfo_size + stats.rx_bufshift);
  
 -                      skb = new_skb;
 +              /*
 +               * NOTICE This can not be use for mac80211,
 +               * this is done in mac80211 code,
 +               * if you done here sec DHCP will fail
 +               * skb_trim(skb, skb->len - 4);
 +               */
  
 -                      rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci->
 -                                                           rx_ring
 -                                                           [rx_queue_idx].
 -                                                           idx] = skb;
 -                      *((dma_addr_t *) skb->cb) =
 +              _rtl_receive_one(hw, skb, rx_status);
 +
 +              if (((rtlpriv->link_info.num_rx_inperiod +
 +                      rtlpriv->link_info.num_tx_inperiod) > 8) ||
 +                      (rtlpriv->link_info.num_rx_inperiod > 2)) {
 +                      tasklet_schedule(&rtlpriv->works.ips_leave_tasklet);
 +              }
 +
 +              dev_kfree_skb_any(skb);
 +              skb = new_skb;
 +
 +              rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb;
 +              *((dma_addr_t *) skb->cb) =
                            pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
                                           rtlpci->rxbuffersize,
                                           PCI_DMA_FROMDEVICE);
  
 -              }
  done:
                bufferaddress = (*((dma_addr_t *)skb->cb));
                tmp_one = 1;
                rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
                                            HW_DESC_RXBUFF_ADDR,
                                            (u8 *)&bufferaddress);
 -              rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
 -                                          (u8 *)&tmp_one);
                rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
                                            HW_DESC_RXPKT_LEN,
                                            (u8 *)&rtlpci->rxbuffersize);
  
 -              if (rtlpci->rx_ring[rx_queue_idx].idx ==
 -                  rtlpci->rxringcount - 1)
 +              if (index == rtlpci->rxringcount - 1)
                        rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
                                                    HW_DESC_RXERO,
                                                    (u8 *)&tmp_one);
  
 -              rtlpci->rx_ring[rx_queue_idx].idx =
 -                  (rtlpci->rx_ring[rx_queue_idx].idx + 1) %
 -                  rtlpci->rxringcount;
 +              rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
 +                                          (u8 *)&tmp_one);
 +
 +              index = (index + 1) % rtlpci->rxringcount;
        }
  
 +      rtlpci->rx_ring[rx_queue_idx].idx = index;
  }
  
  static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
@@@ -919,11 -938,6 +919,11 @@@ static void _rtl_pci_irq_tasklet(struc
        _rtl_pci_tx_chk_waitq(hw);
  }
  
 +static void _rtl_pci_ips_leave_tasklet(struct ieee80211_hw *hw)
 +{
 +      rtl_lps_leave(hw);
 +}
 +
  static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
  {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
@@@ -1022,9 -1036,6 +1022,9 @@@ static void _rtl_pci_init_struct(struc
        tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
                     (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
                     (unsigned long)hw);
 +      tasklet_init(&rtlpriv->works.ips_leave_tasklet,
 +                   (void (*)(unsigned long))_rtl_pci_ips_leave_tasklet,
 +                   (unsigned long)hw);
  }
  
  static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
@@@ -1494,7 -1505,6 +1494,7 @@@ static void rtl_pci_deinit(struct ieee8
  
        synchronize_irq(rtlpci->pdev->irq);
        tasklet_kill(&rtlpriv->works.irq_tasklet);
 +      tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
  
        flush_workqueue(rtlpriv->works.rtl_wq);
        destroy_workqueue(rtlpriv->works.rtl_wq);
@@@ -1569,7 -1579,6 +1569,7 @@@ static void rtl_pci_stop(struct ieee802
        set_hal_stop(rtlhal);
  
        rtlpriv->cfg->ops->disable_interrupt(hw);
 +      tasklet_kill(&rtlpriv->works.ips_leave_tasklet);
  
        spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
        while (ppsc->rfchange_inprogress) {
@@@ -1615,6 -1624,16 +1615,16 @@@ static bool _rtl_pci_find_adapter(struc
        pci_read_config_byte(pdev, 0x8, &revisionid);
        pci_read_config_word(pdev, 0x3C, &irqline);
  
+       /* PCI ID 0x10ec:0x8192 occurs for both RTL8192E, which uses
+        * r8192e_pci, and RTL8192SE, which uses this driver. If the
+        * revision ID is RTL_PCI_REVISION_ID_8192PCIE (0x01), then
+        * the correct driver is r8192e_pci, thus this routine should
+        * return false.
+        */
+       if (deviceid == RTL_PCI_8192SE_DID &&
+           revisionid == RTL_PCI_REVISION_ID_8192PCIE)
+               return false;
        if (deviceid == RTL_PCI_8192_DID ||
            deviceid == RTL_PCI_0044_DID ||
            deviceid == RTL_PCI_0047_DID ||
@@@ -1847,7 -1866,8 +1857,8 @@@ int __devinit rtl_pci_probe(struct pci_
        pci_write_config_byte(pdev, 0x04, 0x07);
  
        /* find adapter */
-       _rtl_pci_find_adapter(pdev, hw);
+       if (!_rtl_pci_find_adapter(pdev, hw))
+               goto fail3;
  
        /* Init IO handler */
        _rtl_pci_io_handler_init(&pdev->dev, hw);
diff --combined include/net/cfg80211.h
@@@ -1284,12 -1284,6 +1284,12 @@@ struct cfg80211_wowlan 
   *    frame on another channel
   *
   * @testmode_cmd: run a test mode command
 + * @testmode_dump: Implement a test mode dump. The cb->args[2] and up may be
 + *    used by the function, but 0 and 1 must not be touched. Additionally,
 + *    return error codes other than -ENOBUFS and -ENOENT will terminate the
 + *    dump and return to userspace with an error, so be careful. If any data
 + *    was passed in from userspace then the data/len arguments will be present
 + *    and point to the data contained in %NL80211_ATTR_TESTDATA.
   *
   * @set_bitrate_mask: set the bitrate mask configuration
   *
@@@ -1439,9 -1433,6 +1439,9 @@@ struct cfg80211_ops 
  
  #ifdef CONFIG_NL80211_TESTMODE
        int     (*testmode_cmd)(struct wiphy *wiphy, void *data, int len);
 +      int     (*testmode_dump)(struct wiphy *wiphy, struct sk_buff *skb,
 +                               struct netlink_callback *cb,
 +                               void *data, int len);
  #endif
  
        int     (*set_bitrate_mask)(struct wiphy *wiphy,
@@@ -2697,7 -2688,7 +2697,7 @@@ void cfg80211_send_unprot_disassoc(stru
   * @dev: network device
   * @addr: The source MAC address of the frame
   * @key_type: The key type that the received frame used
-  * @key_id: Key identifier (0..3)
+  * @key_id: Key identifier (0..3). Can be -1 if missing.
   * @tsc: The TSC value of the frame that generated the MIC failure (6 octets)
   * @gfp: allocation flags
   *
@@@ -2858,10 -2849,8 +2858,10 @@@ struct sk_buff *cfg80211_testmode_alloc
  void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp);
  
  #define CFG80211_TESTMODE_CMD(cmd)    .testmode_cmd = (cmd),
 +#define CFG80211_TESTMODE_DUMP(cmd)   .testmode_dump = (cmd),
  #else
  #define CFG80211_TESTMODE_CMD(cmd)
 +#define CFG80211_TESTMODE_DUMP(cmd)
  #endif
  
  /**
diff --combined net/wireless/nl80211.c
@@@ -3620,8 -3620,7 +3620,8 @@@ static int nl80211_stop_sched_scan(stru
        return __cfg80211_stop_sched_scan(rdev, false);
  }
  
 -static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 +static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
 +                          u32 seq, int flags,
                            struct cfg80211_registered_device *rdev,
                            struct wireless_dev *wdev,
                            struct cfg80211_internal_bss *intbss)
  
        ASSERT_WDEV_LOCK(wdev);
  
 -      hdr = nl80211hdr_put(msg, pid, seq, flags,
 +      hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).pid, seq, flags,
                             NL80211_CMD_NEW_SCAN_RESULTS);
        if (!hdr)
                return -1;
  
 +      genl_dump_check_consistent(cb, hdr, &nl80211_fam);
 +
        NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation);
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex);
  
@@@ -3728,12 -3725,11 +3728,12 @@@ static int nl80211_dump_scan(struct sk_
        spin_lock_bh(&rdev->bss_lock);
        cfg80211_bss_expire(rdev);
  
 +      cb->seq = rdev->bss_generation;
 +
        list_for_each_entry(scan, &rdev->bss_list, list) {
                if (++idx <= start)
                        continue;
 -              if (nl80211_send_bss(skb,
 -                              NETLINK_CB(cb->skb).pid,
 +              if (nl80211_send_bss(skb, cb,
                                cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                rdev, wdev, scan) < 0) {
                        idx--;
@@@ -3757,6 -3753,10 +3757,6 @@@ static int nl80211_send_survey(struct s
        void *hdr;
        struct nlattr *infoattr;
  
 -      /* Survey without a channel doesn't make sense */
 -      if (!survey->channel)
 -              return -EINVAL;
 -
        hdr = nl80211hdr_put(msg, pid, seq, flags,
                             NL80211_CMD_NEW_SURVEY_RESULTS);
        if (!hdr)
@@@ -3819,8 -3819,6 +3819,8 @@@ static int nl80211_dump_survey(struct s
        }
  
        while (1) {
 +              struct ieee80211_channel *chan;
 +
                res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx,
                                            &survey);
                if (res == -ENOENT)
                if (res)
                        goto out_err;
  
 +              /* Survey without a channel doesn't make sense */
 +              if (!survey.channel) {
 +                      res = -EINVAL;
 +                      goto out;
 +              }
 +
 +              chan = ieee80211_get_channel(&dev->wiphy,
 +                                           survey.channel->center_freq);
 +              if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
 +                      survey_idx++;
 +                      continue;
 +              }
 +
                if (nl80211_send_survey(skb,
                                NETLINK_CB(cb->skb).pid,
                                cb->nlh->nlmsg_seq, NLM_F_MULTI,
@@@ -4375,93 -4360,6 +4375,93 @@@ static int nl80211_testmode_do(struct s
        return err;
  }
  
 +static int nl80211_testmode_dump(struct sk_buff *skb,
 +                               struct netlink_callback *cb)
 +{
 +      struct cfg80211_registered_device *dev;
 +      int err;
 +      long phy_idx;
 +      void *data = NULL;
 +      int data_len = 0;
 +
 +      if (cb->args[0]) {
 +              /*
 +               * 0 is a valid index, but not valid for args[0],
 +               * so we need to offset by 1.
 +               */
 +              phy_idx = cb->args[0] - 1;
 +      } else {
 +              err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
 +                                nl80211_fam.attrbuf, nl80211_fam.maxattr,
 +                                nl80211_policy);
 +              if (err)
 +                      return err;
 +              if (!nl80211_fam.attrbuf[NL80211_ATTR_WIPHY])
 +                      return -EINVAL;
 +              phy_idx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
 +              if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
 +                      cb->args[1] =
 +                              (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
 +      }
 +
 +      if (cb->args[1]) {
 +              data = nla_data((void *)cb->args[1]);
 +              data_len = nla_len((void *)cb->args[1]);
 +      }
 +
 +      mutex_lock(&cfg80211_mutex);
 +      dev = cfg80211_rdev_by_wiphy_idx(phy_idx);
 +      if (!dev) {
 +              mutex_unlock(&cfg80211_mutex);
 +              return -ENOENT;
 +      }
 +      cfg80211_lock_rdev(dev);
 +      mutex_unlock(&cfg80211_mutex);
 +
 +      if (!dev->ops->testmode_dump) {
 +              err = -EOPNOTSUPP;
 +              goto out_err;
 +      }
 +
 +      while (1) {
 +              void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).pid,
 +                                         cb->nlh->nlmsg_seq, NLM_F_MULTI,
 +                                         NL80211_CMD_TESTMODE);
 +              struct nlattr *tmdata;
 +
 +              if (nla_put_u32(skb, NL80211_ATTR_WIPHY, dev->wiphy_idx) < 0) {
 +                      genlmsg_cancel(skb, hdr);
 +                      break;
 +              }
 +
 +              tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
 +              if (!tmdata) {
 +                      genlmsg_cancel(skb, hdr);
 +                      break;
 +              }
 +              err = dev->ops->testmode_dump(&dev->wiphy, skb, cb,
 +                                            data, data_len);
 +              nla_nest_end(skb, tmdata);
 +
 +              if (err == -ENOBUFS || err == -ENOENT) {
 +                      genlmsg_cancel(skb, hdr);
 +                      break;
 +              } else if (err) {
 +                      genlmsg_cancel(skb, hdr);
 +                      goto out_err;
 +              }
 +
 +              genlmsg_end(skb, hdr);
 +      }
 +
 +      err = skb->len;
 +      /* see above */
 +      cb->args[0] = phy_idx + 1;
 + out_err:
 +      cfg80211_unlock_rdev(dev);
 +      return err;
 +}
 +
  static struct sk_buff *
  __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev,
                              int approxlen, u32 pid, u32 seq, gfp_t gfp)
@@@ -5759,7 -5657,6 +5759,7 @@@ static struct genl_ops nl80211_ops[] = 
        {
                .cmd = NL80211_CMD_TESTMODE,
                .doit = nl80211_testmode_do,
 +              .dumpit = nl80211_testmode_dump,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
@@@ -6566,7 -6463,8 +6566,8 @@@ void nl80211_michael_mic_failure(struc
        if (addr)
                NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
        NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
-       NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
+       if (key_id != -1)
+               NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
        if (tsc)
                NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);