]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'wireless-next' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi...
authorJohn W. Linville <linville@tuxdriver.com>
Mon, 27 Feb 2012 18:30:45 +0000 (13:30 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 27 Feb 2012 18:30:45 +0000 (13:30 -0500)
35 files changed:
drivers/net/wireless/iwlwifi/Makefile
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-agn-calib.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-tt.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debug.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-debug.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/iwl-mac80211.c
drivers/net/wireless/iwlwifi/iwl-pci.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-shared.h
drivers/net/wireless/iwlwifi/iwl-testmode.c
drivers/net/wireless/iwlwifi/iwl-testmode.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/iwl-ucode.c
drivers/net/wireless/iwlwifi/iwl-ucode.h
drivers/net/wireless/iwlwifi/iwl-wifi.h

index 9dc84a7354dbbde1cdec1560dc91d019039c5feb..46622a0f017b0c357dc11d8a12b61222fac44370 100644 (file)
@@ -1,7 +1,7 @@
 # WIFI
 obj-$(CONFIG_IWLWIFI)  += iwlwifi.o
 iwlwifi-objs           := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o
-iwlwifi-objs           += iwl-ucode.o iwl-agn-tx.o
+iwlwifi-objs           += iwl-ucode.o iwl-agn-tx.o iwl-debug.o
 iwlwifi-objs           += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
 iwlwifi-objs           += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o
 
index 8c1466c907ff2b7cdf2a7af1ecb1029683248a1f..605ee3df1d82dffd1db92ffd9bfbb90a7bd80104 100644 (file)
@@ -120,7 +120,7 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
        .nrg_th_cca = 62,
 };
 
-static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
+static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
 {
        if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
            iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
@@ -128,8 +128,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
                        iwlagn_mod_params.num_of_queues;
 
        hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-       hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
-       hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
 
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ);
 
@@ -146,8 +144,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
 
        /* Set initial sensitivity parameters */
        hw_params(priv).sens = &iwl1000_sensitivity;
-
-       return 0;
 }
 
 static struct iwl_lib_ops iwl1000_lib = {
@@ -193,6 +189,8 @@ static struct iwl_ht_params iwl1000_ht_params = {
        .ucode_api_max = IWL1000_UCODE_API_MAX,                 \
        .ucode_api_ok = IWL1000_UCODE_API_OK,                   \
        .ucode_api_min = IWL1000_UCODE_API_MIN,                 \
+       .max_inst_size = IWLAGN_RTC_INST_SIZE,                  \
+       .max_data_size = IWLAGN_RTC_DATA_SIZE,                  \
        .eeprom_ver = EEPROM_1000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,       \
        .lib = &iwl1000_lib,                                    \
@@ -215,6 +213,8 @@ struct iwl_cfg iwl1000_bg_cfg = {
        .ucode_api_max = IWL100_UCODE_API_MAX,                  \
        .ucode_api_ok = IWL100_UCODE_API_OK,                    \
        .ucode_api_min = IWL100_UCODE_API_MIN,                  \
+       .max_inst_size = IWLAGN_RTC_INST_SIZE,                  \
+       .max_data_size = IWLAGN_RTC_DATA_SIZE,                  \
        .eeprom_ver = EEPROM_1000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,       \
        .lib = &iwl1000_lib,                                    \
index d4f5f3b8757885109ca6299be342a19aea0fd871..e6e8c79a80d8e731f7bc624b695dafeb8e1f3967 100644 (file)
@@ -116,7 +116,7 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
        .nrg_th_cca = 62,
 };
 
-static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
+static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
 {
        if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
            iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
@@ -124,8 +124,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
                        iwlagn_mod_params.num_of_queues;
 
        hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-       hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
-       hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE;
 
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ);
 
@@ -142,8 +140,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
 
        /* Set initial sensitivity parameters */
        hw_params(priv).sens = &iwl2000_sensitivity;
-
-       return 0;
 }
 
 static struct iwl_lib_ops iwl2000_lib = {
@@ -242,6 +238,8 @@ static struct iwl_bt_params iwl2030_bt_params = {
        .ucode_api_max = IWL2000_UCODE_API_MAX,                 \
        .ucode_api_ok = IWL2000_UCODE_API_OK,                   \
        .ucode_api_min = IWL2000_UCODE_API_MIN,                 \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
        .lib = &iwl2000_lib,                                    \
@@ -268,6 +266,8 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = {
        .ucode_api_max = IWL2030_UCODE_API_MAX,                 \
        .ucode_api_ok = IWL2030_UCODE_API_OK,                   \
        .ucode_api_min = IWL2030_UCODE_API_MIN,                 \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
        .lib = &iwl2030_lib,                                    \
@@ -290,6 +290,8 @@ struct iwl_cfg iwl2030_2bgn_cfg = {
        .ucode_api_max = IWL105_UCODE_API_MAX,                  \
        .ucode_api_ok = IWL105_UCODE_API_OK,                    \
        .ucode_api_min = IWL105_UCODE_API_MIN,                  \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
        .lib = &iwl2000_lib,                                    \
@@ -318,6 +320,8 @@ struct iwl_cfg iwl105_bgn_d_cfg = {
        .ucode_api_max = IWL135_UCODE_API_MAX,                  \
        .ucode_api_ok = IWL135_UCODE_API_OK,                    \
        .ucode_api_min = IWL135_UCODE_API_MIN,                  \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
        .lib = &iwl2030_lib,                                    \
index dc9317d0343e05659ae64af720b0011c9afea664..1527dec7a26706d714f46619b44449c796ee0e59 100644 (file)
@@ -162,7 +162,7 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
        hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
 }
 
-static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
+static void iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 {
        if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
            iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
@@ -170,8 +170,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
                        iwlagn_mod_params.num_of_queues;
 
        hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-       hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
-       hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
 
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
                                        BIT(IEEE80211_BAND_5GHZ);
@@ -185,11 +183,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 
        /* Set initial sensitivity parameters */
        hw_params(priv).sens = &iwl5000_sensitivity;
-
-       return 0;
 }
 
-static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
+static void iwl5150_hw_set_hw_params(struct iwl_priv *priv)
 {
        if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
            iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
@@ -197,8 +193,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
                        iwlagn_mod_params.num_of_queues;
 
        hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-       hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
-       hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
 
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
                                        BIT(IEEE80211_BAND_5GHZ);
@@ -212,8 +206,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
 
        /* Set initial sensitivity parameters */
        hw_params(priv).sens = &iwl5150_sensitivity;
-
-       return 0;
 }
 
 static void iwl5150_temperature(struct iwl_priv *priv)
@@ -356,6 +348,8 @@ static struct iwl_ht_params iwl5000_ht_params = {
        .fw_name_pre = IWL5000_FW_PRE,                          \
        .ucode_api_max = IWL5000_UCODE_API_MAX,                 \
        .ucode_api_min = IWL5000_UCODE_API_MIN,                 \
+       .max_inst_size = IWLAGN_RTC_INST_SIZE,                  \
+       .max_data_size = IWLAGN_RTC_DATA_SIZE,                  \
        .eeprom_ver = EEPROM_5000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,       \
        .lib = &iwl5000_lib,                                    \
@@ -399,6 +393,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
        .fw_name_pre = IWL5000_FW_PRE,
        .ucode_api_max = IWL5000_UCODE_API_MAX,
        .ucode_api_min = IWL5000_UCODE_API_MIN,
+       .max_inst_size = IWLAGN_RTC_INST_SIZE,
+       .max_data_size = IWLAGN_RTC_DATA_SIZE,
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
        .lib = &iwl5000_lib,
@@ -412,6 +408,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
        .fw_name_pre = IWL5150_FW_PRE,                          \
        .ucode_api_max = IWL5150_UCODE_API_MAX,                 \
        .ucode_api_min = IWL5150_UCODE_API_MIN,                 \
+       .max_inst_size = IWLAGN_RTC_INST_SIZE,                  \
+       .max_data_size = IWLAGN_RTC_DATA_SIZE,                  \
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,       \
        .lib = &iwl5150_lib,                                    \
index c36fb858a45bfe7ead8dc7722c17facaba6f24ac..1e6fbf4fcb46cbdc865d486a7fb62a5a113efe6e 100644 (file)
@@ -137,7 +137,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
        .nrg_th_cca = 62,
 };
 
-static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
+static void iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 {
        if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
            iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
@@ -145,8 +145,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
                        iwlagn_mod_params.num_of_queues;
 
        hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-       hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
-       hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE;
 
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
                                        BIT(IEEE80211_BAND_5GHZ);
@@ -165,7 +163,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
        /* Set initial sensitivity parameters */
        hw_params(priv).sens = &iwl6000_sensitivity;
 
-       return 0;
 }
 
 static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
@@ -349,6 +346,8 @@ static struct iwl_bt_params iwl6000_bt_params = {
        .ucode_api_max = IWL6000G2_UCODE_API_MAX,               \
        .ucode_api_ok = IWL6000G2_UCODE_API_OK,                 \
        .ucode_api_min = IWL6000G2_UCODE_API_MIN,               \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_6005_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION,       \
        .lib = &iwl6000_lib,                                    \
@@ -389,6 +388,8 @@ struct iwl_cfg iwl6005_2agn_d_cfg = {
        .ucode_api_max = IWL6000G2_UCODE_API_MAX,               \
        .ucode_api_ok = IWL6000G2_UCODE_API_OK,                 \
        .ucode_api_min = IWL6000G2_UCODE_API_MIN,               \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .eeprom_ver = EEPROM_6030_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION,       \
        .lib = &iwl6030_lib,                                    \
@@ -458,6 +459,8 @@ struct iwl_cfg iwl130_bg_cfg = {
        .ucode_api_max = IWL6000_UCODE_API_MAX,                 \
        .ucode_api_ok = IWL6000_UCODE_API_OK,                   \
        .ucode_api_min = IWL6000_UCODE_API_MIN,                 \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .valid_tx_ant = ANT_BC,         /* .cfg overwrite */    \
        .valid_rx_ant = ANT_BC,         /* .cfg overwrite */    \
        .eeprom_ver = EEPROM_6000_EEPROM_VERSION,               \
@@ -487,6 +490,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
        .fw_name_pre = IWL6050_FW_PRE,                          \
        .ucode_api_max = IWL6050_UCODE_API_MAX,                 \
        .ucode_api_min = IWL6050_UCODE_API_MIN,                 \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .valid_tx_ant = ANT_AB,         /* .cfg overwrite */    \
        .valid_rx_ant = ANT_AB,         /* .cfg overwrite */    \
        .lib = &iwl6000_lib,                                    \
@@ -512,6 +517,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
        .fw_name_pre = IWL6050_FW_PRE,                          \
        .ucode_api_max = IWL6050_UCODE_API_MAX,                 \
        .ucode_api_min = IWL6050_UCODE_API_MIN,                 \
+       .max_inst_size = IWL60_RTC_INST_SIZE,                   \
+       .max_data_size = IWL60_RTC_DATA_SIZE,                   \
        .lib = &iwl6000_lib,                                    \
        .additional_nic_config = iwl6150_additional_nic_config, \
        .eeprom_ver = EEPROM_6150_EEPROM_VERSION,               \
@@ -537,6 +544,8 @@ struct iwl_cfg iwl6000_3agn_cfg = {
        .ucode_api_max = IWL6000_UCODE_API_MAX,
        .ucode_api_ok = IWL6000_UCODE_API_OK,
        .ucode_api_min = IWL6000_UCODE_API_MIN,
+       .max_inst_size = IWL60_RTC_INST_SIZE,
+       .max_data_size = IWL60_RTC_DATA_SIZE,
        .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
        .lib = &iwl6000_lib,
index 6aa009827865d677dfd512bafb23038ecc00ae8f..988ee454a9446773a94feea6fb6642c3e187feb6 100644 (file)
@@ -68,6 +68,8 @@
 #include "iwl-agn-calib.h"
 #include "iwl-trans.h"
 #include "iwl-agn.h"
+#include "iwl-wifi.h"
+#include "iwl-ucode.h"
 
 /*****************************************************************************
  * INIT calibrations framework
@@ -634,7 +636,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
        data->last_bad_plcp_cnt_cck = 0;
        data->last_fa_cnt_cck = 0;
 
-       if (priv->enhance_sensitivity_table)
+       if (nic(priv)->fw.enhance_sensitivity_table)
                ret |= iwl_enhance_sensitivity_write(priv);
        else
                ret |= iwl_sensitivity_write(priv);
@@ -745,7 +747,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
 
        iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
        iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
-       if (priv->enhance_sensitivity_table)
+       if (nic(priv)->fw.enhance_sensitivity_table)
                iwl_enhance_sensitivity_write(priv);
        else
                iwl_sensitivity_write(priv);
index a8f7689aaacfb91049941c736ff46660c4830313..c368433f8bc8dc1203d1cd43f05cbf5e269e7cee 100644 (file)
@@ -77,7 +77,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
        tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED;
        tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO;
 
-       if (IWL_UCODE_API(priv->ucode_ver) == 1)
+       if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) == 1)
                tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
        else
                tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
@@ -700,7 +700,7 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv,
                priv->kill_cts_mask = bt_kill_cts_msg[kill_msk];
 
                /* schedule to send runtime bt_config */
-               queue_work(priv->shrd->workqueue, &priv->bt_runtime_config);
+               queue_work(priv->workqueue, &priv->bt_runtime_config);
        }
 }
 
@@ -745,7 +745,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
                                        IWL_BT_COEX_TRAFFIC_LOAD_NONE;
                        }
                        priv->bt_status = coex->bt_status;
-                       queue_work(priv->shrd->workqueue,
+                       queue_work(priv->workqueue,
                                   &priv->bt_traffic_change_work);
                }
        }
index b9ba404d15c1cdd25271175e20848247571aa1de..f88e2e33e2e874a5c6617914d4d793d5791ae207 100644 (file)
@@ -892,7 +892,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
                iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
 
-               queue_work(priv->shrd->workqueue, &priv->bt_full_concurrency);
+               queue_work(priv->workqueue, &priv->bt_full_concurrency);
        }
 }
 
index a14ddab783ea6985907c3693cc131d77bcf60b51..aee7d060d317ab8ea557ffbc1a0ba271cd277240 100644 (file)
@@ -581,7 +581,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
        if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) &&
            (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
                iwlagn_rx_calc_noise(priv);
-               queue_work(priv->shrd->workqueue, &priv->run_time_calib_work);
+               queue_work(priv->workqueue, &priv->run_time_calib_work);
        }
        if (cfg(priv)->lib->temperature && change)
                cfg(priv)->lib->temperature(priv);
index 8ca9570ec36539b7753e79783d452db6dd8fdec4..35dd7e364b4652831d1d2b1fc7b7c5bb20415504 100644 (file)
@@ -900,6 +900,22 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                }
        }
 
+       /*
+        * If the ucode decides to do beacon filtering before
+        * association, it will lose beacons that are needed
+        * before sending frames out on passive channels. This
+        * causes association failures on those channels. Enable
+        * receiving beacons in such cases.
+        */
+
+       if (vif->type == NL80211_IFTYPE_STATION) {
+               if (!bss_conf->assoc)
+                       ctx->staging.filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
+               else
+                       ctx->staging.filter_flags &=
+                                                   ~RXON_FILTER_BCON_AWARE_MSK;
+       }
+
        if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
                iwlagn_commit_rxon(priv, ctx);
 
index c728ed75584e0dad2eecfedb40bf1cb9a8bfd2c6..56d7c0e38163eeb4240f60f43ebe28dd54bf4768 100644 (file)
@@ -568,7 +568,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
                return;
 
        IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n");
-       queue_work(priv->shrd->workqueue, &priv->ct_enter);
+       queue_work(priv->workqueue, &priv->ct_enter);
 }
 
 void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
@@ -577,7 +577,7 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
                return;
 
        IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n");
-       queue_work(priv->shrd->workqueue, &priv->ct_exit);
+       queue_work(priv->workqueue, &priv->ct_exit);
 }
 
 static void iwl_bg_tt_work(struct work_struct *work)
@@ -600,7 +600,7 @@ void iwl_tt_handler(struct iwl_priv *priv)
                return;
 
        IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n");
-       queue_work(priv->shrd->workqueue, &priv->tt_work);
+       queue_work(priv->workqueue, &priv->tt_work);
 }
 
 /* Thermal throttling initialization
index 64f8db685dc50fbdf72a5927331fc93d344a9f10..da18a8fc9af71516abd2a839062a5620489892d0 100644 (file)
@@ -983,7 +983,7 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
        if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) {
                IWL_ERR(priv, "Tx flush command to flush out all frames\n");
                if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-                       queue_work(priv->shrd->workqueue, &priv->tx_flush);
+                       queue_work(priv->workqueue, &priv->tx_flush);
        }
 }
 
index 8837171ad55301af44eb72873beed8b5536b20f5..e8fed167f97ee0b168020e4a85a5621473555d35 100644 (file)
@@ -618,7 +618,7 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
          .valid = cpu_to_le32(valid_tx_ant),
        };
 
-       if (IWL_UCODE_API(priv->ucode_ver) > 1) {
+       if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) > 1) {
                IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
                return iwl_trans_send_cmd_pdu(trans(priv),
                                        TX_ANT_CONFIGURATION_CMD,
@@ -738,14 +738,14 @@ int iwl_alive_start(struct iwl_priv *priv)
        return iwl_power_update_mode(priv, true);
 }
 
-static void iwl_cancel_deferred_work(struct iwl_priv *priv);
-
-void __iwl_down(struct iwl_priv *priv)
+void iwl_down(struct iwl_priv *priv)
 {
        int exit_pending;
 
        IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
 
+       lockdep_assert_held(&priv->shrd->mutex);
+
        iwl_scan_cancel_timeout(priv, 200);
 
        /*
@@ -803,15 +803,6 @@ void __iwl_down(struct iwl_priv *priv)
        priv->beacon_skb = NULL;
 }
 
-void iwl_down(struct iwl_priv *priv)
-{
-       mutex_lock(&priv->shrd->mutex);
-       __iwl_down(priv);
-       mutex_unlock(&priv->shrd->mutex);
-
-       iwl_cancel_deferred_work(priv);
-}
-
 /*****************************************************************************
  *
  * Workqueue callbacks
@@ -869,7 +860,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)
        bt_status = priv->bt_status;
        bt_is_sco = priv->bt_is_sco;
 
-       __iwl_down(priv);
+       iwl_down(priv);
 
        priv->bt_full_concurrent = bt_full_concurrent;
        priv->bt_ci_compliance = bt_ci_compliance;
@@ -939,7 +930,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work)
 
 static void iwl_setup_deferred_work(struct iwl_priv *priv)
 {
-       priv->shrd->workqueue = create_singlethread_workqueue(DRV_NAME);
+       priv->workqueue = create_singlethread_workqueue(DRV_NAME);
 
        init_waitqueue_head(&priv->shrd->wait_command_queue);
 
@@ -970,7 +961,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
        priv->watchdog.function = iwl_bg_watchdog;
 }
 
-static void iwl_cancel_deferred_work(struct iwl_priv *priv)
+void iwl_cancel_deferred_work(struct iwl_priv *priv)
 {
        if (cfg(priv)->lib->cancel_deferred_work)
                cfg(priv)->lib->cancel_deferred_work(priv);
@@ -1091,7 +1082,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
 #define IWL_RX_BUF_SIZE_4K (4 * 1024)
 #define IWL_RX_BUF_SIZE_8K (8 * 1024)
 
-static int iwl_set_hw_params(struct iwl_priv *priv)
+static void iwl_set_hw_params(struct iwl_priv *priv)
 {
        if (iwlagn_mod_params.amsdu_size_8K)
                hw_params(priv).rx_page_order =
@@ -1111,7 +1102,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
        hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout;
 
        /* Device-specific setup */
-       return cfg(priv)->lib->set_hw_params(priv);
+       cfg(priv)->lib->set_hw_params(priv);
 }
 
 
@@ -1248,11 +1239,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
        /************************
         * 5. Setup HW constants
         ************************/
-       if (iwl_set_hw_params(priv)) {
-               err = -ENOENT;
-               IWL_ERR(priv, "failed to set hw parameters\n");
-               goto out_free_eeprom;
-       }
+       iwl_set_hw_params(priv);
 
        /*******************
         * 6. Setup priv
@@ -1273,17 +1260,17 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
        iwl_power_initialize(priv);
        iwl_tt_initialize(priv);
 
-       init_completion(&priv->firmware_loading_complete);
+       init_completion(&nic(priv)->request_firmware_complete);
 
-       err = iwl_request_firmware(priv, true);
+       err = iwl_request_firmware(nic(priv), true);
        if (err)
                goto out_destroy_workqueue;
 
        return 0;
 
 out_destroy_workqueue:
-       destroy_workqueue(priv->shrd->workqueue);
-       priv->shrd->workqueue = NULL;
+       destroy_workqueue(priv->workqueue);
+       priv->workqueue = NULL;
        iwl_uninit_drv(priv);
 out_free_eeprom:
        iwl_eeprom_free(priv->shrd);
@@ -1296,7 +1283,7 @@ out:
 
 void __devexit iwl_remove(struct iwl_priv * priv)
 {
-       wait_for_completion(&priv->firmware_loading_complete);
+       wait_for_completion(&nic(priv)->request_firmware_complete);
 
        IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
 
@@ -1316,18 +1303,18 @@ void __devexit iwl_remove(struct iwl_priv * priv)
        /*This will stop the queues, move the device to low power state */
        iwl_trans_stop_device(trans(priv));
 
-       iwl_dealloc_ucode(trans(priv));
+       iwl_dealloc_ucode(nic(priv));
 
        iwl_eeprom_free(priv->shrd);
 
        /*netif_stop_queue(dev); */
-       flush_workqueue(priv->shrd->workqueue);
+       flush_workqueue(priv->workqueue);
 
        /* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes
-        * priv->shrd->workqueue... so we can't take down the workqueue
+        * priv->workqueue... so we can't take down the workqueue
         * until now... */
-       destroy_workqueue(priv->shrd->workqueue);
-       priv->shrd->workqueue = NULL;
+       destroy_workqueue(priv->workqueue);
+       priv->workqueue = NULL;
        iwl_free_traffic_mem(priv);
 
        iwl_uninit_drv(priv);
index 37c325ff6e8cbea856ba6bbcf8f462365aa9ac34..79894aca9644c9aad26bc1f8f96d8684ed798553 100644 (file)
 
 #include "iwl-dev.h"
 
-struct iwlagn_ucode_capabilities {
-       u32 max_probe_length;
-       u32 standard_phy_calibration_size;
-       u32 flags;
-};
+struct iwl_ucode_capabilities;
 
 extern struct ieee80211_ops iwlagn_hw_ops;
 
@@ -81,14 +77,14 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
        hdr->data_valid = 1;
 }
 
-void __iwl_down(struct iwl_priv *priv);
 void iwl_down(struct iwl_priv *priv);
+void iwl_cancel_deferred_work(struct iwl_priv *priv);
 void iwlagn_prepare_restart(struct iwl_priv *priv);
 
 /* MAC80211 */
 struct ieee80211_hw *iwl_alloc_all(void);
 int iwlagn_mac_setup_register(struct iwl_priv *priv,
-                             struct iwlagn_ucode_capabilities *capa);
+                             struct iwl_ucode_capabilities *capa);
 void iwlagn_mac_unregister(struct iwl_priv *priv);
 
 /* RXON */
index 0677b3dfbfb2de98b351db54666f37841d4daeb1..f3b72bc84d25f2fe8d4cc0458e6c7f70fc5f5e84 100644 (file)
@@ -643,7 +643,7 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv,
  * NOTE:  Does not commit to the hardware; it sets appropriate bit fields
  * in the staging RXON flag structure based on the ch->band
  */
-int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
+void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
                         struct iwl_rxon_context *ctx)
 {
        enum ieee80211_band band = ch->band;
@@ -651,7 +651,7 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
 
        if ((le16_to_cpu(ctx->staging.channel) == channel) &&
            (priv->band == band))
-               return 0;
+               return;
 
        ctx->staging.channel = cpu_to_le16(channel);
        if (band == IEEE80211_BAND_5GHZ)
@@ -663,7 +663,6 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
 
        IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
 
-       return 0;
 }
 
 void iwl_set_flags_for_band(struct iwl_priv *priv,
@@ -875,7 +874,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
                if (iwlagn_mod_params.restart_fw) {
                        IWL_DEBUG_FW_ERRORS(priv,
                                  "Restarting adapter due to uCode error.\n");
-                       queue_work(priv->shrd->workqueue, &priv->restart);
+                       queue_work(priv->workqueue, &priv->restart);
                } else
                        IWL_DEBUG_FW_ERRORS(priv,
                                  "Detected FW error, but not restarting\n");
index 8d60dcf6f2eb87b10da6e33446c440b5a6609ead..930e247bbae6337e3d17a2cde92f6186edb1e45c 100644 (file)
@@ -76,7 +76,7 @@ struct iwl_cmd;
 
 struct iwl_lib_ops {
        /* set hw dependent parameters */
-       int (*set_hw_params)(struct iwl_priv *priv);
+       void (*set_hw_params)(struct iwl_priv *priv);
        /* setup BT Rx handler */
        void (*bt_rx_handler_setup)(struct iwl_priv *priv);
        /* setup BT related deferred work */
@@ -169,7 +169,7 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                           int hw_decrypt);
 int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
+void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
                         struct iwl_rxon_context *ctx);
 void iwl_set_flags_for_band(struct iwl_priv *priv,
                            struct iwl_rxon_context *ctx,
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c
new file mode 100644 (file)
index 0000000..4bc2e70
--- /dev/null
@@ -0,0 +1,127 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 2011 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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+#include <linux/interrupt.h>
+#include "iwl-debug.h"
+
+#define __iwl_fn(fn)                                           \
+void __iwl_ ##fn(struct device *dev, const char *fmt, ...)     \
+{                                                              \
+       struct va_format vaf = {                                \
+               .fmt = fmt,                                     \
+       };                                                      \
+       va_list args;                                           \
+                                                               \
+       va_start(args, fmt);                                    \
+       vaf.va = &args;                                         \
+       dev_ ##fn(dev, "%pV", &vaf);                            \
+       trace_iwlwifi_ ##fn(&vaf);                              \
+       va_end(args);                                           \
+}
+
+__iwl_fn(warn)
+__iwl_fn(info)
+__iwl_fn(crit)
+
+void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
+               const char *fmt, ...)
+{
+       struct va_format vaf = {
+               .fmt = fmt,
+       };
+       va_list args;
+
+       va_start(args, fmt);
+       vaf.va = &args;
+       if (!trace_only) {
+               if (rfkill_prefix)
+                       dev_err(dev, "(RFKILL) %pV", &vaf);
+               else
+                       dev_err(dev, "%pV", &vaf);
+       }
+       trace_iwlwifi_err(&vaf);
+       va_end(args);
+}
+
+#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
+void __iwl_dbg(struct iwl_shared *shared, struct device *dev,
+              u32 level, bool limit, const char *function,
+              const char *fmt, ...)
+{
+       struct va_format vaf = {
+               .fmt = fmt,
+       };
+       va_list args;
+
+       va_start(args, fmt);
+       vaf.va = &args;
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (iwl_get_debug_level(shared) & level &&
+           (!limit || net_ratelimit()))
+               dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U',
+                       function, &vaf);
+#endif
+       trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf);
+       va_end(args);
+}
+#endif
index 351b41d7f4fd11107068f770e7e6ea014034bdc9..bfc08494ed22682e5fd71a9c11b99abcc1c8715f 100644 (file)
 
 #include "iwl-bus.h"
 #include "iwl-shared.h"
+#include "iwl-devtrace.h"
 
 struct iwl_priv;
 
-/*No matter what is m (priv, bus, trans), this will work */
-#define IWL_ERR(m, f, a...) dev_err(trans(m)->dev, f, ## a)
-#define IWL_WARN(m, f, a...) dev_warn(trans(m)->dev, f, ## a)
-#define IWL_INFO(m, f, a...) dev_info(trans(m)->dev, f, ## a)
-#define IWL_CRIT(m, f, a...) dev_crit(trans(m)->dev, f, ## a)
+void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace,
+               const char *fmt, ...);
+void __iwl_warn(struct device *dev, const char *fmt, ...);
+void __iwl_info(struct device *dev, const char *fmt, ...);
+void __iwl_crit(struct device *dev, const char *fmt, ...);
+
+/* No matter what is m (priv, bus, trans), this will work */
+#define IWL_ERR(m, f, a...) __iwl_err(trans(m)->dev, false, false, f, ## a)
+#define IWL_WARN(m, f, a...) __iwl_warn(trans(m)->dev, f, ## a)
+#define IWL_INFO(m, f, a...) __iwl_info(trans(m)->dev, f, ## a)
+#define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a)
+
+#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
+void __iwl_dbg(struct iwl_shared *shared, struct device *dev,
+              u32 level, bool limit, const char *function,
+              const char *fmt, ...);
+#else
+static inline void
+__iwl_dbg(struct iwl_shared *shared, struct device *dev,
+         u32 level, bool limit, const char *function,
+         const char *fmt, ...)
+{}
+#endif
 
 #define iwl_print_hex_error(m, p, len)                                 \
 do {                                                                   \
@@ -46,53 +65,35 @@ do {                                                                        \
                       DUMP_PREFIX_OFFSET, 16, 1, p, len, 1);           \
 } while (0)
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-#define IWL_DEBUG(m, level, fmt, ...)                                  \
-do {                                                                   \
-       if (iwl_get_debug_level((m)->shrd) & (level))                   \
-               dev_err(trans(m)->dev, "%c %s " fmt,                    \
-                       in_interrupt() ? 'I' : 'U', __func__,           \
-                       ##__VA_ARGS__);                                 \
-} while (0)
-
-#define IWL_DEBUG_LIMIT(m, level, fmt, ...)                            \
-do {                                                                   \
-       if (iwl_get_debug_level((m)->shrd) & (level) &&                 \
-           net_ratelimit())                                            \
-               dev_err(trans(m)->dev, "%c %s " fmt,                    \
-                       in_interrupt() ? 'I' : 'U', __func__,           \
-                       ##__VA_ARGS__);                                 \
-} while (0)
+#define IWL_DEBUG(m, level, fmt, args...)                              \
+       __iwl_dbg((m)->shrd, trans(m)->dev, level, false, __func__, fmt, ##args)
+#define IWL_DEBUG_LIMIT(m, level, fmt, args...)                                \
+       __iwl_dbg((m)->shrd, trans(m)->dev, level, true, __func__, fmt, ##args)
 
+#ifdef CONFIG_IWLWIFI_DEBUG
 #define iwl_print_hex_dump(m, level, p, len)                           \
 do {                                                                   \
        if (iwl_get_debug_level((m)->shrd) & level)                     \
                print_hex_dump(KERN_DEBUG, "iwl data: ",                \
                               DUMP_PREFIX_OFFSET, 16, 1, p, len, 1);   \
 } while (0)
-
-#define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...)                            \
+#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...)        \
 do {                                                                   \
-       if (!iwl_is_rfkill(p->shrd))                                    \
-               dev_err(trans(p)->dev, "%s%c %s " fmt,                  \
-                       "",                                             \
-                       in_interrupt() ? 'I' : 'U', __func__,           \
-                       ##__VA_ARGS__);                                 \
-       else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO)           \
-               dev_err(trans(p)->dev, "%s%c %s " fmt,                  \
-                       "(RFKILL) ",                                    \
-                       in_interrupt() ? 'I' : 'U', __func__,           \
-                       ##__VA_ARGS__);                                 \
+       if (!iwl_is_rfkill((m)->shrd))                                  \
+               IWL_ERR(m, fmt, ##args);                                \
+       else                                                            \
+               __iwl_err(trans(m)->dev, true,                          \
+                         !(iwl_get_debug_level((m)->shrd) & IWL_DL_RADIO),\
+                         fmt, ##args);                                 \
 } while (0)
-
 #else
-#define IWL_DEBUG(m, level, fmt, args...)
-#define IWL_DEBUG_LIMIT(m, level, fmt, args...)
 #define iwl_print_hex_dump(m, level, p, len)
-#define IWL_DEBUG_QUIET_RFKILL(p, fmt, args...)        \
-do {                                                   \
-       if (!iwl_is_rfkill(p->shrd))                    \
-               IWL_ERR(p, fmt, ##args);                \
+#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...)        \
+do {                                                                   \
+       if (!iwl_is_rfkill((m)->shrd))                                  \
+               IWL_ERR(m, fmt, ##args);                                \
+       else                                                            \
+               __iwl_err(trans(m)->dev, true, true, fmt, ##args);      \
 } while (0)
 #endif                         /* CONFIG_IWLWIFI_DEBUG */
 
index 136de6fb3fa4ae236be455353b140f5deffbfc7e..ad74138e1c7011a233bcdcc204242fa24917077f 100644 (file)
@@ -40,6 +40,7 @@
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-agn.h"
+#include "iwl-wifi.h"
 
 /* create and remove of files */
 #define DEBUGFS_ADD_FILE(name, parent, mode) do {                      \
@@ -234,12 +235,12 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
 
        /* default is to dump the entire data segment */
        if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
-               struct iwl_trans *trans = trans(priv);
+               struct iwl_nic *nic = nic(priv);
                priv->dbgfs_sram_offset = 0x800000;
-               if (trans->shrd->ucode_type == IWL_UCODE_INIT)
-                       priv->dbgfs_sram_len = trans->ucode_init.data.len;
+               if (nic->shrd->ucode_type == IWL_UCODE_INIT)
+                       priv->dbgfs_sram_len = nic->fw.ucode_init.data.len;
                else
-                       priv->dbgfs_sram_len = trans->ucode_rt.data.len;
+                       priv->dbgfs_sram_len = nic->fw.ucode_rt.data.len;
        }
        len = priv->dbgfs_sram_len;
 
@@ -342,7 +343,7 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
 
        return simple_read_from_buffer(user_buf, count, ppos,
                                       priv->wowlan_sram,
-                                      trans(priv)->ucode_wowlan.data.len);
+                                      nic(priv)->fw.ucode_wowlan.data.len);
 }
 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
                                        size_t count, loff_t *ppos)
index aa99457c3a52360ce647b8869ff766207c0c9b59..494c696dc1779468504acd3f4a7675c60c008751 100644 (file)
@@ -696,11 +696,11 @@ struct iwl_testmode_trace {
        dma_addr_t dma_addr;
        bool trace_enabled;
 };
-struct iwl_testmode_sram {
+struct iwl_testmode_mem {
        u32 buff_size;
        u32 num_chunks;
        u8 *buff_addr;
-       bool sram_readed;
+       bool read_in_progress;
 };
 #endif
 
@@ -721,6 +721,8 @@ struct iwl_priv {
        struct ieee80211_rate *ieee_rates;
        struct kmem_cache *tx_cmd_pool;
 
+       struct workqueue_struct *workqueue;
+
        enum ieee80211_band band;
 
        void (*pre_rx_handler)(struct iwl_priv *priv,
@@ -785,13 +787,6 @@ struct iwl_priv {
        /* EEPROM MAC addresses */
        struct mac_address addresses[2];
 
-       /* uCode images, save to reload in case of failure */
-       int fw_index;                   /* firmware we're trying to load */
-       u32 ucode_ver;                  /* version of ucode, copy of
-                                          iwl_ucode.ver */
-
-       char firmware_name[25];
-
        struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
 
        __le16 switch_channel;
@@ -801,7 +796,6 @@ struct iwl_priv {
        u8 start_calib;
        struct iwl_sensitivity_data sensitivity_data;
        struct iwl_chain_noise_data chain_noise_data;
-       bool enhance_sensitivity_table;
        __le16 sensitivity_tbl[HD_TABLE_SIZE];
        __le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES];
 
@@ -869,11 +863,6 @@ struct iwl_priv {
        struct iwl_rx_phy_res last_phy_res;
        bool last_phy_res_valid;
 
-       struct completion firmware_loading_complete;
-
-       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
-       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
-
        /*
         * chain noise reset and gain commands are the
         * two extra calibration commands follows the standard
@@ -964,7 +953,7 @@ struct iwl_priv {
        bool led_registered;
 #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
        struct iwl_testmode_trace testmode_trace;
-       struct iwl_testmode_sram testmode_sram;
+       struct iwl_testmode_mem testmode_mem;
        u32 tm_fixed_rate;
 #endif
 
index 4d892211ce4ca973cef472728ed144eedda6c09a..96e62338cec0a9ce489d35a85ef0b20abff76c57 100644 (file)
 #undef TRACE_EVENT
 #define TRACE_EVENT(name, proto, ...) \
 static inline void trace_ ## name(proto) {}
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(...)
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(evt_class, name, proto, ...) \
+static inline void trace_ ## name(proto) {}
 #endif
 
 #define PRIV_ENTRY     __field(void *, priv)
@@ -163,6 +168,66 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
                  __entry->p_entry)
 );
 
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM iwlwifi_msg
+
+#define MAX_MSG_LEN    100
+
+DECLARE_EVENT_CLASS(iwlwifi_msg_event,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf),
+       TP_STRUCT__entry(
+               __dynamic_array(char, msg, MAX_MSG_LEN)
+       ),
+       TP_fast_assign(
+               WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+                                      MAX_MSG_LEN, vaf->fmt,
+                                      *vaf->va) >= MAX_MSG_LEN);
+       ),
+       TP_printk("%s", (char *)__get_dynamic_array(msg))
+);
+
+DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf)
+);
+
+TRACE_EVENT(iwlwifi_dbg,
+       TP_PROTO(u32 level, bool in_interrupt, const char *function,
+                struct va_format *vaf),
+       TP_ARGS(level, in_interrupt, function, vaf),
+       TP_STRUCT__entry(
+               __field(u32, level)
+               __field(u8, in_interrupt)
+               __string(function, function)
+               __dynamic_array(char, msg, MAX_MSG_LEN)
+       ),
+       TP_fast_assign(
+               __entry->level = level;
+               __entry->in_interrupt = in_interrupt;
+               __assign_str(function, function);
+               WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+                                      MAX_MSG_LEN, vaf->fmt,
+                                      *vaf->va) >= MAX_MSG_LEN);
+       ),
+       TP_printk("%s", (char *)__get_dynamic_array(msg))
+);
+
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM iwlwifi
 
index d8025fee7e0d56e7d8bf3ce434d2fd9991b3de66..9c29234221fd2fbb23ec25048a27b8bfb11511f1 100644 (file)
@@ -136,7 +136,7 @@ iwlagn_iface_combinations_p2p[] = {
  * other mac80211 functions grouped here.
  */
 int iwlagn_mac_setup_register(struct iwl_priv *priv,
-                                 struct iwlagn_ucode_capabilities *capa)
+                                 struct iwl_ucode_capabilities *capa)
 {
        int ret;
        struct ieee80211_hw *hw = priv->hw;
@@ -195,7 +195,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
                            WIPHY_FLAG_DISABLE_BEACON_HINTS |
                            WIPHY_FLAG_IBSS_RSN;
 
-       if (trans(priv)->ucode_wowlan.code.len &&
+       if (nic(priv)->fw.ucode_wowlan.code.len &&
            device_can_wakeup(trans(priv)->dev)) {
                hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
                                          WIPHY_WOWLAN_DISCONNECT |
@@ -296,7 +296,7 @@ static int __iwl_up(struct iwl_priv *priv)
 
  error:
        set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
-       __iwl_down(priv);
+       iwl_down(priv);
        clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
 
        IWL_ERR(priv, "Unable to initialize device.\n");
@@ -341,9 +341,13 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 
        priv->is_open = 0;
 
+       mutex_lock(&priv->shrd->mutex);
        iwl_down(priv);
+       mutex_unlock(&priv->shrd->mutex);
+
+       iwl_cancel_deferred_work(priv);
 
-       flush_workqueue(priv->shrd->workqueue);
+       flush_workqueue(priv->workqueue);
 
        /* User space software may expect getting rfkill changes
         * even if interface is down, trans->down will leave the RF
@@ -453,17 +457,17 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
                if (ret == 0) {
-                       struct iwl_trans *trans = trans(priv);
+                       struct iwl_nic *nic = nic(priv);
                        if (!priv->wowlan_sram)
                                priv->wowlan_sram =
-                                       kzalloc(trans->ucode_wowlan.data.len,
+                                       kzalloc(nic->fw.ucode_wowlan.data.len,
                                                GFP_KERNEL);
 
                        if (priv->wowlan_sram)
                                _iwl_read_targ_mem_words(
                                        trans(priv), 0x800000,
                                        priv->wowlan_sram,
-                                       trans->ucode_wowlan.data.len / 4);
+                                       nic->fw.ucode_wowlan.data.len / 4);
                }
 #endif
        }
@@ -1117,7 +1121,7 @@ static int iwlagn_mac_set_tim(struct ieee80211_hw *hw,
 {
        struct iwl_priv *priv = hw->priv;
 
-       queue_work(priv->shrd->workqueue, &priv->beacon_update);
+       queue_work(priv->workqueue, &priv->beacon_update);
 
        return 0;
 }
index 3e2fce4ce00c6c0768380313f5958a0ae6f01dce..5190670205344e1d0216acb76fb8159ed09902b7 100644 (file)
@@ -70,6 +70,7 @@
 #include "iwl-trans.h"
 #include "iwl-csr.h"
 #include "iwl-cfg.h"
+#include "iwl-wifi.h"
 
 #define IWL_PCI_DEVICE(dev, subdev, cfg) \
        .vendor = PCI_VENDOR_ID_INTEL,  .device = (dev), \
@@ -282,13 +283,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        bus->shrd->bus = bus;
 
+       /* temporarily create this here */
+       bus->shrd->nic = kzalloc(sizeof(*bus->shrd->nic), GFP_KERNEL);
+       if (!bus->shrd->nic) {
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "Couldn't allocate iwl_nic");
+               err = -ENOMEM;
+               goto out_free_bus;
+       }
+       /* and initialize it as well, temporarily */
+       bus->shrd->nic->shrd = bus->shrd;
        pci_set_drvdata(pdev, bus);
 
 #ifdef CONFIG_IWLWIFI_IDI
        trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent);
        if (trans(bus) == NULL) {
                err = -ENOMEM;
-               goto out_free_bus;
+               goto out_free_nic;
        }
 
        err = iwl_probe(bus, &trans_ops_idi, cfg);
@@ -296,7 +307,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent);
        if (trans(bus) == NULL) {
                err = -ENOMEM;
-               goto out_free_bus;
+               goto out_free_nic;
        }
 
        err = iwl_probe(bus, &trans_ops_pcie, cfg);
@@ -309,6 +320,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 out_free_trans:
        iwl_trans_free(trans(bus));
        pci_set_drvdata(pdev, NULL);
+out_free_nic:
+       kfree(bus->shrd->nic);
 out_free_bus:
        kfree(bus->shrd);
        kfree(bus);
@@ -325,6 +338,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 
        pci_set_drvdata(pdev, NULL);
 
+       kfree(bus->shrd->nic);
        kfree(bus->shrd);
        kfree(bus);
 }
index 7f2e3a1c80efeaea0ae6b7828cd05f6866c19173..42ee1c410efd7cbfc621749c89b72b333ded4a29 100644 (file)
@@ -218,7 +218,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
 int iwl_scan_cancel(struct iwl_priv *priv)
 {
        IWL_DEBUG_SCAN(priv, "Queuing abort scan\n");
-       queue_work(priv->shrd->workqueue, &priv->abort_scan);
+       queue_work(priv->workqueue, &priv->abort_scan);
        return 0;
 }
 
@@ -354,7 +354,7 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
         */
        set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status);
        clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
-       queue_work(priv->shrd->workqueue, &priv->scan_completed);
+       queue_work(priv->workqueue, &priv->scan_completed);
 
        if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
            iwl_advanced_bt_coexist(priv) &&
@@ -374,7 +374,7 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
                                IWL_BT_COEX_TRAFFIC_LOAD_NONE;
                }
                priv->bt_status = scan_notif->bt_status;
-               queue_work(priv->shrd->workqueue,
+               queue_work(priv->workqueue,
                           &priv->bt_traffic_change_work);
        }
        return 0;
@@ -950,7 +950,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
                return ret;
        }
 
-       queue_delayed_work(priv->shrd->workqueue, &priv->scan_check,
+       queue_delayed_work(priv->workqueue, &priv->scan_check,
                           IWL_SCAN_CHECK_WATCHDOG);
 
        return 0;
@@ -963,7 +963,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
  */
 void iwl_internal_short_hw_scan(struct iwl_priv *priv)
 {
-       queue_work(priv->shrd->workqueue, &priv->start_internal_scan);
+       queue_work(priv->workqueue, &priv->start_internal_scan);
 }
 
 static void iwl_bg_start_internal_scan(struct work_struct *work)
index 63d4a4fc5b9e38586389a6ead2eae59f50730e66..f810b41db9dfba0a27cdca623589ec83f165fc37 100644 (file)
@@ -173,8 +173,6 @@ struct iwl_mod_params {
  * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX)
  * @sku: sku read from EEPROM
  * @rx_page_order: Rx buffer page order
- * @max_inst_size: for ucode use
- * @max_data_size: for ucode use
  * @ct_kill_threshold: temperature threshold - in hw dependent unit
  * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit
  *     relevant for 1000, 6000 and up
@@ -192,8 +190,6 @@ struct iwl_hw_params {
        bool shadow_reg_enable;
        u16 sku;
        u32 rx_page_order;
-       u32 max_inst_size;
-       u32 max_data_size;
        u32 ct_kill_threshold;
        u32 ct_kill_exit_threshold;
        unsigned int wd_timeout;
@@ -283,6 +279,8 @@ enum iwl_led_mode {
  * @ucode_api_ok: oldest version of the uCode API that is OK to load
  *     without a warning, for use in transitions
  * @ucode_api_min: Lowest version of uCode API supported by driver.
+ * @max_inst_size: The maximal length of the fw inst section
+ * @max_data_size: The maximal length of the fw data section
  * @valid_tx_ant: valid transmit antenna
  * @valid_rx_ant: valid receive antenna
  * @sku: sku information from EEPROM
@@ -320,6 +318,8 @@ struct iwl_cfg {
        const unsigned int ucode_api_max;
        const unsigned int ucode_api_ok;
        const unsigned int ucode_api_min;
+       const u32 max_data_size;
+       const u32 max_inst_size;
        u8   valid_tx_ant;
        u8   valid_rx_ant;
        u16  sku;
@@ -358,8 +358,8 @@ struct iwl_cfg {
  * @cfg: see struct iwl_cfg
  * @priv: pointer to the upper layer data
  * @trans: pointer to the transport layer data
+ * @nic: pointer to the nic data
  * @hw_params: see struct iwl_hw_params
- * @workqueue: the workqueue used by all the layers of the driver
  * @lock: protect general shared data
  * @sta_lock: protects the station table.
  *     If lock and sta_lock are needed, lock must be acquired first.
@@ -389,9 +389,9 @@ struct iwl_shared {
        struct iwl_cfg *cfg;
        struct iwl_priv *priv;
        struct iwl_trans *trans;
+       struct iwl_nic *nic;
        struct iwl_hw_params hw_params;
 
-       struct workqueue_struct *workqueue;
        spinlock_t lock;
        spinlock_t sta_lock;
        struct mutex mutex;
@@ -420,6 +420,7 @@ struct iwl_shared {
 #define priv(_m)       ((_m)->shrd->priv)
 #define cfg(_m)                ((_m)->shrd->cfg)
 #define bus(_m)                ((_m)->shrd->bus)
+#define nic(_m)                ((_m)->shrd->nic)
 #define trans(_m)      ((_m)->shrd->trans)
 #define hw_params(_m)  ((_m)->shrd->hw_params)
 
index df7ab332c833a38e41e5dc213d8a1221792b3cd2..80955ed06e821c04fbde46c083de35fa07116ac6 100644 (file)
 #include "iwl-bus.h"
 #include "iwl-fh.h"
 
+
+/* Periphery registers absolute lower bound. This is used in order to
+ * differentiate registery access through HBUS_TARG_PRPH_* and
+ * HBUS_TARG_MEM_* accesses.
+ */
+#define IWL_TM_ABS_PRPH_START (0xA00000)
+
 /* The TLVs used in the gnl message policy between the kernel module and
  * user space application. iwl_testmode_gnl_msg_policy is to be carried
  * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
@@ -110,9 +117,9 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
 
        [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
 
-       [IWL_TM_ATTR_SRAM_ADDR] = { .type = NLA_U32, },
-       [IWL_TM_ATTR_SRAM_SIZE] = { .type = NLA_U32, },
-       [IWL_TM_ATTR_SRAM_DUMP] = { .type = NLA_UNSPEC, },
+       [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, },
+       [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, },
+       [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, },
 
        [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
        [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
@@ -172,7 +179,7 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
        skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
                                                                GFP_ATOMIC);
        if (skb == NULL) {
-               IWL_DEBUG_INFO(priv,
+               IWL_ERR(priv,
                         "Run out of memory for messages to user space ?\n");
                return;
        }
@@ -183,24 +190,24 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
 
 nla_put_failure:
        kfree_skb(skb);
-       IWL_DEBUG_INFO(priv, "Ouch, overran buffer, check allocation!\n");
+       IWL_ERR(priv, "Ouch, overran buffer, check allocation!\n");
 }
 
 void iwl_testmode_init(struct iwl_priv *priv)
 {
        priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
        priv->testmode_trace.trace_enabled = false;
-       priv->testmode_sram.sram_readed = false;
+       priv->testmode_mem.read_in_progress = false;
 }
 
-static void iwl_sram_cleanup(struct iwl_priv *priv)
+static void iwl_mem_cleanup(struct iwl_priv *priv)
 {
-       if (priv->testmode_sram.sram_readed) {
-               kfree(priv->testmode_sram.buff_addr);
-               priv->testmode_sram.buff_addr = NULL;
-               priv->testmode_sram.buff_size = 0;
-               priv->testmode_sram.num_chunks = 0;
-               priv->testmode_sram.sram_readed = false;
+       if (priv->testmode_mem.read_in_progress) {
+               kfree(priv->testmode_mem.buff_addr);
+               priv->testmode_mem.buff_addr = NULL;
+               priv->testmode_mem.buff_size = 0;
+               priv->testmode_mem.num_chunks = 0;
+               priv->testmode_mem.read_in_progress = false;
        }
 }
 
@@ -226,9 +233,10 @@ static void iwl_trace_cleanup(struct iwl_priv *priv)
 void iwl_testmode_cleanup(struct iwl_priv *priv)
 {
        iwl_trace_cleanup(priv);
-       iwl_sram_cleanup(priv);
+       iwl_mem_cleanup(priv);
 }
 
+
 /*
  * This function handles the user application commands to the ucode.
  *
@@ -237,8 +245,10 @@ void iwl_testmode_cleanup(struct iwl_priv *priv)
  * host command to the ucode.
  *
  * If any mandatory field is missing, -ENOMSG is replied to the user space
- * application; otherwise, the actual execution result of the host command to
- * ucode is replied.
+ * application; otherwise, waits for the host command to be sent and checks
+ * the return code. In case or error, it is returned, otherwise a reply is
+ * allocated and the reply RX packet
+ * is returned.
  *
  * @hw: ieee80211_hw object that represents the device
  * @tb: gnl message fields from the user space
@@ -247,25 +257,68 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
 {
        struct iwl_priv *priv = hw->priv;
        struct iwl_host_cmd cmd;
+       struct iwl_rx_packet *pkt;
+       struct sk_buff *skb;
+       void *reply_buf;
+       u32 reply_len;
+       int ret;
+       bool cmd_want_skb;
 
        memset(&cmd, 0, sizeof(struct iwl_host_cmd));
 
        if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
            !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
-               IWL_DEBUG_INFO(priv,
-                       "Error finding ucode command mandatory fields\n");
+               IWL_ERR(priv, "Missing ucode command mandatory fields\n");
                return -ENOMSG;
        }
 
-       cmd.flags = CMD_ON_DEMAND;
+       cmd.flags = CMD_ON_DEMAND | CMD_SYNC;
+       cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]);
+       if (cmd_want_skb)
+               cmd.flags |= CMD_WANT_SKB;
+
        cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
        cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
        cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
        cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
-       IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
+       IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
                                " len %d\n", cmd.id, cmd.flags, cmd.len[0]);
-       /* ok, let's submit the command to ucode */
-       return iwl_trans_send_cmd(trans(priv), &cmd);
+
+       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       if (ret) {
+               IWL_ERR(priv, "Failed to send hcmd\n");
+               return ret;
+       }
+       if (!cmd_want_skb)
+               return ret;
+
+       /* Handling return of SKB to the user */
+       pkt = (struct iwl_rx_packet *)cmd.reply_page;
+       if (!pkt) {
+               IWL_ERR(priv, "HCMD received a null response packet\n");
+               return ret;
+       }
+
+       reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+       skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, reply_len + 20);
+       reply_buf = kmalloc(reply_len, GFP_KERNEL);
+       if (!skb || !reply_buf) {
+               kfree_skb(skb);
+               kfree(reply_buf);
+               return -ENOMEM;
+       }
+
+       /* The reply is in a page, that we cannot send to user space. */
+       memcpy(reply_buf, &(pkt->hdr), reply_len);
+       iwl_free_pages(priv->shrd, cmd.reply_page);
+
+       NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
+       NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf);
+       return cfg80211_testmode_reply(skb);
+
+nla_put_failure:
+       IWL_DEBUG_INFO(priv, "Failed creating NL attributes\n");
+       return -ENOMSG;
 }
 
 
@@ -295,7 +348,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
        int status = 0;
 
        if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
-               IWL_DEBUG_INFO(priv, "Error finding register offset\n");
+               IWL_ERR(priv, "Missing register offset\n");
                return -ENOMSG;
        }
        ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
@@ -309,7 +362,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
                cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 ||
                cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) &&
                (ofs >= FH_MEM_UPPER_BOUND)) {
-               IWL_DEBUG_INFO(priv, "offset out of segment (0x0 - 0x%x)\n",
+               IWL_ERR(priv, "offset out of segment (0x0 - 0x%x)\n",
                        FH_MEM_UPPER_BOUND);
                return -EINVAL;
        }
@@ -321,19 +374,17 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
 
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
                NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
                status = cfg80211_testmode_reply(skb);
                if (status < 0)
-                       IWL_DEBUG_INFO(priv,
-                                      "Error sending msg : %d\n", status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                break;
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
                if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
-                       IWL_DEBUG_INFO(priv,
-                                      "Error finding value to write\n");
+                       IWL_ERR(priv, "Missing value to write\n");
                        return -ENOMSG;
                } else {
                        val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
@@ -343,7 +394,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
                break;
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
                if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
-                       IWL_DEBUG_INFO(priv, "Error finding value to write\n");
+                       IWL_ERR(priv, "Missing value to write\n");
                        return -ENOMSG;
                } else {
                        val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
@@ -351,34 +402,8 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
                        iwl_write8(trans(priv), ofs, val8);
                }
                break;
-       case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
-               val32 = iwl_read_prph(trans(priv), ofs);
-               IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
-
-               skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
-               if (!skb) {
-                       IWL_DEBUG_INFO(priv, "Error allocating memory\n");
-                       return -ENOMEM;
-               }
-               NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
-               status = cfg80211_testmode_reply(skb);
-               if (status < 0)
-                       IWL_DEBUG_INFO(priv,
-                                       "Error sending msg : %d\n", status);
-               break;
-       case IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
-               if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
-                       IWL_DEBUG_INFO(priv,
-                                       "Error finding value to write\n");
-                       return -ENOMSG;
-               } else {
-                       val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
-                       IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
-                       iwl_write_prph(trans(priv), ofs, val32);
-               }
-               break;
        default:
-               IWL_DEBUG_INFO(priv, "Unknown testmode register command ID\n");
+               IWL_ERR(priv, "Unknown testmode register command ID\n");
                return -ENOSYS;
        }
 
@@ -400,14 +425,13 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
                                      NULL, NULL);
        ret = iwl_init_alive_start(trans(priv));
        if (ret) {
-               IWL_DEBUG_INFO(priv,
-                       "Error configuring init calibration: %d\n", ret);
+               IWL_ERR(priv, "Fail init calibration: %d\n", ret);
                goto cfg_init_calib_error;
        }
 
        ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ);
        if (ret)
-               IWL_DEBUG_INFO(priv, "Error detecting"
+               IWL_ERR(priv, "Error detecting"
                        " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
        return ret;
 
@@ -448,8 +472,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
                                                        rsp_data_len + 20);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv,
-                                      "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
                NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
@@ -458,15 +481,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                        rsp_data_len, rsp_data_ptr);
                status = cfg80211_testmode_reply(skb);
                if (status < 0)
-                       IWL_DEBUG_INFO(priv, "Error sending msg : %d\n",
-                                      status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                break;
 
        case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
                status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT);
                if (status)
-                       IWL_DEBUG_INFO(priv,
-                               "Error loading init ucode: %d\n", status);
+                       IWL_ERR(priv, "Error loading init ucode: %d\n", status);
                break;
 
        case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
@@ -477,13 +498,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
        case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
                status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR);
                if (status) {
-                       IWL_DEBUG_INFO(priv,
+                       IWL_ERR(priv,
                                "Error loading runtime ucode: %d\n", status);
                        break;
                }
                status = iwl_alive_start(priv);
                if (status)
-                       IWL_DEBUG_INFO(priv,
+                       IWL_ERR(priv,
                                "Error starting the device: %d\n", status);
                break;
 
@@ -492,13 +513,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                iwl_trans_stop_device(trans);
                status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN);
                if (status) {
-                       IWL_DEBUG_INFO(priv,
+                       IWL_ERR(priv,
                                "Error loading WOWLAN ucode: %d\n", status);
                        break;
                }
                status = iwl_alive_start(priv);
                if (status)
-                       IWL_DEBUG_INFO(priv,
+                       IWL_ERR(priv,
                                "Error starting the device: %d\n", status);
                break;
 
@@ -507,8 +528,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                        skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
                                cfg(priv)->base_params->eeprom_size + 20);
                        if (!skb) {
-                               IWL_DEBUG_INFO(priv,
-                                      "Error allocating memory\n");
+                               IWL_ERR(priv, "Memory allocation fail\n");
                                return -ENOMEM;
                        }
                        NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
@@ -518,35 +538,34 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                                priv->shrd->eeprom);
                        status = cfg80211_testmode_reply(skb);
                        if (status < 0)
-                               IWL_DEBUG_INFO(priv,
-                                              "Error sending msg : %d\n",
-                                              status);
+                               IWL_ERR(priv, "Error sending msg : %d\n",
+                                       status);
                } else
                        return -EFAULT;
                break;
 
        case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
                if (!tb[IWL_TM_ATTR_FIXRATE]) {
-                       IWL_DEBUG_INFO(priv,
-                                      "Error finding fixrate setting\n");
+                       IWL_ERR(priv, "Missing fixrate setting\n");
                        return -ENOMSG;
                }
                priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
                break;
 
        case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
-               IWL_INFO(priv, "uCode version raw: 0x%x\n", priv->ucode_ver);
+               IWL_INFO(priv, "uCode version raw: 0x%x\n",
+                        nic(priv)->fw.ucode_ver);
 
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
-               NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, priv->ucode_ver);
+               NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION,
+                           nic(priv)->fw.ucode_ver);
                status = cfg80211_testmode_reply(skb);
                if (status < 0)
-                       IWL_DEBUG_INFO(priv,
-                                       "Error sending msg : %d\n", status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                break;
 
        case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
@@ -555,40 +574,39 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
                NLA_PUT_U32(skb, IWL_TM_ATTR_DEVICE_ID, devid);
                status = cfg80211_testmode_reply(skb);
                if (status < 0)
-                       IWL_DEBUG_INFO(priv,
-                                       "Error sending msg : %d\n", status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                break;
 
        case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
                switch (priv->shrd->ucode_type) {
                case IWL_UCODE_REGULAR:
-                       inst_size = trans(priv)->ucode_rt.code.len;
-                       data_size = trans(priv)->ucode_rt.data.len;
+                       inst_size = nic(priv)->fw.ucode_rt.code.len;
+                       data_size = nic(priv)->fw.ucode_rt.data.len;
                        break;
                case IWL_UCODE_INIT:
-                       inst_size = trans(priv)->ucode_init.code.len;
-                       data_size = trans(priv)->ucode_init.data.len;
+                       inst_size = nic(priv)->fw.ucode_init.code.len;
+                       data_size = nic(priv)->fw.ucode_init.data.len;
                        break;
                case IWL_UCODE_WOWLAN:
-                       inst_size = trans(priv)->ucode_wowlan.code.len;
-                       data_size = trans(priv)->ucode_wowlan.data.len;
+                       inst_size = nic(priv)->fw.ucode_wowlan.code.len;
+                       data_size = nic(priv)->fw.ucode_wowlan.data.len;
                        break;
                case IWL_UCODE_NONE:
-                       IWL_DEBUG_INFO(priv, "The uCode has not been loaded\n");
+                       IWL_ERR(priv, "No uCode has not been loaded\n");
                        break;
                default:
-                       IWL_DEBUG_INFO(priv, "Unsupported uCode type\n");
+                       IWL_ERR(priv, "Unsupported uCode type\n");
                        break;
                }
                NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type);
@@ -596,12 +614,11 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size);
                status = cfg80211_testmode_reply(skb);
                if (status < 0)
-                       IWL_DEBUG_INFO(priv,
-                                       "Error sending msg : %d\n", status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                break;
 
        default:
-               IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
+               IWL_ERR(priv, "Unknown testmode driver command ID\n");
                return -ENOSYS;
        }
        return status;
@@ -664,8 +681,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
                        sizeof(priv->testmode_trace.dma_addr) + 20);
                if (!skb) {
-                       IWL_DEBUG_INFO(priv,
-                               "Error allocating memory\n");
+                       IWL_ERR(priv, "Memory allocation fail\n");
                        iwl_trace_cleanup(priv);
                        return -ENOMEM;
                }
@@ -674,9 +690,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
                        (u64 *)&priv->testmode_trace.dma_addr);
                status = cfg80211_testmode_reply(skb);
                if (status < 0) {
-                       IWL_DEBUG_INFO(priv,
-                                      "Error sending msg : %d\n",
-                                      status);
+                       IWL_ERR(priv, "Error sending msg : %d\n", status);
                }
                priv->testmode_trace.num_chunks =
                        DIV_ROUND_UP(priv->testmode_trace.buff_size,
@@ -687,7 +701,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
                iwl_trace_cleanup(priv);
                break;
        default:
-               IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n");
+               IWL_ERR(priv, "Unknown testmode mem command ID\n");
                return -ENOSYS;
        }
        return status;
@@ -752,7 +766,7 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
        u8 owner;
 
        if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
-               IWL_DEBUG_INFO(priv, "Error finding ucode owner\n");
+               IWL_ERR(priv, "Missing ucode owner\n");
                return -ENOMSG;
        }
 
@@ -760,12 +774,89 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
        if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM))
                priv->shrd->ucode_owner = owner;
        else {
-               IWL_DEBUG_INFO(priv, "Invalid owner\n");
+               IWL_ERR(priv, "Invalid owner\n");
                return -EINVAL;
        }
        return 0;
 }
 
+static int iwl_testmode_indirect_read(struct iwl_priv *priv, u32 addr, u32 size)
+{
+       struct iwl_trans *trans = trans(priv);
+       unsigned long flags;
+       int i;
+
+       if (size & 0x3)
+               return -EINVAL;
+       priv->testmode_mem.buff_size = size;
+       priv->testmode_mem.buff_addr =
+               kmalloc(priv->testmode_mem.buff_size, GFP_KERNEL);
+       if (priv->testmode_mem.buff_addr == NULL)
+               return -ENOMEM;
+
+       /* Hard-coded periphery absolute address */
+       if (IWL_TM_ABS_PRPH_START <= addr &&
+               addr < IWL_TM_ABS_PRPH_START + PRPH_END) {
+                       spin_lock_irqsave(&trans->reg_lock, flags);
+                       iwl_grab_nic_access(trans);
+                       iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
+                               addr | (3 << 24));
+                       for (i = 0; i < size; i += 4)
+                               *(u32 *)(priv->testmode_mem.buff_addr + i) =
+                                       iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
+                       iwl_release_nic_access(trans);
+                       spin_unlock_irqrestore(&trans->reg_lock, flags);
+       } else { /* target memory (SRAM) */
+               _iwl_read_targ_mem_words(trans, addr,
+                       priv->testmode_mem.buff_addr,
+                       priv->testmode_mem.buff_size / 4);
+       }
+
+       priv->testmode_mem.num_chunks =
+               DIV_ROUND_UP(priv->testmode_mem.buff_size, DUMP_CHUNK_SIZE);
+       priv->testmode_mem.read_in_progress = true;
+       return 0;
+
+}
+
+static int iwl_testmode_indirect_write(struct iwl_priv *priv, u32 addr,
+       u32 size, unsigned char *buf)
+{
+       struct iwl_trans *trans = trans(priv);
+       u32 val, i;
+       unsigned long flags;
+
+       if (IWL_TM_ABS_PRPH_START <= addr &&
+               addr < IWL_TM_ABS_PRPH_START + PRPH_END) {
+                       /* Periphery writes can be 1-3 bytes long, or DWORDs */
+                       if (size < 4) {
+                               memcpy(&val, buf, size);
+                               spin_lock_irqsave(&trans->reg_lock, flags);
+                               iwl_grab_nic_access(trans);
+                               iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
+                                           (addr & 0x0000FFFF) |
+                                           ((size - 1) << 24));
+                               iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
+                               iwl_release_nic_access(trans);
+                               /* needed after consecutive writes w/o read */
+                               mmiowb();
+                               spin_unlock_irqrestore(&trans->reg_lock, flags);
+                       } else {
+                               if (size % 4)
+                                       return -EINVAL;
+                               for (i = 0; i < size; i += 4)
+                                       iwl_write_prph(trans, addr+i,
+                                               *(u32 *)(buf+i));
+                       }
+       } else if (iwlagn_hw_valid_rtc_data_addr(addr) ||
+               (IWLAGN_RTC_INST_LOWER_BOUND <= addr &&
+               addr < IWLAGN_RTC_INST_UPPER_BOUND)) {
+                       _iwl_write_targ_mem_words(trans, addr, buf, size/4);
+       } else
+               return -EINVAL;
+       return 0;
+}
+
 /*
  * This function handles the user application commands for SRAM data dump
  *
@@ -782,82 +873,60 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
  * @hw: ieee80211_hw object that represents the device
  * @tb: gnl message fields from the user space
  */
-static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
+static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw,
+       struct nlattr **tb)
 {
        struct iwl_priv *priv = hw->priv;
-       u32 ofs, size, maxsize;
+       u32 addr, size, cmd;
+       unsigned char *buf;
 
-       if (priv->testmode_sram.sram_readed)
+       /* Both read and write should be blocked, for atomicity */
+       if (priv->testmode_mem.read_in_progress)
                return -EBUSY;
 
-       if (!tb[IWL_TM_ATTR_SRAM_ADDR]) {
-               IWL_DEBUG_INFO(priv, "Error finding SRAM offset address\n");
+       cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
+       if (!tb[IWL_TM_ATTR_MEM_ADDR]) {
+               IWL_ERR(priv, "Error finding memory offset address\n");
                return -ENOMSG;
        }
-       ofs = nla_get_u32(tb[IWL_TM_ATTR_SRAM_ADDR]);
-       if (!tb[IWL_TM_ATTR_SRAM_SIZE]) {
-               IWL_DEBUG_INFO(priv, "Error finding size for SRAM reading\n");
+       addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]);
+       if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) {
+               IWL_ERR(priv, "Error finding size for memory reading\n");
                return -ENOMSG;
        }
-       size = nla_get_u32(tb[IWL_TM_ATTR_SRAM_SIZE]);
-       switch (priv->shrd->ucode_type) {
-       case IWL_UCODE_REGULAR:
-               maxsize = trans(priv)->ucode_rt.data.len;
-               break;
-       case IWL_UCODE_INIT:
-               maxsize = trans(priv)->ucode_init.data.len;
-               break;
-       case IWL_UCODE_WOWLAN:
-               maxsize = trans(priv)->ucode_wowlan.data.len;
-               break;
-       case IWL_UCODE_NONE:
-               IWL_ERR(priv, "Error, uCode does not been loaded\n");
-               return -ENOSYS;
-       default:
-               IWL_ERR(priv, "Error, unsupported uCode type\n");
-               return -ENOSYS;
-       }
-       if ((ofs + size) > (maxsize + SRAM_DATA_SEG_OFFSET)) {
-               IWL_ERR(priv, "Invalid offset/size: out of range\n");
-               return -EINVAL;
-       }
-       priv->testmode_sram.buff_size = (size / 4) * 4;
-       priv->testmode_sram.buff_addr =
-               kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL);
-       if (priv->testmode_sram.buff_addr == NULL) {
-               IWL_ERR(priv, "Error allocating memory\n");
-               return -ENOMEM;
+       size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]);
+
+       if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ)
+               return iwl_testmode_indirect_read(priv, addr,  size);
+       else {
+               if (!tb[IWL_TM_ATTR_BUFFER_DUMP])
+                       return -EINVAL;
+               buf = (unsigned char *) nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]);
+               return iwl_testmode_indirect_write(priv, addr, size, buf);
        }
-       _iwl_read_targ_mem_words(trans(priv), ofs,
-                                       priv->testmode_sram.buff_addr,
-                                       priv->testmode_sram.buff_size / 4);
-       priv->testmode_sram.num_chunks =
-               DIV_ROUND_UP(priv->testmode_sram.buff_size, DUMP_CHUNK_SIZE);
-       priv->testmode_sram.sram_readed = true;
-       return 0;
 }
 
-static int iwl_testmode_sram_dump(struct ieee80211_hw *hw, struct nlattr **tb,
+static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb,
                                   struct sk_buff *skb,
                                   struct netlink_callback *cb)
 {
        struct iwl_priv *priv = hw->priv;
        int idx, length;
 
-       if (priv->testmode_sram.sram_readed) {
+       if (priv->testmode_mem.read_in_progress) {
                idx = cb->args[4];
-               if (idx >= priv->testmode_sram.num_chunks) {
-                       iwl_sram_cleanup(priv);
+               if (idx >= priv->testmode_mem.num_chunks) {
+                       iwl_mem_cleanup(priv);
                        return -ENOENT;
                }
                length = DUMP_CHUNK_SIZE;
-               if (((idx + 1) == priv->testmode_sram.num_chunks) &&
-                   (priv->testmode_sram.buff_size % DUMP_CHUNK_SIZE))
-                       length = priv->testmode_sram.buff_size %
+               if (((idx + 1) == priv->testmode_mem.num_chunks) &&
+                   (priv->testmode_mem.buff_size % DUMP_CHUNK_SIZE))
+                       length = priv->testmode_mem.buff_size %
                                DUMP_CHUNK_SIZE;
 
-               NLA_PUT(skb, IWL_TM_ATTR_SRAM_DUMP, length,
-                       priv->testmode_sram.buff_addr +
+               NLA_PUT(skb, IWL_TM_ATTR_BUFFER_DUMP, length,
+                       priv->testmode_mem.buff_addr +
                        (DUMP_CHUNK_SIZE * idx));
                idx++;
                cb->args[4] = idx;
@@ -898,14 +967,13 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
        result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
                        iwl_testmode_gnl_msg_policy);
        if (result != 0) {
-               IWL_DEBUG_INFO(priv,
-                              "Error parsing the gnl message : %d\n", result);
+               IWL_ERR(priv, "Error parsing the gnl message : %d\n", result);
                return result;
        }
 
        /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
        if (!tb[IWL_TM_ATTR_COMMAND]) {
-               IWL_DEBUG_INFO(priv, "Error finding testmode command type\n");
+               IWL_ERR(priv, "Missing testmode command type\n");
                return -ENOMSG;
        }
        /* in case multiple accesses to the device happens */
@@ -919,8 +987,6 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
-       case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
-       case IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
                IWL_DEBUG_INFO(priv, "testmode cmd to register\n");
                result = iwl_testmode_reg(hw, tb);
                break;
@@ -950,13 +1016,15 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
                result = iwl_testmode_ownership(hw, tb);
                break;
 
-       case IWL_TM_CMD_APP2DEV_READ_SRAM:
-               IWL_DEBUG_INFO(priv, "testmode sram read cmd to driver\n");
-               result = iwl_testmode_sram(hw, tb);
+       case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
+       case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
+               IWL_DEBUG_INFO(priv, "testmode indirect memory cmd "
+                       "to driver\n");
+               result = iwl_testmode_indirect_mem(hw, tb);
                break;
 
        default:
-               IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
+               IWL_ERR(priv, "Unknown testmode command\n");
                result = -ENOSYS;
                break;
        }
@@ -981,15 +1049,14 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
                result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
                                iwl_testmode_gnl_msg_policy);
                if (result) {
-                       IWL_DEBUG_INFO(priv,
-                              "Error parsing the gnl message : %d\n", result);
+                       IWL_ERR(priv,
+                               "Error parsing the gnl message : %d\n", result);
                        return result;
                }
 
                /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
                if (!tb[IWL_TM_ATTR_COMMAND]) {
-                       IWL_DEBUG_INFO(priv,
-                               "Error finding testmode command type\n");
+                       IWL_ERR(priv, "Missing testmode command type\n");
                        return -ENOMSG;
                }
                cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
@@ -1003,9 +1070,9 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
                IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n");
                result = iwl_testmode_trace_dump(hw, tb, skb, cb);
                break;
-       case IWL_TM_CMD_APP2DEV_DUMP_SRAM:
+       case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
                IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n");
-               result = iwl_testmode_sram_dump(hw, tb, skb, cb);
+               result = iwl_testmode_buffer_dump(hw, tb, skb, cb);
                break;
        default:
                result = -EINVAL;
index f97d06169b4596d190e8578cc3f4497e5becde11..69b2e80f4071b871469ca5b36c37f93a5a21408c 100644 (file)
@@ -99,7 +99,7 @@
  *     to user application
  * @IWL_TM_CMD_DEV2APP_UCODE_RX_PKT:
  *     commands from kernel space to multicast the spontaneous messages
- *     to user application
+ *     to user application, or reply of host commands
  * @IWL_TM_CMD_DEV2APP_EEPROM_RSP:
  *     commands from kernel space to carry the eeprom response
  *     to user application
  *     if application has the ownership, the only host command from
  *     testmode will deliver to uCode. Default owner is driver
  *
- * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
- * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
- *     commands from user application to indirectly access peripheral register
- *
- * @IWL_TM_CMD_APP2DEV_READ_SRAM:
- * @IWL_TM_CMD_APP2DEV_DUMP_SRAM:
- *     commands from user application to read data in sram
- *
  * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image
  * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version
  * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device
  * @IWL_TM_CMD_APP2DEV_GET_FW_INFO:
  *     retrieve information of existing loaded uCode image
  *
+ * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
+ * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
+ * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
+ *     Commands to read/write data from periphery or SRAM memory ranges.
+ *     Fore reading, a READ command is sent from the userspace and the data
+ *     is returned when the user calls a DUMP command.
+ *     For writing, only a WRITE command is used.
  */
 enum iwl_tm_cmd_t {
        IWL_TM_CMD_APP2DEV_UCODE                = 1,
@@ -142,15 +141,18 @@ enum iwl_tm_cmd_t {
        IWL_TM_CMD_DEV2APP_UCODE_RX_PKT         = 15,
        IWL_TM_CMD_DEV2APP_EEPROM_RSP           = 16,
        IWL_TM_CMD_APP2DEV_OWNERSHIP            = 17,
-       IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32  = 18,
-       IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32 = 19,
-       IWL_TM_CMD_APP2DEV_READ_SRAM            = 20,
-       IWL_TM_CMD_APP2DEV_DUMP_SRAM            = 21,
+       RESERVED_18                             = 18,
+       RESERVED_19                             = 19,
+       RESERVED_20                             = 20,
+       RESERVED_21                             = 21,
        IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW       = 22,
        IWL_TM_CMD_APP2DEV_GET_FW_VERSION       = 23,
        IWL_TM_CMD_APP2DEV_GET_DEVICE_ID        = 24,
        IWL_TM_CMD_APP2DEV_GET_FW_INFO          = 25,
-       IWL_TM_CMD_MAX                          = 26,
+       IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26,
+       IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27,
+       IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28,
+       IWL_TM_CMD_MAX                          = 29,
 };
 
 /*
@@ -171,8 +173,6 @@ enum iwl_tm_cmd_t {
  *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
  *     The mandatory fields are :
  *     IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
- *     IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands;
- *     The optional fields are:
  *     IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
  *     to the ucode
  *
@@ -221,16 +221,19 @@ enum iwl_tm_cmd_t {
  *     The mandatory fields are:
  *     IWL_TM_ATTR_UCODE_OWNER for the new owner
  *
- * @IWL_TM_ATTR_SRAM_ADDR:
- * @IWL_TM_ATTR_SRAM_SIZE:
- *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_READ_SRAM,
+ * @IWL_TM_ATTR_MEM_ADDR:
+ * @IWL_TM_ATTR_BUFFER_SIZE:
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ
+ *     or IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE.
  *     The mandatory fields are:
- *     IWL_TM_ATTR_SRAM_ADDR for the address in sram
- *     IWL_TM_ATTR_SRAM_SIZE for the buffer size of data reading
+ *     IWL_TM_ATTR_MEM_ADDR for the address in SRAM/periphery to read/write
+ *     IWL_TM_ATTR_BUFFER_SIZE for the buffer size of data to read/write.
  *
- * @IWL_TM_ATTR_SRAM_DUMP:
- *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_DUMP_SRAM,
- *     IWL_TM_ATTR_SRAM_DUMP for the data in sram
+ * @IWL_TM_ATTR_BUFFER_DUMP:
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP,
+ *     IWL_TM_ATTR_BUFFER_DUMP is used for the data that was read.
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE,
+ *     this attribute contains the data to write.
  *
  * @IWL_TM_ATTR_FW_VERSION:
  *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_VERSION,
@@ -249,6 +252,10 @@ enum iwl_tm_cmd_t {
  *     IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section
  *     IWL_TM_ATTR_FW_DATA_SIZE for the size of data section
  *
+ * @IWL_TM_ATTR_UCODE_CMD_SKB:
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag
+ *     indicates that the user wants to receive the response of the command
+ *     in a reply SKB. If it's not present, the response is not returned.
  */
 enum iwl_tm_attr_t {
        IWL_TM_ATTR_NOT_APPLICABLE              = 0,
@@ -266,15 +273,16 @@ enum iwl_tm_attr_t {
        IWL_TM_ATTR_TRACE_DUMP                  = 12,
        IWL_TM_ATTR_FIXRATE                     = 13,
        IWL_TM_ATTR_UCODE_OWNER                 = 14,
-       IWL_TM_ATTR_SRAM_ADDR                   = 15,
-       IWL_TM_ATTR_SRAM_SIZE                   = 16,
-       IWL_TM_ATTR_SRAM_DUMP                   = 17,
+       IWL_TM_ATTR_MEM_ADDR                    = 15,
+       IWL_TM_ATTR_BUFFER_SIZE                 = 16,
+       IWL_TM_ATTR_BUFFER_DUMP                 = 17,
        IWL_TM_ATTR_FW_VERSION                  = 18,
        IWL_TM_ATTR_DEVICE_ID                   = 19,
        IWL_TM_ATTR_FW_TYPE                     = 20,
        IWL_TM_ATTR_FW_INST_SIZE                = 21,
        IWL_TM_ATTR_FW_DATA_SIZE                = 22,
-       IWL_TM_ATTR_MAX                         = 23,
+       IWL_TM_ATTR_UCODE_CMD_SKB               = 23,
+       IWL_TM_ATTR_MAX                         = 24,
 };
 
 /* uCode trace buffer */
index 561865f29d56a370156c94e09b8de4908229a5b3..8c30fea8c2b3e6fec241195b000172062c836543 100644 (file)
@@ -230,6 +230,7 @@ struct iwl_trans_pcie {
        struct tasklet_struct irq_tasklet;
        struct isr_statistics isr_stats;
 
+       spinlock_t irq_lock;
        u32 inta_mask;
        u32 scd_base_addr;
        struct iwl_dma_ptr scd_bc_tbls;
index 3826852ec5f07e0f2d10712aa556bb806c6fe63a..6715d04b72f4409d5927bcfcf0fb104bb7476b45 100644 (file)
@@ -34,6 +34,7 @@
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-trans-pcie-int.h"
+#include "iwl-wifi.h"
 
 #ifdef CONFIG_IWLWIFI_IDI
 #include "iwl-amfh.h"
@@ -227,7 +228,7 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
        /* If the pre-allocated buffer pool is dropping low, schedule to
         * refill it */
        if (rxq->free_count <= RX_LOW_WATERMARK)
-               queue_work(trans->shrd->workqueue, &trans_pcie->rx_replenish);
+               schedule_work(&trans_pcie->rx_replenish);
 
 
        /* If we've added more space for the firmware to place data, tell it.
@@ -331,13 +332,14 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
 
 void iwlagn_rx_replenish(struct iwl_trans *trans)
 {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        unsigned long flags;
 
        iwlagn_rx_allocate(trans, GFP_KERNEL);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwlagn_rx_queue_restock(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 static void iwlagn_rx_replenish_now(struct iwl_trans *trans)
@@ -351,14 +353,8 @@ void iwl_bg_rx_replenish(struct work_struct *data)
 {
        struct iwl_trans_pcie *trans_pcie =
            container_of(data, struct iwl_trans_pcie, rx_replenish);
-       struct iwl_trans *trans = trans_pcie->trans;
-
-       if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
-               return;
 
-       mutex_lock(&trans->shrd->mutex);
-       iwlagn_rx_replenish(trans);
-       mutex_unlock(&trans->shrd->mutex);
+       iwlagn_rx_replenish(trans_pcie->trans);
 }
 
 /**
@@ -594,17 +590,17 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
 {
        u32 base;
        struct iwl_error_event_table table;
-       struct iwl_priv *priv = priv(trans);
+       struct iwl_nic *nic = nic(trans);
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
        base = trans->shrd->device_pointers.error_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
                if (!base)
-                       base = priv->init_errlog_ptr;
+                       base = nic->init_errlog_ptr;
        } else {
                if (!base)
-                       base = priv->inst_errlog_ptr;
+                       base = nic->inst_errlog_ptr;
        }
 
        if (!iwlagn_hw_valid_rtc_data_addr(base)) {
@@ -616,7 +612,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
                return;
        }
 
-       iwl_read_targ_mem_words(trans(priv), base, &table, sizeof(table));
+       iwl_read_targ_mem_words(trans, base, &table, sizeof(table));
 
        if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
                IWL_ERR(trans, "Start IWL Error Log Dump:\n");
@@ -626,7 +622,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
 
        trans_pcie->isr_stats.err_code = table.error_id;
 
-       trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low,
+       trace_iwlwifi_dev_ucode_error(priv(nic), table.error_id, table.tsf_low,
                                      table.data1, table.data2, table.line,
                                      table.blink1, table.blink2, table.ilink1,
                                      table.ilink2, table.bcon_time, table.gp1,
@@ -723,7 +719,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
        u32 ptr;        /* SRAM byte address of log data */
        u32 ev, time, data; /* event log data */
        unsigned long reg_flags;
-       struct iwl_priv *priv = priv(trans);
+       struct iwl_nic *nic = nic(trans);
 
        if (num_events == 0)
                return pos;
@@ -731,10 +727,10 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
        base = trans->shrd->device_pointers.log_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
                if (!base)
-                       base = priv->init_evtlog_ptr;
+                       base = nic->init_evtlog_ptr;
        } else {
                if (!base)
-                       base = priv->inst_evtlog_ptr;
+                       base = nic->inst_evtlog_ptr;
        }
 
        if (mode == 0)
@@ -764,7 +760,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
                                                "EVT_LOG:0x%08x:%04u\n",
                                                time, ev);
                        } else {
-                               trace_iwlwifi_dev_ucode_event(priv, 0,
+                               trace_iwlwifi_dev_ucode_event(priv(trans), 0,
                                        time, ev);
                                IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n",
                                        time, ev);
@@ -778,7 +774,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
                        } else {
                                IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n",
                                        time, data, ev);
-                               trace_iwlwifi_dev_ucode_event(priv, time,
+                               trace_iwlwifi_dev_ucode_event(priv(trans), time,
                                        data, ev);
                        }
                }
@@ -840,17 +836,17 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
        u32 logsize;
        int pos = 0;
        size_t bufsz = 0;
-       struct iwl_priv *priv = priv(trans);
+       struct iwl_nic *nic = nic(trans);
 
        base = trans->shrd->device_pointers.log_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
-               logsize = priv->init_evtlog_size;
+               logsize = nic->init_evtlog_size;
                if (!base)
-                       base = priv->init_evtlog_ptr;
+                       base = nic->init_evtlog_ptr;
        } else {
-               logsize = priv->inst_evtlog_size;
+               logsize = nic->inst_evtlog_size;
                if (!base)
-                       base = priv->inst_evtlog_ptr;
+                       base = nic->inst_evtlog_ptr;
        }
 
        if (!iwlagn_hw_valid_rtc_data_addr(base)) {
@@ -949,7 +945,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
 
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Ack/clear/reset pending uCode interrupts.
         * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
@@ -979,7 +975,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        /* saved interrupt in inta variable now we can reset trans_pcie->inta */
        trans_pcie->inta = 0;
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* Now service all interrupt bits discovered above. */
        if (inta & CSR_INT_BIT_HW_ERR) {
@@ -1232,7 +1228,7 @@ void iwl_reset_ict(struct iwl_trans *trans)
        if (!trans_pcie->ict_tbl)
                return;
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_disable_interrupts(trans);
 
        memset(trans_pcie->ict_tbl, 0, ICT_SIZE);
@@ -1249,7 +1245,7 @@ void iwl_reset_ict(struct iwl_trans *trans)
        trans_pcie->ict_index = 0;
        iwl_write32(trans, CSR_INT, trans_pcie->inta_mask);
        iwl_enable_interrupts(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 /* Device is going down disable ict interrupt usage */
@@ -1260,9 +1256,9 @@ void iwl_disable_ict(struct iwl_trans *trans)
 
        unsigned long flags;
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        trans_pcie->use_ict = false;
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 static irqreturn_t iwl_isr(int irq, void *data)
@@ -1281,7 +1277,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
 
        trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Disable (but don't clear!) interrupts here to avoid
         *    back-to-back ISRs and sporadic interrupts from our NIC.
@@ -1325,7 +1321,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
                iwl_enable_interrupts(trans);
 
  unplugged:
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_HANDLED;
 
  none:
@@ -1335,7 +1331,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
                !trans_pcie->inta)
                iwl_enable_interrupts(trans);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_NONE;
 }
 
@@ -1369,7 +1365,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
 
        trace_iwlwifi_dev_irq(priv(trans));
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Disable (but don't clear!) interrupts here to avoid
         * back-to-back ISRs and sporadic interrupts from our NIC.
@@ -1440,7 +1436,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
                iwl_enable_interrupts(trans);
        }
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_HANDLED;
 
  none:
@@ -1451,6 +1447,6 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
            !trans_pcie->inta)
                iwl_enable_interrupts(trans);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_NONE;
 }
index 08e0a7da48a93466481bfd314b98adfcc810dded..a3cebd76dc0cd6bd41db5ab4deb7d981a39d8a3b 100644 (file)
@@ -492,7 +492,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
 
        ra_tid = BUILD_RAxTID(sta_id, tid);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Stop this Tx queue before configuring it */
        iwlagn_tx_queue_stop_scheduler(trans, txq_id);
@@ -532,7 +532,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
        trans_pcie->txq[txq_id].sta_id = sta_id;
        trans_pcie->txq[txq_id].tid = tid;
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 /*
index f5cb5d3cd92641826cb12c33248184e56c8c1b16..176063c4f78165b40c098adb0ca86cf9d78de888 100644 (file)
@@ -219,10 +219,10 @@ static int iwl_rx_init(struct iwl_trans *trans)
 
        iwl_trans_rx_hw_init(trans, rxq);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        rxq->need_update = 1;
        iwl_rx_queue_update_write_ptr(trans, rxq);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        return 0;
 }
@@ -585,7 +585,7 @@ static int iwl_tx_init(struct iwl_trans *trans)
                alloc = true;
        }
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Turn off all Tx DMA fifos */
        iwl_write_prph(trans, SCD_TXFACT, 0);
@@ -594,7 +594,7 @@ static int iwl_tx_init(struct iwl_trans *trans)
        iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
                           trans_pcie->kw.dma >> 4);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* Alloc and init all Tx queues, including the command queue (#4/#9) */
        for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) {
@@ -803,17 +803,18 @@ static void iwl_apm_stop(struct iwl_trans *trans)
 
 static int iwl_nic_init(struct iwl_trans *trans)
 {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        unsigned long flags;
 
        /* nic_init */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_apm_init(trans);
 
        /* Set interrupt coalescing calibration timer to default (512 usecs) */
        iwl_write8(trans, CSR_INT_COALESCING,
                IWL_HOST_INT_CALIB_TIMEOUT_DEF);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        iwl_set_pwr_vmain(trans);
 
@@ -1078,10 +1079,15 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
 
 /*
  * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
- * must be called under priv->shrd->lock and mac access
+ * must be called under the irq lock and with MAC access
  */
 static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
 {
+       struct iwl_trans_pcie __maybe_unused *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+
+       lockdep_assert_held(&trans_pcie->irq_lock);
+
        iwl_write_prph(trans, SCD_TXFACT, mask);
 }
 
@@ -1095,7 +1101,7 @@ static void iwl_tx_start(struct iwl_trans *trans)
        int i, chan;
        u32 reg_val;
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        trans_pcie->scd_base_addr =
                iwl_read_prph(trans, SCD_SRAM_BASE_ADDR);
@@ -1191,7 +1197,7 @@ static void iwl_tx_start(struct iwl_trans *trans)
                                              fifo, 0);
        }
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* Enable L1-Active */
        iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
@@ -1214,7 +1220,7 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
        /* Turn off all Tx DMA fifos */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        iwl_trans_txq_set_sched(trans, 0);
 
@@ -1230,7 +1236,7 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
                            iwl_read_direct32(trans,
                                              FH_TSSR_TX_STATUS_REG));
        }
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        if (!trans_pcie->txq) {
                IWL_WARN(trans, "Stopping tx queues that aren't allocated...");
@@ -1250,9 +1256,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
        /* tell the device to stop sending interrupts */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_disable_interrupts(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* device going down, Stop using ICT table */
        iwl_disable_ict(trans);
@@ -1285,14 +1291,16 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
        /* Upon stop, the APM issues an interrupt if HW RF kill is set.
         * Clean again the interrupt here
         */
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_disable_interrupts(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* wait to make sure we flush pending tasklet*/
        synchronize_irq(trans->irq);
        tasklet_kill(&trans_pcie->irq_tasklet);
 
+       cancel_work_sync(&trans_pcie->rx_replenish);
+
        /* stop and reset the on-board processor */
        iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 }
@@ -2259,6 +2267,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
        trans->shrd = shrd;
        trans_pcie->trans = trans;
        spin_lock_init(&trans->hcmd_lock);
+       spin_lock_init(&trans_pcie->irq_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 */
index ae68c51e532730a3eaa1472c5e5b1407eec25e3d..cc7a3cfb5f24386aa86ef53097e1364db4311d2b 100644 (file)
 
 #include "iwl-shared.h"
 #include "iwl-commands.h"
+#include "iwl-ucode.h"
+#include "iwl-debug.h"
 
- /*This file includes the declaration that are exported from the transport
- * layer */
+/**
+ * DOC: Transport layer - what is it ?
+ *
+ * The tranport layer is the layer that deals with the HW directly. It provides
+ * an abstraction of the underlying HW to the upper layer. The transport layer
+ * doesn't provide any policy, algorithm or anything of this kind, but only
+ * mechanisms to make the HW do something.It is not completely stateless but
+ * close to it.
+ * We will have an implementation for each different supported bus.
+ */
+
+/**
+ * DOC: Life cycle of the transport layer
+ *
+ * The transport layer has a very precise life cycle.
+ *
+ *     1) A helper function is called during the module initialization and
+ *        registers the bus driver's ops with the transport's alloc function.
+ *     2) Bus's probe calls to the transport layer's allocation functions.
+ *        Of course this function is bus specific.
+ *     3) This allocation functions will spawn the upper layer which will
+ *        register mac80211.
+ *
+ *     4) At some point (i.e. mac80211's start call), the op_mode will call
+ *        the following sequence:
+ *        start_hw
+ *        start_fw
+ *
+ *     5) Then when finished (or reset):
+ *        stop_fw (a.k.a. stop device for the moment)
+ *        stop_hw
+ *
+ *     6) Eventually, the free function will be called.
+ */
+
+/**
+ * DOC: API needed by the transport layer from the op_mode
+ *
+ * TODO
+ */
 
 struct iwl_priv;
 struct iwl_shared;
 
+/**
+ * DOC: Host command section
+ *
+ * A host command is a commaned issued by the upper layer to the fw. There are
+ * several versions of fw that have several APIs. The transport layer is
+ * completely agnostic to these differences.
+ * The transport does provide helper functionnality (i.e. SYNC / ASYNC mode),
+ */
 #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
 #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
 #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
 
-enum {
+/**
+ * enum CMD_MODE - how to send the host commands ?
+ *
+ * @CMD_SYNC: The caller will be stalled until the fw responds to the command
+ * @CMD_ASYNC: Return right away and don't want for the response
+ * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
+ *     response.
+ * @CMD_ON_DEMAND: This command is sent by the test mode pipe.
+ */
+enum CMD_MODE {
        CMD_SYNC = 0,
        CMD_ASYNC = BIT(0),
        CMD_WANT_SKB = BIT(1),
@@ -104,20 +161,29 @@ struct iwl_device_cmd {
 
 #define IWL_MAX_CMD_TFDS       2
 
+/**
+ * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command
+ *
+ * IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's
+ *     ring. The transport layer doesn't map the command's buffer to DMA, but
+ *     rather copies it to an previously allocated DMA buffer. This flag tells
+ *     the transport layer not to copy the command, but to map the existing
+ *     buffer. This can save memcpy and is worth with very big comamnds.
+ */
 enum iwl_hcmd_dataflag {
        IWL_HCMD_DFL_NOCOPY     = BIT(0),
 };
 
 /**
  * struct iwl_host_cmd - Host command to the uCode
+ *
  * @data: array of chunks that composes the data of the host command
  * @reply_page: pointer to the page that holds the response to the host command
  * @handler_status: return value of the handler of the command
  *     (put in setup_rx_handlers) - valid for SYNC mode only
- * @callback:
- * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC
+ * @flags: can be CMD_*
  * @len: array of the lenths of the chunks in data
- * @dataflags:
+ * @dataflags: IWL_HCMD_DFL_*
  * @id: id of the host command
  */
 struct iwl_host_cmd {
@@ -131,40 +197,45 @@ struct iwl_host_cmd {
        u8 id;
 };
 
-/* one for each uCode image (inst/data, boot/init/runtime) */
-struct fw_desc {
-       dma_addr_t p_addr;      /* hardware address */
-       void *v_addr;           /* software address */
-       u32 len;                /* size in bytes */
-};
-
-struct fw_img {
-       struct fw_desc code;    /* firmware code image */
-       struct fw_desc data;    /* firmware data image */
-};
-
 /**
  * struct iwl_trans_ops - transport specific operations
+ *
+ * All the handlers MUST be implemented
+ *
  * @start_hw: starts the HW- from that point on, the HW can send interrupts
+ *     May sleep
  * @stop_hw: stops the HW- from that point on, the HW will be in low power but
  *     will still issue interrupt if the HW RF kill is triggered.
+ *     May sleep
  * @start_fw: allocates and inits all the resources for the transport
- *     layer. Also kick a fw image. This handler may sleep.
+ *     layer. Also kick a fw image.
+ *     May sleep
  * @fw_alive: called when the fw sends alive notification
+ *     May sleep
  * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_*
  * @stop_device:stops the whole device (embedded CPU put to reset)
+ *     May sleep
  * @send_cmd:send a host command
+ *     May sleep only if CMD_SYNC is set
  * @tx: send an skb
+ *     Must be atomic
  * @reclaim: free packet until ssn. Returns a list of freed packets.
+ *     Must be atomic
  * @tx_agg_alloc: allocate resources for a TX BA session
+ *     May sleep
  * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is
- *                 ready and a successful ADDBA response has been received.
+ *     ready and a successful ADDBA response has been received.
+ *     May sleep
  * @tx_agg_disable: de-configure a Tx queue to send AMPDUs
+ *     May sleep
  * @free: release all the ressource for the transport layer itself such as
- *        irq, tasklet etc...
+ *     irq, tasklet etc... From this point on, the device may not issue
+ *     any interrupt (incl. RFKILL).
+ *     May sleep
  * @stop_queue: stop a specific queue
  * @check_stuck_queue: check if a specific queue is stuck
  * @wait_tx_queue_empty: wait until all tx queues are empty
+ *     May sleep
  * @dbgfs_register: add the dbgfs files under this directory. Files will be
  *     automatically deleted.
  * @suspend: stop the device unless WoWLAN is configured
@@ -226,8 +297,20 @@ struct iwl_calib_result {
        /* data follows */
 };
 
+/**
+ * enum iwl_trans_state - state of the transport layer
+ *
+ * @IWL_TRANS_NO_FW: no fw has sent an alive response
+ * @IWL_TRANS_FW_ALIVE: a fw has sent an alive response
+ */
+enum iwl_trans_state {
+       IWL_TRANS_NO_FW = 0,
+       IWL_TRANS_FW_ALIVE      = 1,
+};
+
 /**
  * struct iwl_trans - transport common data
+ *
  * @ops - pointer to iwl_trans_ops
  * @shrd - pointer to iwl_shared which holds shared data from the upper layer
  * @hcmd_lock: protects HCMD
@@ -235,12 +318,9 @@ struct iwl_calib_result {
  * @dev - pointer to struct device * that represents the device
  * @irq - the irq number for the device
  * @hw_id: a u32 with the ID of the device / subdevice.
 *    Set during transport alloaction.
*     Set during transport allocation.
  * @hw_id_str: a string with info about HW ID. Set during transport allocation.
  * @ucode_write_complete: indicates that the ucode has been copied.
- * @ucode_rt: run time ucode image
- * @ucode_init: init ucode image
- * @ucode_wowlan: wake on wireless ucode image (optional)
  * @nvm_device_type: indicates OTP or eeprom
  * @pm_support: set to true in start_hw if link pm is supported
  * @calib_results: list head for init calibration results
@@ -248,6 +328,7 @@ struct iwl_calib_result {
 struct iwl_trans {
        const struct iwl_trans_ops *ops;
        struct iwl_shared *shrd;
+       enum iwl_trans_state state;
        spinlock_t hcmd_lock;
        spinlock_t reg_lock;
 
@@ -257,16 +338,11 @@ struct iwl_trans {
        u32 hw_id;
        char hw_id_str[52];
 
-       u8 ucode_write_complete;        /* the image write is complete */
-       struct fw_img ucode_rt;
-       struct fw_img ucode_init;
-       struct fw_img ucode_wowlan;
+       u8 ucode_write_complete;
 
-       /* eeprom related variables */
        int    nvm_device_type;
        bool pm_support;
 
-       /* init calibration results */
        struct list_head calib_results;
 
        /* pointer to trans specific struct */
@@ -276,17 +352,27 @@ struct iwl_trans {
 
 static inline int iwl_trans_start_hw(struct iwl_trans *trans)
 {
+       might_sleep();
+
        return trans->ops->start_hw(trans);
 }
 
 static inline void iwl_trans_stop_hw(struct iwl_trans *trans)
 {
+       might_sleep();
+
        trans->ops->stop_hw(trans);
+
+       trans->state = IWL_TRANS_NO_FW;
 }
 
 static inline void iwl_trans_fw_alive(struct iwl_trans *trans)
 {
+       might_sleep();
+
        trans->ops->fw_alive(trans);
+
+       trans->state = IWL_TRANS_FW_ALIVE;
 }
 
 static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw)
@@ -298,13 +384,20 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw)
 
 static inline void iwl_trans_stop_device(struct iwl_trans *trans)
 {
+       might_sleep();
+
        trans->ops->stop_device(trans);
+
+       trans->state = IWL_TRANS_NO_FW;
 }
 
 static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans,
                                            enum iwl_rxon_context_id ctx,
                                            const char *msg)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        trans->ops->wake_any_queue(trans, ctx, msg);
 }
 
@@ -312,6 +405,9 @@ static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans,
 static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
                                struct iwl_host_cmd *cmd)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->send_cmd(trans, cmd);
 }
 
@@ -322,6 +418,9 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
                struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx,
                u8 sta_id, u8 tid)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->tx(trans, skb, dev_cmd, ctx, sta_id, tid);
 }
 
@@ -329,6 +428,9 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id,
                                 int tid, int txq_id, int ssn, u32 status,
                                 struct sk_buff_head *skbs)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn,
                                   status, skbs);
 }
@@ -336,12 +438,22 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id,
 static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans,
                                            int sta_id, int tid)
 {
+       might_sleep();
+
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->tx_agg_disable(trans, sta_id, tid);
 }
 
 static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans,
                                         int sta_id, int tid)
 {
+       might_sleep();
+
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->tx_agg_alloc(trans, sta_id, tid);
 }
 
@@ -351,6 +463,11 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans,
                                           int sta_id, int tid,
                                           int frame_limit, u16 ssn)
 {
+       might_sleep();
+
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn);
 }
 
@@ -362,16 +479,25 @@ static inline void iwl_trans_free(struct iwl_trans *trans)
 static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q,
                                        const char *msg)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        trans->ops->stop_queue(trans, q, msg);
 }
 
 static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->wait_tx_queue_empty(trans);
 }
 
 static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q)
 {
+       if (trans->state != IWL_TRANS_FW_ALIVE)
+               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+
        return trans->ops->check_stuck_queue(trans, q);
 }
 static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
@@ -410,8 +536,6 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs)
 /*****************************************************
 * Utils functions
 ******************************************************/
-void iwl_dealloc_ucode(struct iwl_trans *trans);
-
 int iwl_send_calib_results(struct iwl_trans *trans);
 int iwl_calib_set(struct iwl_trans *trans,
                  const struct iwl_calib_hdr *cmd, int len);
index 11b659ab261d5bbb4cecc4e9fe3bf9950cfe7d41..61c6c0568c1101d1e69dbfd6717cb80d090b0db9 100644 (file)
@@ -82,29 +82,29 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
  *
  ******************************************************************************/
 
-static void iwl_free_fw_desc(struct iwl_trans *trans, struct fw_desc *desc)
+static void iwl_free_fw_desc(struct iwl_nic *nic, struct fw_desc *desc)
 {
        if (desc->v_addr)
-               dma_free_coherent(trans->dev, desc->len,
+               dma_free_coherent(trans(nic)->dev, desc->len,
                                  desc->v_addr, desc->p_addr);
        desc->v_addr = NULL;
        desc->len = 0;
 }
 
-static void iwl_free_fw_img(struct iwl_trans *trans, struct fw_img *img)
+static void iwl_free_fw_img(struct iwl_nic *nic, struct fw_img *img)
 {
-       iwl_free_fw_desc(trans, &img->code);
-       iwl_free_fw_desc(trans, &img->data);
+       iwl_free_fw_desc(nic, &img->code);
+       iwl_free_fw_desc(nic, &img->data);
 }
 
-void iwl_dealloc_ucode(struct iwl_trans *trans)
+void iwl_dealloc_ucode(struct iwl_nic *nic)
 {
-       iwl_free_fw_img(trans, &trans->ucode_rt);
-       iwl_free_fw_img(trans, &trans->ucode_init);
-       iwl_free_fw_img(trans, &trans->ucode_wowlan);
+       iwl_free_fw_img(nic, &nic->fw.ucode_rt);
+       iwl_free_fw_img(nic, &nic->fw.ucode_init);
+       iwl_free_fw_img(nic, &nic->fw.ucode_wowlan);
 }
 
-static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc,
+static int iwl_alloc_fw_desc(struct iwl_nic *nic, struct fw_desc *desc,
                      const void *data, size_t len)
 {
        if (!len) {
@@ -112,7 +112,7 @@ static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc,
                return -EINVAL;
        }
 
-       desc->v_addr = dma_alloc_coherent(trans->dev, len,
+       desc->v_addr = dma_alloc_coherent(trans(nic)->dev, len,
                                          &desc->p_addr, GFP_KERNEL);
        if (!desc->v_addr)
                return -ENOMEM;
@@ -122,16 +122,16 @@ static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc,
        return 0;
 }
 
-static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans,
+static inline struct fw_img *iwl_get_ucode_image(struct iwl_nic *nic,
                                        enum iwl_ucode_type ucode_type)
 {
        switch (ucode_type) {
        case IWL_UCODE_INIT:
-               return &trans->ucode_init;
+               return &nic->fw.ucode_init;
        case IWL_UCODE_WOWLAN:
-               return &trans->ucode_wowlan;
+               return &nic->fw.ucode_wowlan;
        case IWL_UCODE_REGULAR:
-               return &trans->ucode_rt;
+               return &nic->fw.ucode_rt;
        case IWL_UCODE_NONE:
                break;
        }
@@ -397,15 +397,16 @@ static int iwl_alive_notify(struct iwl_trans *trans)
  *   using sample data 100 bytes apart.  If these sample points are good,
  *   it's a pretty good bet that everything between them is good, too.
  */
-static int iwl_verify_inst_sparse(struct iwl_trans *trans,
+static int iwl_verify_inst_sparse(struct iwl_nic *nic,
                                      struct fw_desc *fw_desc)
 {
+       struct iwl_trans *trans = trans(nic);
        __le32 *image = (__le32 *)fw_desc->v_addr;
        u32 len = fw_desc->len;
        u32 val;
        u32 i;
 
-       IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len);
+       IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len);
 
        for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
                /* read data comes through single port, auto-incr addr */
@@ -421,16 +422,17 @@ static int iwl_verify_inst_sparse(struct iwl_trans *trans,
        return 0;
 }
 
-static void iwl_print_mismatch_inst(struct iwl_trans *trans,
+static void iwl_print_mismatch_inst(struct iwl_nic *nic,
                                    struct fw_desc *fw_desc)
 {
+       struct iwl_trans *trans = trans(nic);
        __le32 *image = (__le32 *)fw_desc->v_addr;
        u32 len = fw_desc->len;
        u32 val;
        u32 offs;
        int errors = 0;
 
-       IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len);
+       IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len);
 
        iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR,
                           IWLAGN_RTC_INST_LOWER_BOUND);
@@ -441,7 +443,7 @@ static void iwl_print_mismatch_inst(struct iwl_trans *trans,
                /* read data comes through single port, auto-incr addr */
                val = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image)) {
-                       IWL_ERR(trans, "uCode INST section at "
+                       IWL_ERR(nic, "uCode INST section at "
                                "offset 0x%x, is 0x%x, s/b 0x%x\n",
                                offs, val, le32_to_cpu(*image));
                        errors++;
@@ -453,24 +455,24 @@ static void iwl_print_mismatch_inst(struct iwl_trans *trans,
  * iwl_verify_ucode - determine which instruction image is in SRAM,
  *    and verify its contents
  */
-static int iwl_verify_ucode(struct iwl_trans *trans,
+static int iwl_verify_ucode(struct iwl_nic *nic,
                            enum iwl_ucode_type ucode_type)
 {
-       struct fw_img *img = iwl_get_ucode_image(trans, ucode_type);
+       struct fw_img *img = iwl_get_ucode_image(nic, ucode_type);
 
        if (!img) {
-               IWL_ERR(trans, "Invalid ucode requested (%d)\n", ucode_type);
+               IWL_ERR(nic, "Invalid ucode requested (%d)\n", ucode_type);
                return -EINVAL;
        }
 
-       if (!iwl_verify_inst_sparse(trans, &img->code)) {
-               IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n");
+       if (!iwl_verify_inst_sparse(nic, &img->code)) {
+               IWL_DEBUG_FW(nic, "uCode is good in inst SRAM\n");
                return 0;
        }
 
-       IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
+       IWL_ERR(nic, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
 
-       iwl_print_mismatch_inst(trans, &img->code);
+       iwl_print_mismatch_inst(nic, &img->code);
        return -EIO;
 }
 
@@ -583,7 +585,7 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
 
        old_type = trans->shrd->ucode_type;
        trans->shrd->ucode_type = ucode_type;
-       fw = iwl_get_ucode_image(trans, ucode_type);
+       fw = iwl_get_ucode_image(nic(trans), ucode_type);
 
        if (!fw)
                return -EINVAL;
@@ -618,7 +620,7 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
         * skip it for WoWLAN.
         */
        if (ucode_type != IWL_UCODE_WOWLAN) {
-               ret = iwl_verify_ucode(trans, ucode_type);
+               ret = iwl_verify_ucode(nic(trans), ucode_type);
                if (ret) {
                        trans->shrd->ucode_type = old_type;
                        return ret;
@@ -647,7 +649,7 @@ int iwl_run_init_ucode(struct iwl_trans *trans)
        lockdep_assert_held(&trans->shrd->mutex);
 
        /* No init ucode required? Curious, but maybe ok */
-       if (!trans->ucode_init.code.len)
+       if (!nic(trans)->fw.ucode_init.code.len)
                return 0;
 
        if (trans->shrd->ucode_type != IWL_UCODE_NONE)
@@ -688,39 +690,40 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
 #define UCODE_EXPERIMENTAL_INDEX       100
 #define UCODE_EXPERIMENTAL_TAG         "exp"
 
-int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
+int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first)
 {
-       const char *name_pre = cfg(priv)->fw_name_pre;
+       struct iwl_cfg *cfg = cfg(nic);
+       const char *name_pre = cfg->fw_name_pre;
        char tag[8];
 
        if (first) {
 #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
-               priv->fw_index = UCODE_EXPERIMENTAL_INDEX;
+               nic->fw_index = UCODE_EXPERIMENTAL_INDEX;
                strcpy(tag, UCODE_EXPERIMENTAL_TAG);
-       } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) {
+       } else if (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) {
 #endif
-               priv->fw_index = cfg(priv)->ucode_api_max;
-               sprintf(tag, "%d", priv->fw_index);
+               nic->fw_index = cfg->ucode_api_max;
+               sprintf(tag, "%d", nic->fw_index);
        } else {
-               priv->fw_index--;
-               sprintf(tag, "%d", priv->fw_index);
+               nic->fw_index--;
+               sprintf(tag, "%d", nic->fw_index);
        }
 
-       if (priv->fw_index < cfg(priv)->ucode_api_min) {
-               IWL_ERR(priv, "no suitable firmware found!\n");
+       if (nic->fw_index < cfg->ucode_api_min) {
+               IWL_ERR(nic, "no suitable firmware found!\n");
                return -ENOENT;
        }
 
-       sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
+       sprintf(nic->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
 
-       IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n",
-                      (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+       IWL_DEBUG_INFO(nic, "attempting to load firmware %s'%s'\n",
+                      (nic->fw_index == UCODE_EXPERIMENTAL_INDEX)
                                ? "EXPERIMENTAL " : "",
-                      priv->firmware_name);
+                      nic->firmware_name);
 
-       return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
-                                      trans(priv)->dev,
-                                      GFP_KERNEL, priv, iwl_ucode_callback);
+       return request_firmware_nowait(THIS_MODULE, 1, nic->firmware_name,
+                                      trans(nic)->dev,
+                                      GFP_KERNEL, nic, iwl_ucode_callback);
 }
 
 struct iwlagn_firmware_pieces {
@@ -734,7 +737,7 @@ struct iwlagn_firmware_pieces {
        u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
 };
 
-static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
+static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic,
                                       const struct firmware *ucode_raw,
                                       struct iwlagn_firmware_pieces *pieces)
 {
@@ -742,14 +745,14 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
        u32 api_ver, hdr_size;
        const u8 *src;
 
-       priv->ucode_ver = le32_to_cpu(ucode->ver);
-       api_ver = IWL_UCODE_API(priv->ucode_ver);
+       nic->fw.ucode_ver = le32_to_cpu(ucode->ver);
+       api_ver = IWL_UCODE_API(nic->fw.ucode_ver);
 
        switch (api_ver) {
        default:
                hdr_size = 28;
                if (ucode_raw->size < hdr_size) {
-                       IWL_ERR(priv, "File size too small!\n");
+                       IWL_ERR(nic, "File size too small!\n");
                        return -EINVAL;
                }
                pieces->build = le32_to_cpu(ucode->u.v2.build);
@@ -764,7 +767,7 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
        case 2:
                hdr_size = 24;
                if (ucode_raw->size < hdr_size) {
-                       IWL_ERR(priv, "File size too small!\n");
+                       IWL_ERR(nic, "File size too small!\n");
                        return -EINVAL;
                }
                pieces->build = 0;
@@ -781,7 +784,7 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
                                pieces->data_size + pieces->init_size +
                                pieces->init_data_size) {
 
-               IWL_ERR(priv,
+               IWL_ERR(nic,
                        "uCode file size %d does not match expected size\n",
                        (int)ucode_raw->size);
                return -EINVAL;
@@ -799,10 +802,10 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
        return 0;
 }
 
-static int iwlagn_load_firmware(struct iwl_priv *priv,
+static int iwl_parse_tlv_firmware(struct iwl_nic *nic,
                                const struct firmware *ucode_raw,
                                struct iwlagn_firmware_pieces *pieces,
-                               struct iwlagn_ucode_capabilities *capa)
+                               struct iwl_ucode_capabilities *capa)
 {
        struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
        struct iwl_ucode_tlv *tlv;
@@ -816,12 +819,12 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
        const u8 *tlv_data;
 
        if (len < sizeof(*ucode)) {
-               IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
+               IWL_ERR(nic, "uCode has invalid length: %zd\n", len);
                return -EINVAL;
        }
 
        if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
-               IWL_ERR(priv, "invalid uCode magic: 0X%x\n",
+               IWL_ERR(nic, "invalid uCode magic: 0X%x\n",
                        le32_to_cpu(ucode->magic));
                return -EINVAL;
        }
@@ -839,11 +842,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
        while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
                wanted_alternative--;
        if (wanted_alternative && wanted_alternative != tmp)
-               IWL_WARN(priv,
+               IWL_WARN(nic,
                         "uCode alternative %d not available, choosing %d\n",
                         tmp, wanted_alternative);
 
-       priv->ucode_ver = le32_to_cpu(ucode->ver);
+       nic->fw.ucode_ver = le32_to_cpu(ucode->ver);
        pieces->build = le32_to_cpu(ucode->build);
        data = ucode->data;
 
@@ -861,7 +864,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
                tlv_data = tlv->data;
 
                if (len < tlv_len) {
-                       IWL_ERR(priv, "invalid TLV len: %zd/%u\n",
+                       IWL_ERR(nic, "invalid TLV len: %zd/%u\n",
                                len, tlv_len);
                        return -EINVAL;
                }
@@ -894,7 +897,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
                        pieces->init_data_size = tlv_len;
                        break;
                case IWL_UCODE_TLV_BOOT:
-                       IWL_ERR(priv, "Found unexpected BOOT ucode\n");
+                       IWL_ERR(nic, "Found unexpected BOOT ucode\n");
                        break;
                case IWL_UCODE_TLV_PROBE_MAX_LEN:
                        if (tlv_len != sizeof(u32))
@@ -962,7 +965,7 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
                case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
                        if (tlv_len)
                                goto invalid_tlv_len;
-                       priv->enhance_sensitivity_table = true;
+                       nic->fw.enhance_sensitivity_table = true;
                        break;
                case IWL_UCODE_TLV_WOWLAN_INST:
                        pieces->wowlan_inst = tlv_data;
@@ -979,22 +982,22 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
                                        le32_to_cpup((__le32 *)tlv_data);
                        break;
                default:
-                       IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type);
+                       IWL_DEBUG_INFO(nic, "unknown TLV: %d\n", tlv_type);
                        break;
                }
        }
 
        if (len) {
-               IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
-               iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
+               IWL_ERR(nic, "invalid TLV after parsing: %zd\n", len);
+               iwl_print_hex_dump(nic, IWL_DL_FW, (u8 *)data, len);
                return -EINVAL;
        }
 
        return 0;
 
  invalid_tlv_len:
-       IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
-       iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len);
+       IWL_ERR(nic, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
+       iwl_print_hex_dump(nic, IWL_DL_FW, tlv_data, tlv_len);
 
        return -EINVAL;
 }
@@ -1007,21 +1010,23 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
  */
 static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 {
-       struct iwl_priv *priv = context;
+       struct iwl_nic *nic = context;
+       struct iwl_cfg *cfg = cfg(nic);
+       struct iwl_fw *fw = &nic->fw;
+       struct iwl_priv *priv = priv(nic); /* temporary */
        struct iwl_ucode_header *ucode;
        int err;
        struct iwlagn_firmware_pieces pieces;
-       const unsigned int api_max = cfg(priv)->ucode_api_max;
-       unsigned int api_ok = cfg(priv)->ucode_api_ok;
-       const unsigned int api_min = cfg(priv)->ucode_api_min;
+       const unsigned int api_max = cfg->ucode_api_max;
+       unsigned int api_ok = cfg->ucode_api_ok;
+       const unsigned int api_min = cfg->ucode_api_min;
        u32 api_ver;
        char buildstr[25];
        u32 build;
-       struct iwlagn_ucode_capabilities ucode_capa = {
-               .max_probe_length = 200,
-               .standard_phy_calibration_size =
-                       IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
-       };
+
+       fw->ucode_capa.max_probe_length = 200;
+       fw->ucode_capa.standard_phy_calibration_size =
+                       IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
 
        if (!api_ok)
                api_ok = api_max;
@@ -1029,19 +1034,19 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
        memset(&pieces, 0, sizeof(pieces));
 
        if (!ucode_raw) {
-               if (priv->fw_index <= api_ok)
-                       IWL_ERR(priv,
+               if (nic->fw_index <= api_ok)
+                       IWL_ERR(nic,
                                "request for firmware file '%s' failed.\n",
-                               priv->firmware_name);
+                               nic->firmware_name);
                goto try_again;
        }
 
-       IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
-                      priv->firmware_name, ucode_raw->size);
+       IWL_DEBUG_INFO(nic, "Loaded firmware file '%s' (%zd bytes).\n",
+                      nic->firmware_name, ucode_raw->size);
 
        /* Make sure that we got at least the API version number */
        if (ucode_raw->size < 4) {
-               IWL_ERR(priv, "File size way too small!\n");
+               IWL_ERR(nic, "File size way too small!\n");
                goto try_again;
        }
 
@@ -1049,15 +1054,15 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
        ucode = (struct iwl_ucode_header *)ucode_raw->data;
 
        if (ucode->ver)
-               err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces);
+               err = iwl_parse_v1_v2_firmware(nic, ucode_raw, &pieces);
        else
-               err = iwlagn_load_firmware(priv, ucode_raw, &pieces,
-                                          &ucode_capa);
+               err = iwl_parse_tlv_firmware(nic, ucode_raw, &pieces,
+                                          &fw->ucode_capa);
 
        if (err)
                goto try_again;
 
-       api_ver = IWL_UCODE_API(priv->ucode_ver);
+       api_ver = IWL_UCODE_API(nic->fw.ucode_ver);
        build = pieces.build;
 
        /*
@@ -1066,9 +1071,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
         * on the API version read from firmware header from here on forward
         */
        /* no api version check required for experimental uCode */
-       if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
+       if (nic->fw_index != UCODE_EXPERIMENTAL_INDEX) {
                if (api_ver < api_min || api_ver > api_max) {
-                       IWL_ERR(priv,
+                       IWL_ERR(nic,
                                "Driver unable to support your firmware API. "
                                "Driver supports v%u, firmware is v%u.\n",
                                api_max, api_ver);
@@ -1077,39 +1082,39 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 
                if (api_ver < api_ok) {
                        if (api_ok != api_max)
-                               IWL_ERR(priv, "Firmware has old API version, "
+                               IWL_ERR(nic, "Firmware has old API version, "
                                        "expected v%u through v%u, got v%u.\n",
                                        api_ok, api_max, api_ver);
                        else
-                               IWL_ERR(priv, "Firmware has old API version, "
+                               IWL_ERR(nic, "Firmware has old API version, "
                                        "expected v%u, got v%u.\n",
                                        api_max, api_ver);
-                       IWL_ERR(priv, "New firmware can be obtained from "
+                       IWL_ERR(nic, "New firmware can be obtained from "
                                      "http://www.intellinuxwireless.org/.\n");
                }
        }
 
        if (build)
                sprintf(buildstr, " build %u%s", build,
-                      (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+                      (nic->fw_index == UCODE_EXPERIMENTAL_INDEX)
                                ? " (EXP)" : "");
        else
                buildstr[0] = '\0';
 
-       IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n",
-                IWL_UCODE_MAJOR(priv->ucode_ver),
-                IWL_UCODE_MINOR(priv->ucode_ver),
-                IWL_UCODE_API(priv->ucode_ver),
-                IWL_UCODE_SERIAL(priv->ucode_ver),
+       IWL_INFO(nic, "loaded firmware version %u.%u.%u.%u%s\n",
+                IWL_UCODE_MAJOR(nic->fw.ucode_ver),
+                IWL_UCODE_MINOR(nic->fw.ucode_ver),
+                IWL_UCODE_API(nic->fw.ucode_ver),
+                IWL_UCODE_SERIAL(nic->fw.ucode_ver),
                 buildstr);
 
        snprintf(priv->hw->wiphy->fw_version,
                 sizeof(priv->hw->wiphy->fw_version),
                 "%u.%u.%u.%u%s",
-                IWL_UCODE_MAJOR(priv->ucode_ver),
-                IWL_UCODE_MINOR(priv->ucode_ver),
-                IWL_UCODE_API(priv->ucode_ver),
-                IWL_UCODE_SERIAL(priv->ucode_ver),
+                IWL_UCODE_MAJOR(nic->fw.ucode_ver),
+                IWL_UCODE_MINOR(nic->fw.ucode_ver),
+                IWL_UCODE_API(nic->fw.ucode_ver),
+                IWL_UCODE_SERIAL(nic->fw.ucode_ver),
                 buildstr);
 
        /*
@@ -1118,38 +1123,38 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
         * user just got a corrupted version of the latest API.
         */
 
-       IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
-                      priv->ucode_ver);
-       IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n",
+       IWL_DEBUG_INFO(nic, "f/w package hdr ucode version raw = 0x%x\n",
+                      nic->fw.ucode_ver);
+       IWL_DEBUG_INFO(nic, "f/w package hdr runtime inst size = %Zd\n",
                       pieces.inst_size);
-       IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n",
+       IWL_DEBUG_INFO(nic, "f/w package hdr runtime data size = %Zd\n",
                       pieces.data_size);
-       IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n",
+       IWL_DEBUG_INFO(nic, "f/w package hdr init inst size = %Zd\n",
                       pieces.init_size);
-       IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
+       IWL_DEBUG_INFO(nic, "f/w package hdr init data size = %Zd\n",
                       pieces.init_data_size);
 
        /* Verify that uCode images will fit in card's SRAM */
-       if (pieces.inst_size > hw_params(priv).max_inst_size) {
-               IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n",
+       if (pieces.inst_size > cfg->max_inst_size) {
+               IWL_ERR(nic, "uCode instr len %Zd too large to fit in\n",
                        pieces.inst_size);
                goto try_again;
        }
 
-       if (pieces.data_size > hw_params(priv).max_data_size) {
-               IWL_ERR(priv, "uCode data len %Zd too large to fit in\n",
+       if (pieces.data_size > cfg->max_data_size) {
+               IWL_ERR(nic, "uCode data len %Zd too large to fit in\n",
                        pieces.data_size);
                goto try_again;
        }
 
-       if (pieces.init_size > hw_params(priv).max_inst_size) {
-               IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n",
+       if (pieces.init_size > cfg->max_inst_size) {
+               IWL_ERR(nic, "uCode init instr len %Zd too large to fit in\n",
                        pieces.init_size);
                goto try_again;
        }
 
-       if (pieces.init_data_size > hw_params(priv).max_data_size) {
-               IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n",
+       if (pieces.init_data_size > cfg->max_data_size) {
+               IWL_ERR(nic, "uCode init data len %Zd too large to fit in\n",
                        pieces.init_data_size);
                goto try_again;
        }
@@ -1159,34 +1164,34 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
        /* Runtime instructions and 2 copies of data:
         * 1) unmodified from disk
         * 2) backup cache for save/restore during power-downs */
-       if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code,
+       if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.code,
                              pieces.inst, pieces.inst_size))
                goto err_pci_alloc;
-       if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data,
+       if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.data,
                              pieces.data, pieces.data_size))
                goto err_pci_alloc;
 
        /* Initialization instructions and data */
        if (pieces.init_size && pieces.init_data_size) {
-               if (iwl_alloc_fw_desc(trans(priv),
-                                     &trans(priv)->ucode_init.code,
+               if (iwl_alloc_fw_desc(nic,
+                                     &nic->fw.ucode_init.code,
                                      pieces.init, pieces.init_size))
                        goto err_pci_alloc;
-               if (iwl_alloc_fw_desc(trans(priv),
-                                     &trans(priv)->ucode_init.data,
+               if (iwl_alloc_fw_desc(nic,
+                                     &nic->fw.ucode_init.data,
                                      pieces.init_data, pieces.init_data_size))
                        goto err_pci_alloc;
        }
 
        /* WoWLAN instructions and data */
        if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
-               if (iwl_alloc_fw_desc(trans(priv),
-                                     &trans(priv)->ucode_wowlan.code,
+               if (iwl_alloc_fw_desc(nic,
+                                     &nic->fw.ucode_wowlan.code,
                                      pieces.wowlan_inst,
                                      pieces.wowlan_inst_size))
                        goto err_pci_alloc;
-               if (iwl_alloc_fw_desc(trans(priv),
-                                     &trans(priv)->ucode_wowlan.data,
+               if (iwl_alloc_fw_desc(nic,
+                                     &nic->fw.ucode_wowlan.data,
                                      pieces.wowlan_data,
                                      pieces.wowlan_data_size))
                        goto err_pci_alloc;
@@ -1199,92 +1204,94 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
         * for each event, which is of mode 1 (including timestamp) for all
         * new microcodes that include this information.
         */
-       priv->init_evtlog_ptr = pieces.init_evtlog_ptr;
+       nic->init_evtlog_ptr = pieces.init_evtlog_ptr;
        if (pieces.init_evtlog_size)
-               priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
+               nic->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
        else
-               priv->init_evtlog_size =
-                       cfg(priv)->base_params->max_event_log_size;
-       priv->init_errlog_ptr = pieces.init_errlog_ptr;
-       priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
+               nic->init_evtlog_size =
+                       cfg->base_params->max_event_log_size;
+       nic->init_errlog_ptr = pieces.init_errlog_ptr;
+       nic->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
        if (pieces.inst_evtlog_size)
-               priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
+               nic->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
        else
-               priv->inst_evtlog_size =
-                       cfg(priv)->base_params->max_event_log_size;
-       priv->inst_errlog_ptr = pieces.inst_errlog_ptr;
+               nic->inst_evtlog_size =
+                       cfg->base_params->max_event_log_size;
+       nic->inst_errlog_ptr = pieces.inst_errlog_ptr;
 #ifndef CONFIG_IWLWIFI_P2P
-       ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
+       fw->ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
 #endif
 
        priv->new_scan_threshold_behaviour =
-               !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
+               !!(fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
 
-       if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE))
-               ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
+       if (!(cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE))
+               fw->ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
 
        /*
         * if not PAN, then don't support P2P -- might be a uCode
         * packaging bug or due to the eeprom check above
         */
-       if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN))
-               ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
+       if (!(fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN))
+               fw->ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
 
-       if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
+       if (fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
                priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
-               priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
+               nic->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
        } else {
                priv->sta_key_max_num = STA_KEY_MAX_NUM;
-               priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
+               nic->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
        }
        /*
         * figure out the offset of chain noise reset and gain commands
         * base on the size of standard phy calibration commands table size
         */
-       if (ucode_capa.standard_phy_calibration_size >
+       if (fw->ucode_capa.standard_phy_calibration_size >
            IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
-               ucode_capa.standard_phy_calibration_size =
+               fw->ucode_capa.standard_phy_calibration_size =
                        IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
 
        priv->phy_calib_chain_noise_reset_cmd =
-               ucode_capa.standard_phy_calibration_size;
+               fw->ucode_capa.standard_phy_calibration_size;
        priv->phy_calib_chain_noise_gain_cmd =
-               ucode_capa.standard_phy_calibration_size + 1;
+               fw->ucode_capa.standard_phy_calibration_size + 1;
 
        /* initialize all valid contexts */
-       iwl_init_context(priv, ucode_capa.flags);
+       iwl_init_context(priv, fw->ucode_capa.flags);
 
        /**************************************************
         * This is still part of probe() in a sense...
         *
         * 9. Setup and register with mac80211 and debugfs
         **************************************************/
-       err = iwlagn_mac_setup_register(priv, &ucode_capa);
+       err = iwlagn_mac_setup_register(priv, &fw->ucode_capa);
        if (err)
                goto out_unbind;
 
        err = iwl_dbgfs_register(priv, DRV_NAME);
        if (err)
-               IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
+               IWL_ERR(nic,
+                       "failed to create debugfs files. Ignoring error: %d\n",
+                       err);
 
        /* We have our copies now, allow OS release its copies */
        release_firmware(ucode_raw);
-       complete(&priv->firmware_loading_complete);
+       complete(&nic->request_firmware_complete);
        return;
 
  try_again:
        /* try next, if any */
-       if (iwl_request_firmware(priv, false))
+       if (iwl_request_firmware(nic, false))
                goto out_unbind;
        release_firmware(ucode_raw);
        return;
 
  err_pci_alloc:
-       IWL_ERR(priv, "failed to allocate pci memory\n");
-       iwl_dealloc_ucode(trans(priv));
+       IWL_ERR(nic, "failed to allocate pci memory\n");
+       iwl_dealloc_ucode(nic);
  out_unbind:
-       complete(&priv->firmware_loading_complete);
-       device_release_driver(trans(priv)->dev);
+       complete(&nic->request_firmware_complete);
+       device_release_driver(trans(nic)->dev);
        release_firmware(ucode_raw);
 }
 
index eccf92519a840df761204846fdcd5f1a5030ffb3..d13e6241f126599a2b874aedf1266954fa0d917d 100644 (file)
@@ -63,6 +63,8 @@
 #ifndef __iwl_ucode_h__
 #define __iwl_ucode_h__
 
+#include <linux/netdevice.h>
+
 /* v1/v2 uCode file layout */
 struct iwl_ucode_header {
        __le32 ver;     /* major/minor/API/serial */
@@ -171,8 +173,49 @@ struct iwl_tlv_ucode_header {
        u8 data[0];
 };
 
-struct iwl_priv;
+struct iwl_ucode_capabilities {
+       u32 max_probe_length;
+       u32 standard_phy_calibration_size;
+       u32 flags;
+};
+
+/* one for each uCode image (inst/data, boot/init/runtime) */
+struct fw_desc {
+       dma_addr_t p_addr;      /* hardware address */
+       void *v_addr;           /* software address */
+       u32 len;                /* size in bytes */
+};
 
-int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first);
+struct fw_img {
+       struct fw_desc code;    /* firmware code image */
+       struct fw_desc data;    /* firmware data image */
+};
+
+/**
+ * struct iwl_fw - variables associated with the firmware
+ *
+ * @ucode_ver: ucode version from the ucode file
+ * @fw_version: firmware version string
+ * @ucode_rt: run time ucode image
+ * @ucode_init: init ucode image
+ * @ucode_wowlan: wake on wireless ucode image (optional)
+ * @ucode_capa: capabilities parsed from the ucode file.
+ * @enhance_sensitivity_table: device can do enhanced sensitivity.
+ */
+struct iwl_fw {
+
+       /* ucode image and variables */
+       u32 ucode_ver;                  /* version of ucode, copy of
+                                          iwl_ucode.ver */
+       char fw_version[ETHTOOL_BUSINFO_LEN];
+
+       /* ucode images */
+       struct fw_img ucode_rt;
+       struct fw_img ucode_init;
+       struct fw_img ucode_wowlan;
+
+       struct iwl_ucode_capabilities ucode_capa;
+       bool enhance_sensitivity_table;
+};
 
 #endif  /* __iwl_ucode_h__ */
index 7e6eb20823cf9757121b6ec683e3d734a88aed92..84172f6de4bba1890e4d7e26839f7398a52f02a3 100644 (file)
 #define __iwl_wifi_h__
 
 #include "iwl-shared.h"
+#include "iwl-ucode.h"
+
+/**
+ * struct iwl_nic - nic common data
+ * @fw: the iwl_fw structure
+ * @shrd: pointer to common shared structure
+ * @fw_index: firmware revision to try loading
+ * @firmware_name: composite filename of ucode file to load
+ * @init_evtlog_ptr: event log offset for init ucode.
+ * @init_evtlog_size: event log size for init ucode.
+ * @init_errlog_ptr: error log offfset for init ucode.
+ * @inst_evtlog_ptr: event log offset for runtime ucode.
+ * @inst_evtlog_size: event log size for runtime ucode.
+ * @inst_errlog_ptr: error log offfset for runtime ucode.
+ * @request_firmware_complete: the firmware has been obtained from user space
+ */
+struct iwl_nic {
+       struct iwl_fw fw;
+
+       struct iwl_shared *shrd;
+
+       int fw_index;                   /* firmware we're trying to load */
+       char firmware_name[25];         /* name of firmware file to load */
+
+       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
+       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
+
+       struct completion request_firmware_complete;
+};
+
+
+int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first);
+void iwl_dealloc_ucode(struct iwl_nic *nic);
 
 int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type);
 void iwl_send_prio_tbl(struct iwl_trans *trans);