Merge branch 'for-linville' of git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index bb6a737..89a41d3 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -14,7 +14,6 @@
iwlagn-objs += iwl-1000.o
iwlagn-objs += iwl-2000.o
-iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index baf8011..3da8cf2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -45,7 +45,6 @@
#include "iwl-agn.h"
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL1000_UCODE_API_MAX 5
@@ -121,10 +120,10 @@
static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -197,21 +196,11 @@
EEPROM_REG_BAND_24_HT40_CHANNELS,
EEPROM_REGULATORY_BAND_NO_HT40,
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
};
@@ -249,7 +238,6 @@
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.ops = &iwl1000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl1000_base_params, \
.led_mode = IWL_LED_BLINK
@@ -271,7 +259,6 @@
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.ops = &iwl1000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl1000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.rx_with_siso_diversity = true
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index e76e02c..bca462c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -46,17 +46,16 @@
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
#include "iwl-6000-hw.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL2030_UCODE_API_MAX 5
#define IWL2000_UCODE_API_MAX 5
-#define IWL200_UCODE_API_MAX 5
+#define IWL105_UCODE_API_MAX 5
/* Lowest firmware API version supported */
#define IWL2030_UCODE_API_MIN 5
#define IWL2000_UCODE_API_MIN 5
-#define IWL200_UCODE_API_MIN 5
+#define IWL105_UCODE_API_MIN 5
#define IWL2030_FW_PRE "iwlwifi-2030-"
#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode"
@@ -64,8 +63,8 @@
#define IWL2000_FW_PRE "iwlwifi-2000-"
#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode"
-#define IWL200_FW_PRE "iwlwifi-200-"
-#define IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode"
+#define IWL105_FW_PRE "iwlwifi-105-"
+#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE #api ".ucode"
static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
{
@@ -128,10 +127,10 @@
static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -280,22 +279,12 @@
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_REGULATORY_BAND_NO_HT40,
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
};
@@ -312,13 +301,13 @@
.utils = &iwlagn_hcmd_utils,
};
-static const struct iwl_ops iwl200_ops = {
+static const struct iwl_ops iwl105_ops = {
.lib = &iwl2000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
};
-static const struct iwl_ops iwl230_ops = {
+static const struct iwl_ops iwl135_ops = {
.lib = &iwl2000_lib,
.hcmd = &iwlagn_bt_hcmd,
.utils = &iwlagn_hcmd_utils,
@@ -383,7 +372,6 @@
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.ops = &iwl2000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl2000_base_params, \
.need_dc_calib = true, \
.need_temp_offset_calib = true, \
@@ -409,7 +397,6 @@
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.ops = &iwl2030_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl2030_base_params, \
.bt_params = &iwl2030_bt_params, \
.need_dc_calib = true, \
@@ -429,14 +416,13 @@
IWL_DEVICE_2030,
};
-#define IWL_DEVICE_200 \
- .fw_name_pre = IWL200_FW_PRE, \
- .ucode_api_max = IWL200_UCODE_API_MAX, \
- .ucode_api_min = IWL200_UCODE_API_MIN, \
+#define IWL_DEVICE_105 \
+ .fw_name_pre = IWL105_FW_PRE, \
+ .ucode_api_max = IWL105_UCODE_API_MAX, \
+ .ucode_api_min = IWL105_UCODE_API_MIN, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
- .ops = &iwl200_ops, \
- .mod_params = &iwlagn_mod_params, \
+ .ops = &iwl105_ops, \
.base_params = &iwl2000_base_params, \
.need_dc_calib = true, \
.need_temp_offset_calib = true, \
@@ -444,25 +430,24 @@
.adv_pm = true, \
.rx_with_siso_diversity = true \
-struct iwl_cfg iwl200_bg_cfg = {
- .name = "200 Series 1x1 BG",
- IWL_DEVICE_200,
+struct iwl_cfg iwl105_bg_cfg = {
+ .name = "105 Series 1x1 BG",
+ IWL_DEVICE_105,
};
-struct iwl_cfg iwl200_bgn_cfg = {
- .name = "200 Series 1x1 BGN",
- IWL_DEVICE_200,
+struct iwl_cfg iwl105_bgn_cfg = {
+ .name = "105 Series 1x1 BGN",
+ IWL_DEVICE_105,
.ht_params = &iwl2000_ht_params,
};
-#define IWL_DEVICE_230 \
- .fw_name_pre = IWL200_FW_PRE, \
- .ucode_api_max = IWL200_UCODE_API_MAX, \
- .ucode_api_min = IWL200_UCODE_API_MIN, \
+#define IWL_DEVICE_135 \
+ .fw_name_pre = IWL105_FW_PRE, \
+ .ucode_api_max = IWL105_UCODE_API_MAX, \
+ .ucode_api_min = IWL105_UCODE_API_MIN, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
- .ops = &iwl230_ops, \
- .mod_params = &iwlagn_mod_params, \
+ .ops = &iwl135_ops, \
.base_params = &iwl2030_base_params, \
.bt_params = &iwl2030_bt_params, \
.need_dc_calib = true, \
@@ -471,17 +456,17 @@
.adv_pm = true, \
.rx_with_siso_diversity = true \
-struct iwl_cfg iwl230_bg_cfg = {
- .name = "200 Series 1x1 BG/BT",
- IWL_DEVICE_230,
+struct iwl_cfg iwl135_bg_cfg = {
+ .name = "105 Series 1x1 BG/BT",
+ IWL_DEVICE_135,
};
-struct iwl_cfg iwl230_bgn_cfg = {
- .name = "200 Series 1x1 BGN/BT",
- IWL_DEVICE_230,
+struct iwl_cfg iwl135_bgn_cfg = {
+ .name = "105 Series 1x1 BGN/BT",
+ IWL_DEVICE_135,
.ht_params = &iwl2000_ht_params,
};
MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL200_MODULE_FIRMWARE(IWL200_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 655afc1..561f2cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -47,7 +47,6 @@
#include "iwl-agn.h"
#include "iwl-agn-hw.h"
#include "iwl-5000-hw.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL5000_UCODE_API_MAX 5
@@ -165,10 +164,10 @@
static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -210,10 +209,10 @@
static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -366,21 +365,11 @@
EEPROM_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
};
@@ -413,21 +402,11 @@
EEPROM_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
},
.temp_ops = {
.temperature = iwl5150_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
};
@@ -468,7 +447,6 @@
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
.ops = &iwl5000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl5000_base_params, \
.led_mode = IWL_LED_BLINK
@@ -512,7 +490,6 @@
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.ops = &iwl5000_ops,
- .mod_params = &iwlagn_mod_params,
.base_params = &iwl5000_base_params,
.ht_params = &iwl5000_ht_params,
.led_mode = IWL_LED_BLINK,
@@ -526,7 +503,6 @@
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
.ops = &iwl5150_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl5000_base_params, \
.need_dc_calib = true, \
.led_mode = IWL_LED_BLINK, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 905eb57..6045457 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -46,7 +46,6 @@
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
#include "iwl-6000-hw.h"
-#include "iwl-agn-debugfs.h"
/* Highest firmware API version supported */
#define IWL6000_UCODE_API_MAX 4
@@ -80,7 +79,7 @@
static void iwl6050_additional_nic_config(struct iwl_priv *priv)
{
/* Indicate calibration version to uCode. */
- if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
+ if (iwlagn_eeprom_calib_version(priv) >= 6)
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
}
@@ -88,7 +87,7 @@
static void iwl6150_additional_nic_config(struct iwl_priv *priv)
{
/* Indicate calibration version to uCode. */
- if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
+ if (iwlagn_eeprom_calib_version(priv) >= 6)
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
@@ -154,10 +153,10 @@
static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
{
- if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
- priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+ if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+ iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
priv->cfg->base_params->num_of_queues =
- priv->cfg->mod_params->num_of_queues;
+ iwlagn_mod_params.num_of_queues;
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -305,22 +304,12 @@
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
};
@@ -354,22 +343,12 @@
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
EEPROM_REG_BAND_52_HT40_CHANNELS
},
- .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
- .release_semaphore = iwlcore_eeprom_release_semaphore,
- .calib_version = iwlagn_eeprom_calib_version,
.query_addr = iwlagn_eeprom_query_addr,
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
},
.temp_ops = {
.temperature = iwlagn_temperature,
},
- .debugfs_ops = {
- .rx_stats_read = iwl_ucode_rx_stats_read,
- .tx_stats_read = iwl_ucode_tx_stats_read,
- .general_stats_read = iwl_ucode_general_stats_read,
- .bt_stats_read = iwl_ucode_bt_stats_read,
- .reply_tx_error = iwl_reply_tx_error_read,
- },
.txfifo_flush = iwlagn_txfifo_flush,
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
};
@@ -482,7 +461,6 @@
.eeprom_ver = EEPROM_6005_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
.ops = &iwl6000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6000_g2_base_params, \
.need_dc_calib = true, \
.need_temp_offset_calib = true, \
@@ -511,7 +489,6 @@
.eeprom_ver = EEPROM_6030_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
.ops = &iwl6030_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6000_g2_base_params, \
.bt_params = &iwl6000_bt_params, \
.need_dc_calib = true, \
@@ -593,7 +570,6 @@
.eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
.ops = &iwl6000_ops, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6000_base_params, \
.pa_type = IWL_PA_INTERNAL, \
.led_mode = IWL_LED_BLINK
@@ -623,7 +599,6 @@
.ops = &iwl6050_ops, \
.eeprom_ver = EEPROM_6050_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
- .mod_params = &iwlagn_mod_params, \
.base_params = &iwl6050_base_params, \
.need_dc_calib = true, \
.led_mode = IWL_LED_BLINK, \
@@ -648,7 +623,6 @@
.eeprom_ver = EEPROM_6150_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION,
.ops = &iwl6150_ops,
- .mod_params = &iwlagn_mod_params,
.base_params = &iwl6050_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
@@ -664,7 +638,6 @@
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
.ops = &iwl6000_ops,
- .mod_params = &iwlagn_mod_params,
.base_params = &iwl6000_base_params,
.ht_params = &iwl6000_ht_params,
.need_dc_calib = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
deleted file mode 100644
index 71a5f31..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ /dev/null
@@ -1,1025 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 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
- *****************************************************************************/
-#include "iwl-agn.h"
-#include "iwl-agn-debugfs.h"
-
-static const char *fmt_value = " %-30s %10u\n";
-static const char *fmt_hex = " %-30s 0x%02X\n";
-static const char *fmt_table = " %-30s %10u %10u %10u %10u\n";
-static const char *fmt_header =
- "%-32s current cumulative delta max\n";
-
-static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
-{
- int p = 0;
- u32 flag;
-
- flag = le32_to_cpu(priv->statistics.flag);
-
- p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
- if (flag & UCODE_STATISTICS_CLEAR_MSK)
- p += scnprintf(buf + p, bufsz - p,
- "\tStatistics have been cleared\n");
- p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
- (flag & UCODE_STATISTICS_FREQUENCY_MSK)
- ? "2.4 GHz" : "5.2 GHz");
- p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
- (flag & UCODE_STATISTICS_NARROW_BAND_MSK)
- ? "enabled" : "disabled");
-
- return p;
-}
-
-ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
- {
- struct iwl_priv *priv = file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = sizeof(struct statistics_rx_phy) * 40 +
- sizeof(struct statistics_rx_non_phy) * 40 +
- sizeof(struct statistics_rx_ht_phy) * 40 + 400;
- ssize_t ret;
- struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
- struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
- struct statistics_rx_non_phy *general, *accum_general;
- struct statistics_rx_non_phy *delta_general, *max_general;
- struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /*
- * the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- ofdm = &priv->statistics.rx_ofdm;
- cck = &priv->statistics.rx_cck;
- general = &priv->statistics.rx_non_phy;
- ht = &priv->statistics.rx_ofdm_ht;
- accum_ofdm = &priv->accum_stats.rx_ofdm;
- accum_cck = &priv->accum_stats.rx_cck;
- accum_general = &priv->accum_stats.rx_non_phy;
- accum_ht = &priv->accum_stats.rx_ofdm_ht;
- delta_ofdm = &priv->delta_stats.rx_ofdm;
- delta_cck = &priv->delta_stats.rx_cck;
- delta_general = &priv->delta_stats.rx_non_phy;
- delta_ht = &priv->delta_stats.rx_ofdm_ht;
- max_ofdm = &priv->max_delta_stats.rx_ofdm;
- max_cck = &priv->max_delta_stats.rx_cck;
- max_general = &priv->max_delta_stats.rx_non_phy;
- max_ht = &priv->max_delta_stats.rx_ofdm_ht;
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - OFDM:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ina_cnt:",
- le32_to_cpu(ofdm->ina_cnt),
- accum_ofdm->ina_cnt,
- delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_cnt:",
- le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
- delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "plcp_err:",
- le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
- delta_ofdm->plcp_err, max_ofdm->plcp_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_err:",
- le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
- delta_ofdm->crc32_err, max_ofdm->crc32_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "overrun_err:",
- le32_to_cpu(ofdm->overrun_err),
- accum_ofdm->overrun_err, delta_ofdm->overrun_err,
- max_ofdm->overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "early_overrun_err:",
- le32_to_cpu(ofdm->early_overrun_err),
- accum_ofdm->early_overrun_err,
- delta_ofdm->early_overrun_err,
- max_ofdm->early_overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_good:",
- le32_to_cpu(ofdm->crc32_good),
- accum_ofdm->crc32_good, delta_ofdm->crc32_good,
- max_ofdm->crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "false_alarm_cnt:",
- le32_to_cpu(ofdm->false_alarm_cnt),
- accum_ofdm->false_alarm_cnt,
- delta_ofdm->false_alarm_cnt,
- max_ofdm->false_alarm_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_sync_err_cnt:",
- le32_to_cpu(ofdm->fina_sync_err_cnt),
- accum_ofdm->fina_sync_err_cnt,
- delta_ofdm->fina_sync_err_cnt,
- max_ofdm->fina_sync_err_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sfd_timeout:",
- le32_to_cpu(ofdm->sfd_timeout),
- accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
- max_ofdm->sfd_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_timeout:",
- le32_to_cpu(ofdm->fina_timeout),
- accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
- max_ofdm->fina_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "unresponded_rts:",
- le32_to_cpu(ofdm->unresponded_rts),
- accum_ofdm->unresponded_rts,
- delta_ofdm->unresponded_rts,
- max_ofdm->unresponded_rts);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rxe_frame_lmt_ovrun:",
- le32_to_cpu(ofdm->rxe_frame_limit_overrun),
- accum_ofdm->rxe_frame_limit_overrun,
- delta_ofdm->rxe_frame_limit_overrun,
- max_ofdm->rxe_frame_limit_overrun);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ack_cnt:",
- le32_to_cpu(ofdm->sent_ack_cnt),
- accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
- max_ofdm->sent_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_cts_cnt:",
- le32_to_cpu(ofdm->sent_cts_cnt),
- accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
- max_ofdm->sent_cts_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ba_rsp_cnt:",
- le32_to_cpu(ofdm->sent_ba_rsp_cnt),
- accum_ofdm->sent_ba_rsp_cnt,
- delta_ofdm->sent_ba_rsp_cnt,
- max_ofdm->sent_ba_rsp_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dsp_self_kill:",
- le32_to_cpu(ofdm->dsp_self_kill),
- accum_ofdm->dsp_self_kill,
- delta_ofdm->dsp_self_kill,
- max_ofdm->dsp_self_kill);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "mh_format_err:",
- le32_to_cpu(ofdm->mh_format_err),
- accum_ofdm->mh_format_err,
- delta_ofdm->mh_format_err,
- max_ofdm->mh_format_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "re_acq_main_rssi_sum:",
- le32_to_cpu(ofdm->re_acq_main_rssi_sum),
- accum_ofdm->re_acq_main_rssi_sum,
- delta_ofdm->re_acq_main_rssi_sum,
- max_ofdm->re_acq_main_rssi_sum);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - CCK:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ina_cnt:",
- le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
- delta_cck->ina_cnt, max_cck->ina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_cnt:",
- le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
- delta_cck->fina_cnt, max_cck->fina_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "plcp_err:",
- le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
- delta_cck->plcp_err, max_cck->plcp_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_err:",
- le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
- delta_cck->crc32_err, max_cck->crc32_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "overrun_err:",
- le32_to_cpu(cck->overrun_err),
- accum_cck->overrun_err, delta_cck->overrun_err,
- max_cck->overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "early_overrun_err:",
- le32_to_cpu(cck->early_overrun_err),
- accum_cck->early_overrun_err,
- delta_cck->early_overrun_err,
- max_cck->early_overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_good:",
- le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
- delta_cck->crc32_good, max_cck->crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "false_alarm_cnt:",
- le32_to_cpu(cck->false_alarm_cnt),
- accum_cck->false_alarm_cnt,
- delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_sync_err_cnt:",
- le32_to_cpu(cck->fina_sync_err_cnt),
- accum_cck->fina_sync_err_cnt,
- delta_cck->fina_sync_err_cnt,
- max_cck->fina_sync_err_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sfd_timeout:",
- le32_to_cpu(cck->sfd_timeout),
- accum_cck->sfd_timeout, delta_cck->sfd_timeout,
- max_cck->sfd_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "fina_timeout:",
- le32_to_cpu(cck->fina_timeout),
- accum_cck->fina_timeout, delta_cck->fina_timeout,
- max_cck->fina_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "unresponded_rts:",
- le32_to_cpu(cck->unresponded_rts),
- accum_cck->unresponded_rts, delta_cck->unresponded_rts,
- max_cck->unresponded_rts);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rxe_frame_lmt_ovrun:",
- le32_to_cpu(cck->rxe_frame_limit_overrun),
- accum_cck->rxe_frame_limit_overrun,
- delta_cck->rxe_frame_limit_overrun,
- max_cck->rxe_frame_limit_overrun);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ack_cnt:",
- le32_to_cpu(cck->sent_ack_cnt),
- accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
- max_cck->sent_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_cts_cnt:",
- le32_to_cpu(cck->sent_cts_cnt),
- accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
- max_cck->sent_cts_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sent_ba_rsp_cnt:",
- le32_to_cpu(cck->sent_ba_rsp_cnt),
- accum_cck->sent_ba_rsp_cnt,
- delta_cck->sent_ba_rsp_cnt,
- max_cck->sent_ba_rsp_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dsp_self_kill:",
- le32_to_cpu(cck->dsp_self_kill),
- accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
- max_cck->dsp_self_kill);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "mh_format_err:",
- le32_to_cpu(cck->mh_format_err),
- accum_cck->mh_format_err, delta_cck->mh_format_err,
- max_cck->mh_format_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "re_acq_main_rssi_sum:",
- le32_to_cpu(cck->re_acq_main_rssi_sum),
- accum_cck->re_acq_main_rssi_sum,
- delta_cck->re_acq_main_rssi_sum,
- max_cck->re_acq_main_rssi_sum);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - GENERAL:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bogus_cts:",
- le32_to_cpu(general->bogus_cts),
- accum_general->bogus_cts, delta_general->bogus_cts,
- max_general->bogus_cts);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bogus_ack:",
- le32_to_cpu(general->bogus_ack),
- accum_general->bogus_ack, delta_general->bogus_ack,
- max_general->bogus_ack);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "non_bssid_frames:",
- le32_to_cpu(general->non_bssid_frames),
- accum_general->non_bssid_frames,
- delta_general->non_bssid_frames,
- max_general->non_bssid_frames);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "filtered_frames:",
- le32_to_cpu(general->filtered_frames),
- accum_general->filtered_frames,
- delta_general->filtered_frames,
- max_general->filtered_frames);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "non_channel_beacons:",
- le32_to_cpu(general->non_channel_beacons),
- accum_general->non_channel_beacons,
- delta_general->non_channel_beacons,
- max_general->non_channel_beacons);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "channel_beacons:",
- le32_to_cpu(general->channel_beacons),
- accum_general->channel_beacons,
- delta_general->channel_beacons,
- max_general->channel_beacons);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "num_missed_bcon:",
- le32_to_cpu(general->num_missed_bcon),
- accum_general->num_missed_bcon,
- delta_general->num_missed_bcon,
- max_general->num_missed_bcon);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "adc_rx_saturation_time:",
- le32_to_cpu(general->adc_rx_saturation_time),
- accum_general->adc_rx_saturation_time,
- delta_general->adc_rx_saturation_time,
- max_general->adc_rx_saturation_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ina_detect_search_tm:",
- le32_to_cpu(general->ina_detection_search_time),
- accum_general->ina_detection_search_time,
- delta_general->ina_detection_search_time,
- max_general->ina_detection_search_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_silence_rssi_a:",
- le32_to_cpu(general->beacon_silence_rssi_a),
- accum_general->beacon_silence_rssi_a,
- delta_general->beacon_silence_rssi_a,
- max_general->beacon_silence_rssi_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_silence_rssi_b:",
- le32_to_cpu(general->beacon_silence_rssi_b),
- accum_general->beacon_silence_rssi_b,
- delta_general->beacon_silence_rssi_b,
- max_general->beacon_silence_rssi_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_silence_rssi_c:",
- le32_to_cpu(general->beacon_silence_rssi_c),
- accum_general->beacon_silence_rssi_c,
- delta_general->beacon_silence_rssi_c,
- max_general->beacon_silence_rssi_c);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "interference_data_flag:",
- le32_to_cpu(general->interference_data_flag),
- accum_general->interference_data_flag,
- delta_general->interference_data_flag,
- max_general->interference_data_flag);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "channel_load:",
- le32_to_cpu(general->channel_load),
- accum_general->channel_load,
- delta_general->channel_load,
- max_general->channel_load);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dsp_false_alarms:",
- le32_to_cpu(general->dsp_false_alarms),
- accum_general->dsp_false_alarms,
- delta_general->dsp_false_alarms,
- max_general->dsp_false_alarms);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_rssi_a:",
- le32_to_cpu(general->beacon_rssi_a),
- accum_general->beacon_rssi_a,
- delta_general->beacon_rssi_a,
- max_general->beacon_rssi_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_rssi_b:",
- le32_to_cpu(general->beacon_rssi_b),
- accum_general->beacon_rssi_b,
- delta_general->beacon_rssi_b,
- max_general->beacon_rssi_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_rssi_c:",
- le32_to_cpu(general->beacon_rssi_c),
- accum_general->beacon_rssi_c,
- delta_general->beacon_rssi_c,
- max_general->beacon_rssi_c);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_energy_a:",
- le32_to_cpu(general->beacon_energy_a),
- accum_general->beacon_energy_a,
- delta_general->beacon_energy_a,
- max_general->beacon_energy_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_energy_b:",
- le32_to_cpu(general->beacon_energy_b),
- accum_general->beacon_energy_b,
- delta_general->beacon_energy_b,
- max_general->beacon_energy_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "beacon_energy_c:",
- le32_to_cpu(general->beacon_energy_c),
- accum_general->beacon_energy_c,
- delta_general->beacon_energy_c,
- max_general->beacon_energy_c);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Rx - OFDM_HT:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "plcp_err:",
- le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
- delta_ht->plcp_err, max_ht->plcp_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "overrun_err:",
- le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
- delta_ht->overrun_err, max_ht->overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "early_overrun_err:",
- le32_to_cpu(ht->early_overrun_err),
- accum_ht->early_overrun_err,
- delta_ht->early_overrun_err,
- max_ht->early_overrun_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_good:",
- le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
- delta_ht->crc32_good, max_ht->crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "crc32_err:",
- le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
- delta_ht->crc32_err, max_ht->crc32_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "mh_format_err:",
- le32_to_cpu(ht->mh_format_err),
- accum_ht->mh_format_err,
- delta_ht->mh_format_err, max_ht->mh_format_err);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg_crc32_good:",
- le32_to_cpu(ht->agg_crc32_good),
- accum_ht->agg_crc32_good,
- delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg_mpdu_cnt:",
- le32_to_cpu(ht->agg_mpdu_cnt),
- accum_ht->agg_mpdu_cnt,
- delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg_cnt:",
- le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
- delta_ht->agg_cnt, max_ht->agg_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "unsupport_mcs:",
- le32_to_cpu(ht->unsupport_mcs),
- accum_ht->unsupport_mcs,
- delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_ucode_tx_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
- ssize_t ret;
- struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /* the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- tx = &priv->statistics.tx;
- accum_tx = &priv->accum_stats.tx;
- delta_tx = &priv->delta_stats.tx;
- max_tx = &priv->max_delta_stats.tx;
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_Tx:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "preamble:",
- le32_to_cpu(tx->preamble_cnt),
- accum_tx->preamble_cnt,
- delta_tx->preamble_cnt, max_tx->preamble_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rx_detected_cnt:",
- le32_to_cpu(tx->rx_detected_cnt),
- accum_tx->rx_detected_cnt,
- delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bt_prio_defer_cnt:",
- le32_to_cpu(tx->bt_prio_defer_cnt),
- accum_tx->bt_prio_defer_cnt,
- delta_tx->bt_prio_defer_cnt,
- max_tx->bt_prio_defer_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "bt_prio_kill_cnt:",
- le32_to_cpu(tx->bt_prio_kill_cnt),
- accum_tx->bt_prio_kill_cnt,
- delta_tx->bt_prio_kill_cnt,
- max_tx->bt_prio_kill_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "few_bytes_cnt:",
- le32_to_cpu(tx->few_bytes_cnt),
- accum_tx->few_bytes_cnt,
- delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "cts_timeout:",
- le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
- delta_tx->cts_timeout, max_tx->cts_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ack_timeout:",
- le32_to_cpu(tx->ack_timeout),
- accum_tx->ack_timeout,
- delta_tx->ack_timeout, max_tx->ack_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "expected_ack_cnt:",
- le32_to_cpu(tx->expected_ack_cnt),
- accum_tx->expected_ack_cnt,
- delta_tx->expected_ack_cnt,
- max_tx->expected_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "actual_ack_cnt:",
- le32_to_cpu(tx->actual_ack_cnt),
- accum_tx->actual_ack_cnt,
- delta_tx->actual_ack_cnt,
- max_tx->actual_ack_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "dump_msdu_cnt:",
- le32_to_cpu(tx->dump_msdu_cnt),
- accum_tx->dump_msdu_cnt,
- delta_tx->dump_msdu_cnt,
- max_tx->dump_msdu_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "abort_nxt_frame_mismatch:",
- le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
- accum_tx->burst_abort_next_frame_mismatch_cnt,
- delta_tx->burst_abort_next_frame_mismatch_cnt,
- max_tx->burst_abort_next_frame_mismatch_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "abort_missing_nxt_frame:",
- le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
- accum_tx->burst_abort_missing_next_frame_cnt,
- delta_tx->burst_abort_missing_next_frame_cnt,
- max_tx->burst_abort_missing_next_frame_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "cts_timeout_collision:",
- le32_to_cpu(tx->cts_timeout_collision),
- accum_tx->cts_timeout_collision,
- delta_tx->cts_timeout_collision,
- max_tx->cts_timeout_collision);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "ack_ba_timeout_collision:",
- le32_to_cpu(tx->ack_or_ba_timeout_collision),
- accum_tx->ack_or_ba_timeout_collision,
- delta_tx->ack_or_ba_timeout_collision,
- max_tx->ack_or_ba_timeout_collision);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg ba_timeout:",
- le32_to_cpu(tx->agg.ba_timeout),
- accum_tx->agg.ba_timeout,
- delta_tx->agg.ba_timeout,
- max_tx->agg.ba_timeout);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg ba_resched_frames:",
- le32_to_cpu(tx->agg.ba_reschedule_frames),
- accum_tx->agg.ba_reschedule_frames,
- delta_tx->agg.ba_reschedule_frames,
- max_tx->agg.ba_reschedule_frames);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_agg_frame:",
- le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
- accum_tx->agg.scd_query_agg_frame_cnt,
- delta_tx->agg.scd_query_agg_frame_cnt,
- max_tx->agg.scd_query_agg_frame_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_no_agg:",
- le32_to_cpu(tx->agg.scd_query_no_agg),
- accum_tx->agg.scd_query_no_agg,
- delta_tx->agg.scd_query_no_agg,
- max_tx->agg.scd_query_no_agg);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_agg:",
- le32_to_cpu(tx->agg.scd_query_agg),
- accum_tx->agg.scd_query_agg,
- delta_tx->agg.scd_query_agg,
- max_tx->agg.scd_query_agg);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg scd_query_mismatch:",
- le32_to_cpu(tx->agg.scd_query_mismatch),
- accum_tx->agg.scd_query_mismatch,
- delta_tx->agg.scd_query_mismatch,
- max_tx->agg.scd_query_mismatch);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg frame_not_ready:",
- le32_to_cpu(tx->agg.frame_not_ready),
- accum_tx->agg.frame_not_ready,
- delta_tx->agg.frame_not_ready,
- max_tx->agg.frame_not_ready);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg underrun:",
- le32_to_cpu(tx->agg.underrun),
- accum_tx->agg.underrun,
- delta_tx->agg.underrun, max_tx->agg.underrun);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg bt_prio_kill:",
- le32_to_cpu(tx->agg.bt_prio_kill),
- accum_tx->agg.bt_prio_kill,
- delta_tx->agg.bt_prio_kill,
- max_tx->agg.bt_prio_kill);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "agg rx_ba_rsp_cnt:",
- le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
- accum_tx->agg.rx_ba_rsp_cnt,
- delta_tx->agg.rx_ba_rsp_cnt,
- max_tx->agg.rx_ba_rsp_cnt);
-
- if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
- pos += scnprintf(buf + pos, bufsz - pos,
- "tx power: (1/2 dB step)\n");
- if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_hex, "antenna A:",
- tx->tx_power.ant_a);
- if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_hex, "antenna B:",
- tx->tx_power.ant_b);
- if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_hex, "antenna C:",
- tx->tx_power.ant_c);
- }
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = sizeof(struct statistics_general) * 10 + 300;
- ssize_t ret;
- struct statistics_general_common *general, *accum_general;
- struct statistics_general_common *delta_general, *max_general;
- struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
- struct statistics_div *div, *accum_div, *delta_div, *max_div;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /* the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- general = &priv->statistics.common;
- dbg = &priv->statistics.common.dbg;
- div = &priv->statistics.common.div;
- accum_general = &priv->accum_stats.common;
- accum_dbg = &priv->accum_stats.common.dbg;
- accum_div = &priv->accum_stats.common.div;
- delta_general = &priv->delta_stats.common;
- max_general = &priv->max_delta_stats.common;
- delta_dbg = &priv->delta_stats.common.dbg;
- max_dbg = &priv->max_delta_stats.common.dbg;
- delta_div = &priv->delta_stats.common.div;
- max_div = &priv->max_delta_stats.common.div;
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_header, "Statistics_General:");
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_value, "temperature:",
- le32_to_cpu(general->temperature));
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_value, "temperature_m:",
- le32_to_cpu(general->temperature_m));
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_value, "ttl_timestamp:",
- le32_to_cpu(general->ttl_timestamp));
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "burst_check:",
- le32_to_cpu(dbg->burst_check),
- accum_dbg->burst_check,
- delta_dbg->burst_check, max_dbg->burst_check);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "burst_count:",
- le32_to_cpu(dbg->burst_count),
- accum_dbg->burst_count,
- delta_dbg->burst_count, max_dbg->burst_count);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "wait_for_silence_timeout_count:",
- le32_to_cpu(dbg->wait_for_silence_timeout_cnt),
- accum_dbg->wait_for_silence_timeout_cnt,
- delta_dbg->wait_for_silence_timeout_cnt,
- max_dbg->wait_for_silence_timeout_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "sleep_time:",
- le32_to_cpu(general->sleep_time),
- accum_general->sleep_time,
- delta_general->sleep_time, max_general->sleep_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "slots_out:",
- le32_to_cpu(general->slots_out),
- accum_general->slots_out,
- delta_general->slots_out, max_general->slots_out);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "slots_idle:",
- le32_to_cpu(general->slots_idle),
- accum_general->slots_idle,
- delta_general->slots_idle, max_general->slots_idle);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "tx_on_a:",
- le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
- delta_div->tx_on_a, max_div->tx_on_a);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "tx_on_b:",
- le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
- delta_div->tx_on_b, max_div->tx_on_b);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "exec_time:",
- le32_to_cpu(div->exec_time), accum_div->exec_time,
- delta_div->exec_time, max_div->exec_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "probe_time:",
- le32_to_cpu(div->probe_time), accum_div->probe_time,
- delta_div->probe_time, max_div->probe_time);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "rx_enable_counter:",
- le32_to_cpu(general->rx_enable_counter),
- accum_general->rx_enable_counter,
- delta_general->rx_enable_counter,
- max_general->rx_enable_counter);
- pos += scnprintf(buf + pos, bufsz - pos,
- fmt_table, "num_of_sos_states:",
- le32_to_cpu(general->num_of_sos_states),
- accum_general->num_of_sos_states,
- delta_general->num_of_sos_states,
- max_general->num_of_sos_states);
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_ucode_bt_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
- ssize_t ret;
- struct statistics_bt_activity *bt, *accum_bt;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- if (!priv->bt_enable_flag)
- return -EINVAL;
-
- /* make request to uCode to retrieve statistics information */
- mutex_lock(&priv->mutex);
- ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
- mutex_unlock(&priv->mutex);
-
- if (ret) {
- IWL_ERR(priv,
- "Error sending statistics request: %zd\n", ret);
- return -EAGAIN;
- }
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- /*
- * the statistic information display here is based on
- * the last statistics notification from uCode
- * might not reflect the current uCode activity
- */
- bt = &priv->statistics.bt_activity;
- accum_bt = &priv->accum_stats.bt_activity;
-
- pos += iwl_statistics_flag(priv, buf, bufsz);
- pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
- pos += scnprintf(buf + pos, bufsz - pos,
- "\t\t\tcurrent\t\t\taccumulative\n");
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_tx_req_cnt),
- accum_bt->hi_priority_tx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_tx_denied_cnt),
- accum_bt->hi_priority_tx_denied_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_tx_req_cnt),
- accum_bt->lo_priority_tx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_tx_denied_cnt),
- accum_bt->lo_priority_tx_denied_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_rx_req_cnt),
- accum_bt->hi_priority_rx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->hi_priority_rx_denied_cnt),
- accum_bt->hi_priority_rx_denied_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_rx_req_cnt),
- accum_bt->lo_priority_rx_req_cnt);
- pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
- le32_to_cpu(bt->lo_priority_rx_denied_cnt),
- accum_bt->lo_priority_rx_denied_cnt);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
- le32_to_cpu(priv->statistics.num_bt_kills),
- priv->statistics.accum_num_bt_kills);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-ssize_t iwl_reply_tx_error_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
- int pos = 0;
- char *buf;
- int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) +
- (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
- ssize_t ret;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IWL_ERR(priv, "Can not allocate Buffer\n");
- return -ENOMEM;
- }
-
- pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
- priv->_agn.reply_tx_stats.pp_delay);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
- priv->_agn.reply_tx_stats.pp_few_bytes);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
- priv->_agn.reply_tx_stats.pp_bt_prio);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
- priv->_agn.reply_tx_stats.pp_quiet_period);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
- priv->_agn.reply_tx_stats.pp_calc_ttak);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_tx_fail_reason(
- TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
- priv->_agn.reply_tx_stats.int_crossed_retry);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
- priv->_agn.reply_tx_stats.short_limit);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
- priv->_agn.reply_tx_stats.long_limit);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
- priv->_agn.reply_tx_stats.fifo_underrun);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
- priv->_agn.reply_tx_stats.drain_flow);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
- priv->_agn.reply_tx_stats.rfkill_flush);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
- priv->_agn.reply_tx_stats.life_expire);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
- priv->_agn.reply_tx_stats.dest_ps);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
- priv->_agn.reply_tx_stats.host_abort);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
- priv->_agn.reply_tx_stats.pp_delay);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
- priv->_agn.reply_tx_stats.sta_invalid);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
- priv->_agn.reply_tx_stats.frag_drop);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
- priv->_agn.reply_tx_stats.tid_disable);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
- priv->_agn.reply_tx_stats.fifo_flush);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_tx_fail_reason(
- TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
- priv->_agn.reply_tx_stats.insuff_cf_poll);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
- priv->_agn.reply_tx_stats.fail_hw_drop);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_tx_fail_reason(
- TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
- priv->_agn.reply_tx_stats.sta_color_mismatch);
- pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
- priv->_agn.reply_tx_stats.unknown);
-
- pos += scnprintf(buf + pos, bufsz - pos,
- "\nStatistics_Agg_TX_Error:\n");
-
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
- priv->_agn.reply_agg_tx_stats.underrun);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
- priv->_agn.reply_agg_tx_stats.bt_prio);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
- priv->_agn.reply_agg_tx_stats.few_bytes);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
- priv->_agn.reply_agg_tx_stats.abort);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_LAST_SENT_TTL_MSK),
- priv->_agn.reply_agg_tx_stats.last_sent_ttl);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
- priv->_agn.reply_agg_tx_stats.last_sent_try);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
- priv->_agn.reply_agg_tx_stats.last_sent_bt_kill);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
- priv->_agn.reply_agg_tx_stats.scd_query);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
- iwl_get_agg_tx_fail_reason(
- AGG_TX_STATE_TEST_BAD_CRC32_MSK),
- priv->_agn.reply_agg_tx_stats.bad_crc32);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
- priv->_agn.reply_agg_tx_stats.response);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
- priv->_agn.reply_agg_tx_stats.dump_tx);
- pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
- iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
- priv->_agn.reply_agg_tx_stats.delay_tx);
- pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
- priv->_agn.reply_agg_tx_stats.unknown);
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
deleted file mode 100644
index 9a3f329..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 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
- *****************************************************************************/
-
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-debug.h"
-
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-#else
-static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-static ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index 3bcaa10..2ef9448 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -81,52 +81,13 @@
*
******************************************************************************/
-/*
- * The device's EEPROM semaphore prevents conflicts between driver and uCode
- * when accessing the EEPROM; each access is a series of pulses to/from the
- * EEPROM chip, not a single event, so even reads could conflict if they
- * weren't arbitrated by the semaphore.
- */
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
-{
- u16 count;
- int ret;
-
- for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
- /* Request semaphore */
- iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
- /* See if we got it */
- ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
- EEPROM_SEM_TIMEOUT);
- if (ret >= 0) {
- IWL_DEBUG_EEPROM(priv,
- "Acquired semaphore after %d tries.\n",
- count+1);
- return ret;
- }
- }
-
- return ret;
-}
-
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
-{
- iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
-}
-
int iwl_eeprom_check_version(struct iwl_priv *priv)
{
u16 eeprom_ver;
u16 calib_ver;
eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
- calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
+ calib_ver = iwlagn_eeprom_calib_version(priv);
if (eeprom_ver < priv->cfg->eeprom_ver ||
calib_ver < priv->cfg->eeprom_calib_ver)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 861cc93..49dd03f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -37,54 +37,6 @@
#include "iwl-io.h"
#include "iwl-agn.h"
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
- struct iwl_rxon_context *ctx)
-{
- int ret = 0;
- struct iwl5000_rxon_assoc_cmd rxon_assoc;
- const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
- const struct iwl_rxon_cmd *rxon2 = &ctx->active;
-
- if ((rxon1->flags == rxon2->flags) &&
- (rxon1->filter_flags == rxon2->filter_flags) &&
- (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
- (rxon1->ofdm_ht_single_stream_basic_rates ==
- rxon2->ofdm_ht_single_stream_basic_rates) &&
- (rxon1->ofdm_ht_dual_stream_basic_rates ==
- rxon2->ofdm_ht_dual_stream_basic_rates) &&
- (rxon1->ofdm_ht_triple_stream_basic_rates ==
- rxon2->ofdm_ht_triple_stream_basic_rates) &&
- (rxon1->acquisition_data == rxon2->acquisition_data) &&
- (rxon1->rx_chain == rxon2->rx_chain) &&
- (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
- return 0;
- }
-
- rxon_assoc.flags = ctx->staging.flags;
- rxon_assoc.filter_flags = ctx->staging.filter_flags;
- rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
- rxon_assoc.reserved1 = 0;
- rxon_assoc.reserved2 = 0;
- rxon_assoc.reserved3 = 0;
- rxon_assoc.ofdm_ht_single_stream_basic_rates =
- ctx->staging.ofdm_ht_single_stream_basic_rates;
- rxon_assoc.ofdm_ht_dual_stream_basic_rates =
- ctx->staging.ofdm_ht_dual_stream_basic_rates;
- rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
- rxon_assoc.ofdm_ht_triple_stream_basic_rates =
- ctx->staging.ofdm_ht_triple_stream_basic_rates;
- rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
-
- ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
- sizeof(rxon_assoc), &rxon_assoc, NULL);
- if (ret)
- return ret;
-
- return ret;
-}
-
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
{
struct iwl_tx_ant_config_cmd tx_ant_cmd = {
@@ -364,7 +316,6 @@
}
struct iwl_hcmd_ops iwlagn_hcmd = {
- .rxon_assoc = iwlagn_send_rxon_assoc,
.commit_rxon = iwlagn_commit_rxon,
.set_rxon_chain = iwlagn_set_rxon_chain,
.set_tx_ant = iwlagn_send_tx_ant_config,
@@ -373,7 +324,6 @@
};
struct iwl_hcmd_ops iwlagn_bt_hcmd = {
- .rxon_assoc = iwlagn_send_rxon_assoc,
.commit_rxon = iwlagn_commit_rxon,
.set_rxon_chain = iwlagn_set_rxon_chain,
.set_tx_ant = iwlagn_send_tx_ant_config,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index e202a40..8e79653 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -665,7 +665,7 @@
rb_timeout = RX_RB_TIMEOUT;
- if (priv->cfg->mod_params->amsdu_size_8K)
+ if (iwlagn_mod_params.amsdu_size_8K)
rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
else
rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
@@ -1294,9 +1294,17 @@
* mean we never reach it, but at the same time work around
* the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
* here instead of IWL_GOOD_CRC_TH_DISABLED.
+ *
+ * This was fixed in later versions along with some other
+ * scan changes, and the threshold behaves as a flag in those
+ * versions.
*/
- scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
- IWL_GOOD_CRC_TH_NEVER;
+ if (priv->new_scan_threshold_behaviour)
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+ IWL_GOOD_CRC_TH_DISABLED;
+ else
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+ IWL_GOOD_CRC_TH_NEVER;
band = priv->scan_band;
@@ -2363,12 +2371,21 @@
/* device going down, Stop using ICT table */
iwl_disable_ict(priv);
- iwlagn_txq_ctx_stop(priv);
- iwlagn_rxq_stop(priv);
+ /*
+ * If a HW restart happens during firmware loading,
+ * then the firmware loading might call this function
+ * and later it might be called again due to the
+ * restart. So don't process again if the device is
+ * already dead.
+ */
+ if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
+ iwlagn_txq_ctx_stop(priv);
+ iwlagn_rxq_stop(priv);
- /* Power-down device's busmaster DMA clocks */
- iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
- udelay(5);
+ /* Power-down device's busmaster DMA clocks */
+ iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+ udelay(5);
+ }
/* Make sure (redundant) we've released our request to stay awake */
iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 202ef64..0238743 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -121,6 +121,151 @@
return iwlagn_send_beacon_cmd(priv);
}
+static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret = 0;
+ struct iwl_rxon_assoc_cmd rxon_assoc;
+ const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
+ const struct iwl_rxon_cmd *rxon2 = &ctx->active;
+
+ if ((rxon1->flags == rxon2->flags) &&
+ (rxon1->filter_flags == rxon2->filter_flags) &&
+ (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
+ (rxon1->ofdm_ht_single_stream_basic_rates ==
+ rxon2->ofdm_ht_single_stream_basic_rates) &&
+ (rxon1->ofdm_ht_dual_stream_basic_rates ==
+ rxon2->ofdm_ht_dual_stream_basic_rates) &&
+ (rxon1->ofdm_ht_triple_stream_basic_rates ==
+ rxon2->ofdm_ht_triple_stream_basic_rates) &&
+ (rxon1->acquisition_data == rxon2->acquisition_data) &&
+ (rxon1->rx_chain == rxon2->rx_chain) &&
+ (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
+ return 0;
+ }
+
+ rxon_assoc.flags = ctx->staging.flags;
+ rxon_assoc.filter_flags = ctx->staging.filter_flags;
+ rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+ rxon_assoc.reserved1 = 0;
+ rxon_assoc.reserved2 = 0;
+ rxon_assoc.reserved3 = 0;
+ rxon_assoc.ofdm_ht_single_stream_basic_rates =
+ ctx->staging.ofdm_ht_single_stream_basic_rates;
+ rxon_assoc.ofdm_ht_dual_stream_basic_rates =
+ ctx->staging.ofdm_ht_dual_stream_basic_rates;
+ rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
+ rxon_assoc.ofdm_ht_triple_stream_basic_rates =
+ ctx->staging.ofdm_ht_triple_stream_basic_rates;
+ rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
+
+ ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
+ sizeof(rxon_assoc), &rxon_assoc, NULL);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int iwlagn_rxon_disconn(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret;
+ struct iwl_rxon_cmd *active = (void *)&ctx->active;
+
+ if (ctx->ctxid == IWL_RXON_CTX_BSS)
+ ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
+ else
+ ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+ if (ret)
+ return ret;
+
+ /*
+ * Un-assoc RXON clears the station table and WEP
+ * keys, so we have to restore those afterwards.
+ */
+ iwl_clear_ucode_stations(priv, ctx);
+ iwl_restore_stations(priv, ctx);
+ ret = iwl_restore_default_wep_keys(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+ return ret;
+ }
+
+ memcpy(active, &ctx->staging, sizeof(*active));
+ return 0;
+}
+
+static int iwlagn_rxon_connect(struct iwl_priv *priv,
+ struct iwl_rxon_context *ctx)
+{
+ int ret;
+ struct iwl_rxon_cmd *active = (void *)&ctx->active;
+
+ /* RXON timing must be before associated RXON */
+ ret = iwl_send_rxon_timing(priv, ctx);
+ if (ret) {
+ IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+ return ret;
+ }
+ /* QoS info may be cleared by previous un-assoc RXON */
+ iwlagn_update_qos(priv, ctx);
+
+ /*
+ * We'll run into this code path when beaconing is
+ * enabled, but then we also need to send the beacon
+ * to the device.
+ */
+ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
+ ret = iwlagn_update_beacon(priv, ctx->vif);
+ if (ret) {
+ IWL_ERR(priv,
+ "Error sending required beacon (%d)!\n",
+ ret);
+ return ret;
+ }
+ }
+
+ priv->start_calib = 0;
+ /*
+ * Apply the new configuration.
+ *
+ * Associated RXON doesn't clear the station table in uCode,
+ * so we don't need to restore stations etc. after this.
+ */
+ ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+ sizeof(struct iwl_rxon_cmd), &ctx->staging);
+ if (ret) {
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ memcpy(active, &ctx->staging, sizeof(*active));
+
+ iwl_reprogram_ap_sta(priv, ctx);
+
+ /* IBSS beacon needs to be sent after setting assoc */
+ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
+ if (iwlagn_update_beacon(priv, ctx->vif))
+ IWL_ERR(priv, "Error sending IBSS beacon\n");
+ iwl_init_sensitivity(priv);
+
+ /*
+ * If we issue a new RXON command which required a tune then
+ * we must send a new TXPOWER command or we won't be able to
+ * Tx any frames.
+ *
+ * It's expected we set power here if channel is changing.
+ */
+ ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
+ if (ret) {
+ IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
/**
* iwlagn_commit_rxon - commit staging_rxon to hardware
*
@@ -128,6 +273,16 @@
* the active_rxon structure is updated with the new data. This
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
+ *
+ * The connect/disconnect flow should be as the following:
+ *
+ * 1. make sure send RXON command with association bit unset if not connect
+ * this should include the channel and the band for the candidate
+ * to be connected to
+ * 2. Add Station before RXON association with the AP
+ * 3. RXON_timing has to send before RXON for connection
+ * 4. full RXON command - associated bit set
+ * 5. use RXON_ASSOC command to update any flags changes
*/
int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
@@ -177,6 +332,7 @@
else
ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ iwl_print_rx_config_cmd(priv, ctx);
ret = iwl_check_rxon_cmd(priv, ctx);
if (ret) {
IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
@@ -200,14 +356,13 @@
* and other flags for the current radio configuration.
*/
if (!iwl_full_rxon_required(priv, ctx)) {
- ret = iwl_send_rxon_assoc(priv, ctx);
+ ret = iwlagn_send_rxon_assoc(priv, ctx);
if (ret) {
IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
return ret;
}
memcpy(active, &ctx->staging, sizeof(*active));
- iwl_print_rx_config_cmd(priv, ctx);
return 0;
}
@@ -217,7 +372,7 @@
return ret;
}
- iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
+ iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto);
IWL_DEBUG_INFO(priv,
"Going to commit RXON\n"
@@ -235,92 +390,13 @@
* set up filters in the device.
*/
if ((old_assoc && new_assoc) || !new_assoc) {
- if (ctx->ctxid == IWL_RXON_CTX_BSS)
- ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
- else
- ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+ ret = iwlagn_rxon_disconn(priv, ctx);
if (ret)
return ret;
-
- memcpy(active, &ctx->staging, sizeof(*active));
-
- /*
- * Un-assoc RXON clears the station table and WEP
- * keys, so we have to restore those afterwards.
- */
- iwl_clear_ucode_stations(priv, ctx);
- iwl_restore_stations(priv, ctx);
- ret = iwl_restore_default_wep_keys(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
- return ret;
- }
}
- /* RXON timing must be before associated RXON */
- ret = iwl_send_rxon_timing(priv, ctx);
- if (ret) {
- IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
- return ret;
- }
-
- if (new_assoc) {
- /* QoS info may be cleared by previous un-assoc RXON */
- iwlagn_update_qos(priv, ctx);
-
- /*
- * We'll run into this code path when beaconing is
- * enabled, but then we also need to send the beacon
- * to the device.
- */
- if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
- ret = iwlagn_update_beacon(priv, ctx->vif);
- if (ret) {
- IWL_ERR(priv,
- "Error sending required beacon (%d)!\n",
- ret);
- return ret;
- }
- }
-
- priv->start_calib = 0;
- /*
- * Apply the new configuration.
- *
- * Associated RXON doesn't clear the station table in uCode,
- * so we don't need to restore stations etc. after this.
- */
- ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
- sizeof(struct iwl_rxon_cmd), &ctx->staging);
- if (ret) {
- IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
- return ret;
- }
- memcpy(active, &ctx->staging, sizeof(*active));
-
- iwl_reprogram_ap_sta(priv, ctx);
-
- /* IBSS beacon needs to be sent after setting assoc */
- if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
- if (iwlagn_update_beacon(priv, ctx->vif))
- IWL_ERR(priv, "Error sending IBSS beacon\n");
- }
-
- iwl_print_rx_config_cmd(priv, ctx);
-
- iwl_init_sensitivity(priv);
-
- /*
- * If we issue a new RXON command which required a tune then we must
- * send a new TXPOWER command or we won't be able to Tx any frames.
- *
- * It's expected we set power here if channel is changing.
- */
- ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
- if (ret) {
- IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
- return ret;
- }
+ if (new_assoc)
+ return iwlagn_rxon_connect(priv, ctx);
return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index a4ec524..003d524 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1716,6 +1716,9 @@
priv->cfg->base_params->max_event_log_size;
priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
+ priv->new_scan_threshold_behaviour =
+ !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
+
if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
@@ -2493,6 +2496,42 @@
mutex_unlock(&priv->mutex);
}
+static void iwlagn_prepare_restart(struct iwl_priv *priv)
+{
+ struct iwl_rxon_context *ctx;
+ bool bt_full_concurrent;
+ u8 bt_ci_compliance;
+ u8 bt_load;
+ u8 bt_status;
+
+ lockdep_assert_held(&priv->mutex);
+
+ for_each_context(priv, ctx)
+ ctx->vif = NULL;
+ priv->is_open = 0;
+
+ /*
+ * __iwl_down() will clear the BT status variables,
+ * which is correct, but when we restart we really
+ * want to keep them so restore them afterwards.
+ *
+ * The restart process will later pick them up and
+ * re-configure the hw when we reconfigure the BT
+ * command.
+ */
+ bt_full_concurrent = priv->bt_full_concurrent;
+ bt_ci_compliance = priv->bt_ci_compliance;
+ bt_load = priv->bt_traffic_load;
+ bt_status = priv->bt_status;
+
+ __iwl_down(priv);
+
+ priv->bt_full_concurrent = bt_full_concurrent;
+ priv->bt_ci_compliance = bt_ci_compliance;
+ priv->bt_traffic_load = bt_load;
+ priv->bt_status = bt_status;
+}
+
static void iwl_bg_restart(struct work_struct *data)
{
struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -2501,38 +2540,8 @@
return;
if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
- struct iwl_rxon_context *ctx;
- bool bt_full_concurrent;
- u8 bt_ci_compliance;
- u8 bt_load;
- u8 bt_status;
-
mutex_lock(&priv->mutex);
- for_each_context(priv, ctx)
- ctx->vif = NULL;
- priv->is_open = 0;
-
- /*
- * __iwl_down() will clear the BT status variables,
- * which is correct, but when we restart we really
- * want to keep them so restore them afterwards.
- *
- * The restart process will later pick them up and
- * re-configure the hw when we reconfigure the BT
- * command.
- */
- bt_full_concurrent = priv->bt_full_concurrent;
- bt_ci_compliance = priv->bt_ci_compliance;
- bt_load = priv->bt_traffic_load;
- bt_status = priv->bt_status;
-
- __iwl_down(priv);
-
- priv->bt_full_concurrent = bt_full_concurrent;
- priv->bt_ci_compliance = bt_ci_compliance;
- priv->bt_traffic_load = bt_load;
- priv->bt_status = bt_status;
-
+ iwlagn_prepare_restart(priv);
mutex_unlock(&priv->mutex);
iwl_cancel_deferred_work(priv);
ieee80211_restart_hw(priv->hw);
@@ -2825,7 +2834,7 @@
IWL_DEBUG_MAC80211(priv, "enter\n");
- if (priv->cfg->mod_params->sw_crypto) {
+ if (iwlagn_mod_params.sw_crypto) {
IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
@@ -3513,14 +3522,14 @@
{
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
- if (priv->cfg->mod_params->amsdu_size_8K)
+ if (iwlagn_mod_params.amsdu_size_8K)
priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K);
else
priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K);
priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
- if (priv->cfg->mod_params->disable_11n)
+ if (iwlagn_mod_params.disable_11n)
priv->cfg->sku &= ~IWL_SKU_N;
/* Device-specific setup */
@@ -4120,21 +4129,21 @@
{IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)},
{IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)},
-/* 200 Series */
- {IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)},
- {IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)},
+/* 105 Series */
+ {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)},
-/* 230 Series */
- {IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)},
- {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)},
- {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)},
+/* 135 Series */
+ {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)},
+ {IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)},
{0}
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index c475ac4..b477336 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -102,10 +102,10 @@
extern struct iwl_cfg iwl6035_2agn_cfg;
extern struct iwl_cfg iwl6035_2abg_cfg;
extern struct iwl_cfg iwl6035_2bg_cfg;
-extern struct iwl_cfg iwl200_bg_cfg;
-extern struct iwl_cfg iwl200_bgn_cfg;
-extern struct iwl_cfg iwl230_bg_cfg;
-extern struct iwl_cfg iwl230_bgn_cfg;
+extern struct iwl_cfg iwl105_bg_cfg;
+extern struct iwl_cfg iwl105_bgn_cfg;
+extern struct iwl_cfg iwl135_bg_cfg;
+extern struct iwl_cfg iwl135_bgn_cfg;
extern struct iwl_mod_params iwlagn_mod_params;
extern struct iwl_hcmd_ops iwlagn_hcmd;
@@ -256,8 +256,6 @@
struct ieee80211_vif *vif, bool add);
/* hcmd */
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
- struct iwl_rxon_context *ctx);
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
@@ -329,8 +327,6 @@
/* eeprom */
void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
/* notification wait support */
void __acquires(wait_entry)
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index e125896..5fdad65 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -661,7 +661,7 @@
/*
* REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
*/
-struct iwl5000_rxon_assoc_cmd {
+struct iwl_rxon_assoc_cmd {
__le32 flags;
__le32 filter_flags;
u8 ofdm_basic_rates;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index af72fd5..4653dea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -41,6 +41,7 @@
#include "iwl-power.h"
#include "iwl-sta.h"
#include "iwl-helpers.h"
+#include "iwl-agn.h"
/*
@@ -94,7 +95,7 @@
max_bit_rate = MAX_BIT_RATE_40_MHZ;
}
- if (priv->cfg->mod_params->amsdu_size_8K)
+ if (iwlagn_mod_params.amsdu_size_8K)
ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
@@ -415,72 +416,72 @@
int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
struct iwl_rxon_cmd *rxon = &ctx->staging;
- bool error = false;
+ u32 errors = 0;
if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
IWL_WARN(priv, "check 2.4G: wrong narrow\n");
- error = true;
+ errors |= BIT(0);
}
if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
IWL_WARN(priv, "check 2.4G: wrong radar\n");
- error = true;
+ errors |= BIT(1);
}
} else {
if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
IWL_WARN(priv, "check 5.2G: not short slot!\n");
- error = true;
+ errors |= BIT(2);
}
if (rxon->flags & RXON_FLG_CCK_MSK) {
IWL_WARN(priv, "check 5.2G: CCK!\n");
- error = true;
+ errors |= BIT(3);
}
}
if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
IWL_WARN(priv, "mac/bssid mcast!\n");
- error = true;
+ errors |= BIT(4);
}
/* make sure basic rates 6Mbps and 1Mbps are supported */
if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
(rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
IWL_WARN(priv, "neither 1 nor 6 are basic\n");
- error = true;
+ errors |= BIT(5);
}
if (le16_to_cpu(rxon->assoc_id) > 2007) {
IWL_WARN(priv, "aid > 2007\n");
- error = true;
+ errors |= BIT(6);
}
if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
IWL_WARN(priv, "CCK and short slot\n");
- error = true;
+ errors |= BIT(7);
}
if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
IWL_WARN(priv, "CCK and auto detect");
- error = true;
+ errors |= BIT(8);
}
if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
RXON_FLG_TGG_PROTECT_MSK)) ==
RXON_FLG_TGG_PROTECT_MSK) {
IWL_WARN(priv, "TGg but no auto-detect\n");
- error = true;
+ errors |= BIT(9);
}
- if (error)
- IWL_WARN(priv, "Tuning to channel %d\n",
- le16_to_cpu(rxon->channel));
-
- if (error) {
- IWL_ERR(priv, "Invalid RXON\n");
- return -EINVAL;
+ if (rxon->channel == 0) {
+ IWL_WARN(priv, "zero channel is invalid\n");
+ errors |= BIT(10);
}
- return 0;
+
+ WARN(errors, "Invalid RXON (%#x), channel %d",
+ errors, le16_to_cpu(rxon->channel));
+
+ return errors ? -EINVAL : 0;
}
/**
@@ -926,7 +927,7 @@
}
if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- if (priv->cfg->mod_params->restart_fw) {
+ if (iwlagn_mod_params.restart_fw) {
IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
"Restarting adapter due to uCode error.\n");
queue_work(priv->workqueue, &priv->restart);
@@ -995,6 +996,8 @@
{
IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
+ clear_bit(STATUS_DEVICE_ENABLED, &priv->status);
+
/* Stop device's DMA activity */
iwl_apm_stop_master(priv);
@@ -1109,6 +1112,8 @@
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+ set_bit(STATUS_DEVICE_ENABLED, &priv->status);
+
out:
return ret;
}
@@ -1743,7 +1748,7 @@
* detect failure), then fw_restart module parameter
* need to be check before performing firmware reload
*/
- if (!external && !priv->cfg->mod_params->restart_fw) {
+ if (!external && !iwlagn_mod_params.restart_fw) {
IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
"module parameter setting\n");
break;
@@ -1760,6 +1765,7 @@
{
struct iwl_priv *priv = hw->priv;
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+ struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct iwl_rxon_context *tmp;
u32 interface_modes;
int err;
@@ -1784,6 +1790,19 @@
goto out;
}
+ /*
+ * Refuse a change that should be done by moving from the PAN
+ * context to the BSS context instead, if the BSS context is
+ * available and can support the new interface type.
+ */
+ if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif &&
+ (bss_ctx->interface_modes & BIT(newtype) ||
+ bss_ctx->exclusive_interface_modes & BIT(newtype))) {
+ BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+ err = -EBUSY;
+ goto out;
+ }
+
if (ctx->exclusive_interface_modes & BIT(newtype)) {
for_each_context(priv, tmp) {
if (ctx == tmp)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 32a990f..dec98207 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -90,7 +90,6 @@
#define IWL_CMD(x) case x: return #x
struct iwl_hcmd_ops {
- int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
void (*set_rxon_chain)(struct iwl_priv *priv,
struct iwl_rxon_context *ctx);
@@ -122,19 +121,6 @@
void (*config)(struct iwl_priv *priv);
};
-struct iwl_debugfs_ops {
- ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
- ssize_t (*reply_tx_error)(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-};
-
struct iwl_temp_ops {
void (*temperature)(struct iwl_priv *priv);
};
@@ -183,7 +169,6 @@
int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
- struct iwl_debugfs_ops debugfs_ops;
};
/* NIC specific ops */
@@ -326,8 +311,6 @@
u16 eeprom_ver;
u16 eeprom_calib_ver;
const struct iwl_ops *ops;
- /* module based parameters which can be set from modprobe cmd */
- const struct iwl_mod_params *mod_params;
/* params not likely to change within a device family */
struct iwl_base_params *base_params;
/* params likely to change within a device family */
@@ -592,6 +575,7 @@
#define STATUS_SCAN_HW 15
#define STATUS_POWER_PMI 16
#define STATUS_FW_ERROR 17
+#define STATUS_DEVICE_ENABLED 18
static inline int iwl_is_ready(struct iwl_priv *priv)
@@ -644,11 +628,6 @@
int iwl_apm_init(struct iwl_priv *priv);
int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-static inline int iwl_send_rxon_assoc(struct iwl_priv *priv,
- struct iwl_rxon_context *ctx)
-{
- return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx);
-}
static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
struct iwl_rxon_context *ctx)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 7bd4f5a..0e6a04b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -39,6 +39,7 @@
#include "iwl-debug.h"
#include "iwl-core.h"
#include "iwl-io.h"
+#include "iwl-agn.h"
/* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
@@ -1037,13 +1038,463 @@
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
+static const char *fmt_value = " %-30s %10u\n";
+static const char *fmt_hex = " %-30s 0x%02X\n";
+static const char *fmt_table = " %-30s %10u %10u %10u %10u\n";
+static const char *fmt_header =
+ "%-32s current cumulative delta max\n";
+
+static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
+{
+ int p = 0;
+ u32 flag;
+
+ flag = le32_to_cpu(priv->statistics.flag);
+
+ p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
+ if (flag & UCODE_STATISTICS_CLEAR_MSK)
+ p += scnprintf(buf + p, bufsz - p,
+ "\tStatistics have been cleared\n");
+ p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
+ (flag & UCODE_STATISTICS_FREQUENCY_MSK)
+ ? "2.4 GHz" : "5.2 GHz");
+ p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
+ (flag & UCODE_STATISTICS_NARROW_BAND_MSK)
+ ? "enabled" : "disabled");
+
+ return p;
+}
+
static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
- return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
- user_buf, count, ppos);
+ int pos = 0;
+ char *buf;
+ int bufsz = sizeof(struct statistics_rx_phy) * 40 +
+ sizeof(struct statistics_rx_non_phy) * 40 +
+ sizeof(struct statistics_rx_ht_phy) * 40 + 400;
+ ssize_t ret;
+ struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
+ struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
+ struct statistics_rx_non_phy *general, *accum_general;
+ struct statistics_rx_non_phy *delta_general, *max_general;
+ struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ ofdm = &priv->statistics.rx_ofdm;
+ cck = &priv->statistics.rx_cck;
+ general = &priv->statistics.rx_non_phy;
+ ht = &priv->statistics.rx_ofdm_ht;
+ accum_ofdm = &priv->accum_stats.rx_ofdm;
+ accum_cck = &priv->accum_stats.rx_cck;
+ accum_general = &priv->accum_stats.rx_non_phy;
+ accum_ht = &priv->accum_stats.rx_ofdm_ht;
+ delta_ofdm = &priv->delta_stats.rx_ofdm;
+ delta_cck = &priv->delta_stats.rx_cck;
+ delta_general = &priv->delta_stats.rx_non_phy;
+ delta_ht = &priv->delta_stats.rx_ofdm_ht;
+ max_ofdm = &priv->max_delta_stats.rx_ofdm;
+ max_cck = &priv->max_delta_stats.rx_cck;
+ max_general = &priv->max_delta_stats.rx_non_phy;
+ max_ht = &priv->max_delta_stats.rx_ofdm_ht;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - OFDM:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ina_cnt:",
+ le32_to_cpu(ofdm->ina_cnt),
+ accum_ofdm->ina_cnt,
+ delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_cnt:",
+ le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
+ delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "plcp_err:",
+ le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
+ delta_ofdm->plcp_err, max_ofdm->plcp_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_err:",
+ le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
+ delta_ofdm->crc32_err, max_ofdm->crc32_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "overrun_err:",
+ le32_to_cpu(ofdm->overrun_err),
+ accum_ofdm->overrun_err, delta_ofdm->overrun_err,
+ max_ofdm->overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "early_overrun_err:",
+ le32_to_cpu(ofdm->early_overrun_err),
+ accum_ofdm->early_overrun_err,
+ delta_ofdm->early_overrun_err,
+ max_ofdm->early_overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_good:",
+ le32_to_cpu(ofdm->crc32_good),
+ accum_ofdm->crc32_good, delta_ofdm->crc32_good,
+ max_ofdm->crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "false_alarm_cnt:",
+ le32_to_cpu(ofdm->false_alarm_cnt),
+ accum_ofdm->false_alarm_cnt,
+ delta_ofdm->false_alarm_cnt,
+ max_ofdm->false_alarm_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_sync_err_cnt:",
+ le32_to_cpu(ofdm->fina_sync_err_cnt),
+ accum_ofdm->fina_sync_err_cnt,
+ delta_ofdm->fina_sync_err_cnt,
+ max_ofdm->fina_sync_err_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sfd_timeout:",
+ le32_to_cpu(ofdm->sfd_timeout),
+ accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
+ max_ofdm->sfd_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_timeout:",
+ le32_to_cpu(ofdm->fina_timeout),
+ accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
+ max_ofdm->fina_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "unresponded_rts:",
+ le32_to_cpu(ofdm->unresponded_rts),
+ accum_ofdm->unresponded_rts,
+ delta_ofdm->unresponded_rts,
+ max_ofdm->unresponded_rts);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rxe_frame_lmt_ovrun:",
+ le32_to_cpu(ofdm->rxe_frame_limit_overrun),
+ accum_ofdm->rxe_frame_limit_overrun,
+ delta_ofdm->rxe_frame_limit_overrun,
+ max_ofdm->rxe_frame_limit_overrun);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ack_cnt:",
+ le32_to_cpu(ofdm->sent_ack_cnt),
+ accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
+ max_ofdm->sent_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_cts_cnt:",
+ le32_to_cpu(ofdm->sent_cts_cnt),
+ accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
+ max_ofdm->sent_cts_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ba_rsp_cnt:",
+ le32_to_cpu(ofdm->sent_ba_rsp_cnt),
+ accum_ofdm->sent_ba_rsp_cnt,
+ delta_ofdm->sent_ba_rsp_cnt,
+ max_ofdm->sent_ba_rsp_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dsp_self_kill:",
+ le32_to_cpu(ofdm->dsp_self_kill),
+ accum_ofdm->dsp_self_kill,
+ delta_ofdm->dsp_self_kill,
+ max_ofdm->dsp_self_kill);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "mh_format_err:",
+ le32_to_cpu(ofdm->mh_format_err),
+ accum_ofdm->mh_format_err,
+ delta_ofdm->mh_format_err,
+ max_ofdm->mh_format_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "re_acq_main_rssi_sum:",
+ le32_to_cpu(ofdm->re_acq_main_rssi_sum),
+ accum_ofdm->re_acq_main_rssi_sum,
+ delta_ofdm->re_acq_main_rssi_sum,
+ max_ofdm->re_acq_main_rssi_sum);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - CCK:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ina_cnt:",
+ le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
+ delta_cck->ina_cnt, max_cck->ina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_cnt:",
+ le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
+ delta_cck->fina_cnt, max_cck->fina_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "plcp_err:",
+ le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
+ delta_cck->plcp_err, max_cck->plcp_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_err:",
+ le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
+ delta_cck->crc32_err, max_cck->crc32_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "overrun_err:",
+ le32_to_cpu(cck->overrun_err),
+ accum_cck->overrun_err, delta_cck->overrun_err,
+ max_cck->overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "early_overrun_err:",
+ le32_to_cpu(cck->early_overrun_err),
+ accum_cck->early_overrun_err,
+ delta_cck->early_overrun_err,
+ max_cck->early_overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_good:",
+ le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
+ delta_cck->crc32_good, max_cck->crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "false_alarm_cnt:",
+ le32_to_cpu(cck->false_alarm_cnt),
+ accum_cck->false_alarm_cnt,
+ delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_sync_err_cnt:",
+ le32_to_cpu(cck->fina_sync_err_cnt),
+ accum_cck->fina_sync_err_cnt,
+ delta_cck->fina_sync_err_cnt,
+ max_cck->fina_sync_err_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sfd_timeout:",
+ le32_to_cpu(cck->sfd_timeout),
+ accum_cck->sfd_timeout, delta_cck->sfd_timeout,
+ max_cck->sfd_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "fina_timeout:",
+ le32_to_cpu(cck->fina_timeout),
+ accum_cck->fina_timeout, delta_cck->fina_timeout,
+ max_cck->fina_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "unresponded_rts:",
+ le32_to_cpu(cck->unresponded_rts),
+ accum_cck->unresponded_rts, delta_cck->unresponded_rts,
+ max_cck->unresponded_rts);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rxe_frame_lmt_ovrun:",
+ le32_to_cpu(cck->rxe_frame_limit_overrun),
+ accum_cck->rxe_frame_limit_overrun,
+ delta_cck->rxe_frame_limit_overrun,
+ max_cck->rxe_frame_limit_overrun);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ack_cnt:",
+ le32_to_cpu(cck->sent_ack_cnt),
+ accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
+ max_cck->sent_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_cts_cnt:",
+ le32_to_cpu(cck->sent_cts_cnt),
+ accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
+ max_cck->sent_cts_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sent_ba_rsp_cnt:",
+ le32_to_cpu(cck->sent_ba_rsp_cnt),
+ accum_cck->sent_ba_rsp_cnt,
+ delta_cck->sent_ba_rsp_cnt,
+ max_cck->sent_ba_rsp_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dsp_self_kill:",
+ le32_to_cpu(cck->dsp_self_kill),
+ accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
+ max_cck->dsp_self_kill);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "mh_format_err:",
+ le32_to_cpu(cck->mh_format_err),
+ accum_cck->mh_format_err, delta_cck->mh_format_err,
+ max_cck->mh_format_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "re_acq_main_rssi_sum:",
+ le32_to_cpu(cck->re_acq_main_rssi_sum),
+ accum_cck->re_acq_main_rssi_sum,
+ delta_cck->re_acq_main_rssi_sum,
+ max_cck->re_acq_main_rssi_sum);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - GENERAL:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bogus_cts:",
+ le32_to_cpu(general->bogus_cts),
+ accum_general->bogus_cts, delta_general->bogus_cts,
+ max_general->bogus_cts);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bogus_ack:",
+ le32_to_cpu(general->bogus_ack),
+ accum_general->bogus_ack, delta_general->bogus_ack,
+ max_general->bogus_ack);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "non_bssid_frames:",
+ le32_to_cpu(general->non_bssid_frames),
+ accum_general->non_bssid_frames,
+ delta_general->non_bssid_frames,
+ max_general->non_bssid_frames);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "filtered_frames:",
+ le32_to_cpu(general->filtered_frames),
+ accum_general->filtered_frames,
+ delta_general->filtered_frames,
+ max_general->filtered_frames);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "non_channel_beacons:",
+ le32_to_cpu(general->non_channel_beacons),
+ accum_general->non_channel_beacons,
+ delta_general->non_channel_beacons,
+ max_general->non_channel_beacons);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "channel_beacons:",
+ le32_to_cpu(general->channel_beacons),
+ accum_general->channel_beacons,
+ delta_general->channel_beacons,
+ max_general->channel_beacons);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "num_missed_bcon:",
+ le32_to_cpu(general->num_missed_bcon),
+ accum_general->num_missed_bcon,
+ delta_general->num_missed_bcon,
+ max_general->num_missed_bcon);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "adc_rx_saturation_time:",
+ le32_to_cpu(general->adc_rx_saturation_time),
+ accum_general->adc_rx_saturation_time,
+ delta_general->adc_rx_saturation_time,
+ max_general->adc_rx_saturation_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ina_detect_search_tm:",
+ le32_to_cpu(general->ina_detection_search_time),
+ accum_general->ina_detection_search_time,
+ delta_general->ina_detection_search_time,
+ max_general->ina_detection_search_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_silence_rssi_a:",
+ le32_to_cpu(general->beacon_silence_rssi_a),
+ accum_general->beacon_silence_rssi_a,
+ delta_general->beacon_silence_rssi_a,
+ max_general->beacon_silence_rssi_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_silence_rssi_b:",
+ le32_to_cpu(general->beacon_silence_rssi_b),
+ accum_general->beacon_silence_rssi_b,
+ delta_general->beacon_silence_rssi_b,
+ max_general->beacon_silence_rssi_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_silence_rssi_c:",
+ le32_to_cpu(general->beacon_silence_rssi_c),
+ accum_general->beacon_silence_rssi_c,
+ delta_general->beacon_silence_rssi_c,
+ max_general->beacon_silence_rssi_c);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "interference_data_flag:",
+ le32_to_cpu(general->interference_data_flag),
+ accum_general->interference_data_flag,
+ delta_general->interference_data_flag,
+ max_general->interference_data_flag);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "channel_load:",
+ le32_to_cpu(general->channel_load),
+ accum_general->channel_load,
+ delta_general->channel_load,
+ max_general->channel_load);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dsp_false_alarms:",
+ le32_to_cpu(general->dsp_false_alarms),
+ accum_general->dsp_false_alarms,
+ delta_general->dsp_false_alarms,
+ max_general->dsp_false_alarms);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_rssi_a:",
+ le32_to_cpu(general->beacon_rssi_a),
+ accum_general->beacon_rssi_a,
+ delta_general->beacon_rssi_a,
+ max_general->beacon_rssi_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_rssi_b:",
+ le32_to_cpu(general->beacon_rssi_b),
+ accum_general->beacon_rssi_b,
+ delta_general->beacon_rssi_b,
+ max_general->beacon_rssi_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_rssi_c:",
+ le32_to_cpu(general->beacon_rssi_c),
+ accum_general->beacon_rssi_c,
+ delta_general->beacon_rssi_c,
+ max_general->beacon_rssi_c);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_energy_a:",
+ le32_to_cpu(general->beacon_energy_a),
+ accum_general->beacon_energy_a,
+ delta_general->beacon_energy_a,
+ max_general->beacon_energy_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_energy_b:",
+ le32_to_cpu(general->beacon_energy_b),
+ accum_general->beacon_energy_b,
+ delta_general->beacon_energy_b,
+ max_general->beacon_energy_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "beacon_energy_c:",
+ le32_to_cpu(general->beacon_energy_c),
+ accum_general->beacon_energy_c,
+ delta_general->beacon_energy_c,
+ max_general->beacon_energy_c);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Rx - OFDM_HT:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "plcp_err:",
+ le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
+ delta_ht->plcp_err, max_ht->plcp_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "overrun_err:",
+ le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
+ delta_ht->overrun_err, max_ht->overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "early_overrun_err:",
+ le32_to_cpu(ht->early_overrun_err),
+ accum_ht->early_overrun_err,
+ delta_ht->early_overrun_err,
+ max_ht->early_overrun_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_good:",
+ le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
+ delta_ht->crc32_good, max_ht->crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "crc32_err:",
+ le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
+ delta_ht->crc32_err, max_ht->crc32_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "mh_format_err:",
+ le32_to_cpu(ht->mh_format_err),
+ accum_ht->mh_format_err,
+ delta_ht->mh_format_err, max_ht->mh_format_err);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg_crc32_good:",
+ le32_to_cpu(ht->agg_crc32_good),
+ accum_ht->agg_crc32_good,
+ delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg_mpdu_cnt:",
+ le32_to_cpu(ht->agg_mpdu_cnt),
+ accum_ht->agg_mpdu_cnt,
+ delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg_cnt:",
+ le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
+ delta_ht->agg_cnt, max_ht->agg_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "unsupport_mcs:",
+ le32_to_cpu(ht->unsupport_mcs),
+ accum_ht->unsupport_mcs,
+ delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
}
static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
@@ -1051,8 +1502,190 @@
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
- return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
- user_buf, count, ppos);
+ int pos = 0;
+ char *buf;
+ int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
+ ssize_t ret;
+ struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /* the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ tx = &priv->statistics.tx;
+ accum_tx = &priv->accum_stats.tx;
+ delta_tx = &priv->delta_stats.tx;
+ max_tx = &priv->max_delta_stats.tx;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_Tx:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "preamble:",
+ le32_to_cpu(tx->preamble_cnt),
+ accum_tx->preamble_cnt,
+ delta_tx->preamble_cnt, max_tx->preamble_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rx_detected_cnt:",
+ le32_to_cpu(tx->rx_detected_cnt),
+ accum_tx->rx_detected_cnt,
+ delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bt_prio_defer_cnt:",
+ le32_to_cpu(tx->bt_prio_defer_cnt),
+ accum_tx->bt_prio_defer_cnt,
+ delta_tx->bt_prio_defer_cnt,
+ max_tx->bt_prio_defer_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "bt_prio_kill_cnt:",
+ le32_to_cpu(tx->bt_prio_kill_cnt),
+ accum_tx->bt_prio_kill_cnt,
+ delta_tx->bt_prio_kill_cnt,
+ max_tx->bt_prio_kill_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "few_bytes_cnt:",
+ le32_to_cpu(tx->few_bytes_cnt),
+ accum_tx->few_bytes_cnt,
+ delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "cts_timeout:",
+ le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
+ delta_tx->cts_timeout, max_tx->cts_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ack_timeout:",
+ le32_to_cpu(tx->ack_timeout),
+ accum_tx->ack_timeout,
+ delta_tx->ack_timeout, max_tx->ack_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "expected_ack_cnt:",
+ le32_to_cpu(tx->expected_ack_cnt),
+ accum_tx->expected_ack_cnt,
+ delta_tx->expected_ack_cnt,
+ max_tx->expected_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "actual_ack_cnt:",
+ le32_to_cpu(tx->actual_ack_cnt),
+ accum_tx->actual_ack_cnt,
+ delta_tx->actual_ack_cnt,
+ max_tx->actual_ack_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "dump_msdu_cnt:",
+ le32_to_cpu(tx->dump_msdu_cnt),
+ accum_tx->dump_msdu_cnt,
+ delta_tx->dump_msdu_cnt,
+ max_tx->dump_msdu_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "abort_nxt_frame_mismatch:",
+ le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
+ accum_tx->burst_abort_next_frame_mismatch_cnt,
+ delta_tx->burst_abort_next_frame_mismatch_cnt,
+ max_tx->burst_abort_next_frame_mismatch_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "abort_missing_nxt_frame:",
+ le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
+ accum_tx->burst_abort_missing_next_frame_cnt,
+ delta_tx->burst_abort_missing_next_frame_cnt,
+ max_tx->burst_abort_missing_next_frame_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "cts_timeout_collision:",
+ le32_to_cpu(tx->cts_timeout_collision),
+ accum_tx->cts_timeout_collision,
+ delta_tx->cts_timeout_collision,
+ max_tx->cts_timeout_collision);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "ack_ba_timeout_collision:",
+ le32_to_cpu(tx->ack_or_ba_timeout_collision),
+ accum_tx->ack_or_ba_timeout_collision,
+ delta_tx->ack_or_ba_timeout_collision,
+ max_tx->ack_or_ba_timeout_collision);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg ba_timeout:",
+ le32_to_cpu(tx->agg.ba_timeout),
+ accum_tx->agg.ba_timeout,
+ delta_tx->agg.ba_timeout,
+ max_tx->agg.ba_timeout);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg ba_resched_frames:",
+ le32_to_cpu(tx->agg.ba_reschedule_frames),
+ accum_tx->agg.ba_reschedule_frames,
+ delta_tx->agg.ba_reschedule_frames,
+ max_tx->agg.ba_reschedule_frames);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_agg_frame:",
+ le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
+ accum_tx->agg.scd_query_agg_frame_cnt,
+ delta_tx->agg.scd_query_agg_frame_cnt,
+ max_tx->agg.scd_query_agg_frame_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_no_agg:",
+ le32_to_cpu(tx->agg.scd_query_no_agg),
+ accum_tx->agg.scd_query_no_agg,
+ delta_tx->agg.scd_query_no_agg,
+ max_tx->agg.scd_query_no_agg);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_agg:",
+ le32_to_cpu(tx->agg.scd_query_agg),
+ accum_tx->agg.scd_query_agg,
+ delta_tx->agg.scd_query_agg,
+ max_tx->agg.scd_query_agg);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg scd_query_mismatch:",
+ le32_to_cpu(tx->agg.scd_query_mismatch),
+ accum_tx->agg.scd_query_mismatch,
+ delta_tx->agg.scd_query_mismatch,
+ max_tx->agg.scd_query_mismatch);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg frame_not_ready:",
+ le32_to_cpu(tx->agg.frame_not_ready),
+ accum_tx->agg.frame_not_ready,
+ delta_tx->agg.frame_not_ready,
+ max_tx->agg.frame_not_ready);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg underrun:",
+ le32_to_cpu(tx->agg.underrun),
+ accum_tx->agg.underrun,
+ delta_tx->agg.underrun, max_tx->agg.underrun);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg bt_prio_kill:",
+ le32_to_cpu(tx->agg.bt_prio_kill),
+ accum_tx->agg.bt_prio_kill,
+ delta_tx->agg.bt_prio_kill,
+ max_tx->agg.bt_prio_kill);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "agg rx_ba_rsp_cnt:",
+ le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
+ accum_tx->agg.rx_ba_rsp_cnt,
+ delta_tx->agg.rx_ba_rsp_cnt,
+ max_tx->agg.rx_ba_rsp_cnt);
+
+ if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "tx power: (1/2 dB step)\n");
+ if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_hex, "antenna A:",
+ tx->tx_power.ant_a);
+ if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_hex, "antenna B:",
+ tx->tx_power.ant_b);
+ if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_hex, "antenna C:",
+ tx->tx_power.ant_c);
+ }
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
}
static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
@@ -1060,8 +1693,347 @@
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
- return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
- user_buf, count, ppos);
+ int pos = 0;
+ char *buf;
+ int bufsz = sizeof(struct statistics_general) * 10 + 300;
+ ssize_t ret;
+ struct statistics_general_common *general, *accum_general;
+ struct statistics_general_common *delta_general, *max_general;
+ struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
+ struct statistics_div *div, *accum_div, *delta_div, *max_div;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /* the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ general = &priv->statistics.common;
+ dbg = &priv->statistics.common.dbg;
+ div = &priv->statistics.common.div;
+ accum_general = &priv->accum_stats.common;
+ accum_dbg = &priv->accum_stats.common.dbg;
+ accum_div = &priv->accum_stats.common.div;
+ delta_general = &priv->delta_stats.common;
+ max_general = &priv->max_delta_stats.common;
+ delta_dbg = &priv->delta_stats.common.dbg;
+ max_dbg = &priv->max_delta_stats.common.dbg;
+ delta_div = &priv->delta_stats.common.div;
+ max_div = &priv->max_delta_stats.common.div;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_header, "Statistics_General:");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_value, "temperature:",
+ le32_to_cpu(general->temperature));
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_value, "temperature_m:",
+ le32_to_cpu(general->temperature_m));
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_value, "ttl_timestamp:",
+ le32_to_cpu(general->ttl_timestamp));
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "burst_check:",
+ le32_to_cpu(dbg->burst_check),
+ accum_dbg->burst_check,
+ delta_dbg->burst_check, max_dbg->burst_check);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "burst_count:",
+ le32_to_cpu(dbg->burst_count),
+ accum_dbg->burst_count,
+ delta_dbg->burst_count, max_dbg->burst_count);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "wait_for_silence_timeout_count:",
+ le32_to_cpu(dbg->wait_for_silence_timeout_cnt),
+ accum_dbg->wait_for_silence_timeout_cnt,
+ delta_dbg->wait_for_silence_timeout_cnt,
+ max_dbg->wait_for_silence_timeout_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "sleep_time:",
+ le32_to_cpu(general->sleep_time),
+ accum_general->sleep_time,
+ delta_general->sleep_time, max_general->sleep_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "slots_out:",
+ le32_to_cpu(general->slots_out),
+ accum_general->slots_out,
+ delta_general->slots_out, max_general->slots_out);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "slots_idle:",
+ le32_to_cpu(general->slots_idle),
+ accum_general->slots_idle,
+ delta_general->slots_idle, max_general->slots_idle);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "tx_on_a:",
+ le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
+ delta_div->tx_on_a, max_div->tx_on_a);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "tx_on_b:",
+ le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
+ delta_div->tx_on_b, max_div->tx_on_b);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "exec_time:",
+ le32_to_cpu(div->exec_time), accum_div->exec_time,
+ delta_div->exec_time, max_div->exec_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "probe_time:",
+ le32_to_cpu(div->probe_time), accum_div->probe_time,
+ delta_div->probe_time, max_div->probe_time);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "rx_enable_counter:",
+ le32_to_cpu(general->rx_enable_counter),
+ accum_general->rx_enable_counter,
+ delta_general->rx_enable_counter,
+ max_general->rx_enable_counter);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ fmt_table, "num_of_sos_states:",
+ le32_to_cpu(general->num_of_sos_states),
+ accum_general->num_of_sos_states,
+ delta_general->num_of_sos_states,
+ max_general->num_of_sos_states);
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ int pos = 0;
+ char *buf;
+ int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
+ ssize_t ret;
+ struct statistics_bt_activity *bt, *accum_bt;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ if (!priv->bt_enable_flag)
+ return -EINVAL;
+
+ /* make request to uCode to retrieve statistics information */
+ mutex_lock(&priv->mutex);
+ ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
+ mutex_unlock(&priv->mutex);
+
+ if (ret) {
+ IWL_ERR(priv,
+ "Error sending statistics request: %zd\n", ret);
+ return -EAGAIN;
+ }
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * the statistic information display here is based on
+ * the last statistics notification from uCode
+ * might not reflect the current uCode activity
+ */
+ bt = &priv->statistics.bt_activity;
+ accum_bt = &priv->accum_stats.bt_activity;
+
+ pos += iwl_statistics_flag(priv, buf, bufsz);
+ pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\t\t\tcurrent\t\t\taccumulative\n");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_tx_req_cnt),
+ accum_bt->hi_priority_tx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_tx_denied_cnt),
+ accum_bt->hi_priority_tx_denied_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_tx_req_cnt),
+ accum_bt->lo_priority_tx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_tx_denied_cnt),
+ accum_bt->lo_priority_tx_denied_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_rx_req_cnt),
+ accum_bt->hi_priority_rx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->hi_priority_rx_denied_cnt),
+ accum_bt->hi_priority_rx_denied_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_rx_req_cnt),
+ accum_bt->lo_priority_rx_req_cnt);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+ le32_to_cpu(bt->lo_priority_rx_denied_cnt),
+ accum_bt->lo_priority_rx_denied_cnt);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
+ le32_to_cpu(priv->statistics.num_bt_kills),
+ priv->statistics.accum_num_bt_kills);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ int pos = 0;
+ char *buf;
+ int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) +
+ (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
+ ssize_t ret;
+
+ if (!iwl_is_alive(priv))
+ return -EAGAIN;
+
+ buf = kzalloc(bufsz, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERR(priv, "Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
+ priv->_agn.reply_tx_stats.pp_delay);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
+ priv->_agn.reply_tx_stats.pp_few_bytes);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
+ priv->_agn.reply_tx_stats.pp_bt_prio);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
+ priv->_agn.reply_tx_stats.pp_quiet_period);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
+ priv->_agn.reply_tx_stats.pp_calc_ttak);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_tx_fail_reason(
+ TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
+ priv->_agn.reply_tx_stats.int_crossed_retry);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
+ priv->_agn.reply_tx_stats.short_limit);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
+ priv->_agn.reply_tx_stats.long_limit);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
+ priv->_agn.reply_tx_stats.fifo_underrun);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
+ priv->_agn.reply_tx_stats.drain_flow);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
+ priv->_agn.reply_tx_stats.rfkill_flush);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
+ priv->_agn.reply_tx_stats.life_expire);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
+ priv->_agn.reply_tx_stats.dest_ps);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
+ priv->_agn.reply_tx_stats.host_abort);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
+ priv->_agn.reply_tx_stats.pp_delay);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
+ priv->_agn.reply_tx_stats.sta_invalid);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
+ priv->_agn.reply_tx_stats.frag_drop);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
+ priv->_agn.reply_tx_stats.tid_disable);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
+ priv->_agn.reply_tx_stats.fifo_flush);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_tx_fail_reason(
+ TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
+ priv->_agn.reply_tx_stats.insuff_cf_poll);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
+ priv->_agn.reply_tx_stats.fail_hw_drop);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_tx_fail_reason(
+ TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
+ priv->_agn.reply_tx_stats.sta_color_mismatch);
+ pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
+ priv->_agn.reply_tx_stats.unknown);
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\nStatistics_Agg_TX_Error:\n");
+
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
+ priv->_agn.reply_agg_tx_stats.underrun);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
+ priv->_agn.reply_agg_tx_stats.bt_prio);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
+ priv->_agn.reply_agg_tx_stats.few_bytes);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
+ priv->_agn.reply_agg_tx_stats.abort);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_LAST_SENT_TTL_MSK),
+ priv->_agn.reply_agg_tx_stats.last_sent_ttl);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
+ priv->_agn.reply_agg_tx_stats.last_sent_try);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
+ priv->_agn.reply_agg_tx_stats.last_sent_bt_kill);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
+ priv->_agn.reply_agg_tx_stats.scd_query);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(
+ AGG_TX_STATE_TEST_BAD_CRC32_MSK),
+ priv->_agn.reply_agg_tx_stats.bad_crc32);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
+ priv->_agn.reply_agg_tx_stats.response);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
+ priv->_agn.reply_agg_tx_stats.dump_tx);
+ pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+ iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
+ priv->_agn.reply_agg_tx_stats.delay_tx);
+ pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
+ priv->_agn.reply_agg_tx_stats.unknown);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
}
static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
@@ -1526,16 +2498,6 @@
return count;
}
-static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
-
- return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file,
- user_buf, count, ppos);
-}
-
static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos) {
@@ -1650,18 +2612,6 @@
return count;
}
-static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_priv *priv = file->private_data;
-
- if (priv->cfg->ops->lib->debugfs_ops.reply_tx_error)
- return priv->cfg->ops->lib->debugfs_ops.reply_tx_error(
- file, user_buf, count, ppos);
- else
- return -ENODATA;
-}
DEBUGFS_READ_FILE_OPS(rx_statistics);
DEBUGFS_READ_FILE_OPS(tx_statistics);
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 197fa74..f098eff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -547,12 +547,13 @@
* enum iwl_ucode_tlv_flag - ucode API flags
* @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
* was a separate TLV but moved here to save space.
- * @IWL_UCODE_TLV_FLAGS_RESERVED_1: reserved
+ * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
+ * treats good CRC threshold as a boolean
* @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
*/
enum iwl_ucode_tlv_flag {
IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
- IWL_UCODE_TLV_FLAGS_RESERVED_1 = BIT(1),
+ IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
};
@@ -1263,6 +1264,8 @@
/* max number of station keys */
u8 sta_key_max_num;
+ bool new_scan_threshold_behaviour;
+
/* EEPROM MAC addresses */
struct mac_address addresses[2];
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 1e1a2d8..c839796 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -142,6 +142,45 @@
*
******************************************************************************/
+/*
+ * The device's EEPROM semaphore prevents conflicts between driver and uCode
+ * when accessing the EEPROM; each access is a series of pulses to/from the
+ * EEPROM chip, not a single event, so even reads could conflict if they
+ * weren't arbitrated by the semaphore.
+ */
+static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+ u16 count;
+ int ret;
+
+ for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
+ /* Request semaphore */
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+ /* See if we got it */
+ ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+ EEPROM_SEM_TIMEOUT);
+ if (ret >= 0) {
+ IWL_DEBUG_EEPROM(priv,
+ "Acquired semaphore after %d tries.\n",
+ count+1);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static void iwl_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+ iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+}
+
static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
{
u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
@@ -421,7 +460,7 @@
}
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
- ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
+ ret = iwl_eeprom_acquire_semaphore(priv);
if (ret < 0) {
IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
ret = -ENOENT;
@@ -488,7 +527,7 @@
ret = 0;
done:
- priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
+ iwl_eeprom_release_semaphore(priv);
err:
if (ret)
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 9ce0525..c960c6f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -294,9 +294,6 @@
struct iwl_eeprom_ops {
const u32 regulatory_bands[7];
- int (*acquire_semaphore) (struct iwl_priv *priv);
- void (*release_semaphore) (struct iwl_priv *priv);
- u16 (*calib_version) (struct iwl_priv *priv);
const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset);
void (*update_enhanced_txpower) (struct iwl_priv *priv);
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 993b3df..aa4a906 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -73,10 +73,9 @@
return -ETIMEDOUT;
}
-int iwl_grab_nic_access(struct iwl_priv *priv)
+int iwl_grab_nic_access_silent(struct iwl_priv *priv)
{
int ret;
- u32 val;
lockdep_assert_held(&priv->reg_lock);
@@ -107,9 +106,6 @@
(CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
if (ret < 0) {
- val = iwl_read32(priv, CSR_GP_CNTRL);
- IWL_ERR(priv,
- "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
return -EIO;
}
@@ -117,6 +113,18 @@
return 0;
}
+int iwl_grab_nic_access(struct iwl_priv *priv)
+{
+ int ret = iwl_grab_nic_access_silent(priv);
+ if (ret) {
+ u32 val = iwl_read32(priv, CSR_GP_CNTRL);
+ IWL_ERR(priv,
+ "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
+ }
+
+ return ret;
+}
+
void iwl_release_nic_access(struct iwl_priv *priv)
{
lockdep_assert_held(&priv->reg_lock);
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 262e026..869edc5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -62,6 +62,7 @@
int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
int timeout);
+int iwl_grab_nic_access_silent(struct iwl_priv *priv);
int iwl_grab_nic_access(struct iwl_priv *priv);
void iwl_release_nic_access(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index aca9a1d..0053e9e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -433,7 +433,6 @@
struct statistics_tx *tx,
unsigned long stamp)
{
- const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
unsigned int msecs;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -449,13 +448,13 @@
if (msecs < 99)
return;
- if (mod_params->ack_check && !iwl_good_ack_health(priv, tx)) {
+ if (iwlagn_mod_params.ack_check && !iwl_good_ack_health(priv, tx)) {
IWL_ERR(priv, "low ack count detected, restart firmware\n");
if (!iwl_force_reset(priv, IWL_FW_RESET, false))
return;
}
- if (mod_params->plcp_check &&
+ if (iwlagn_mod_params.plcp_check &&
!iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
iwl_force_reset(priv, IWL_RF_RESET, false);
}
@@ -846,7 +845,7 @@
}
/* In case of HW accelerated crypto and bad decryption, drop */
- if (!priv->cfg->mod_params->sw_crypto &&
+ if (!iwlagn_mod_params.sw_crypto &&
iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
deleted file mode 100644
index cb80bb4..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ieee80211 subsystem header files.
- *
- * 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.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_spectrum_h__
-#define __iwl_spectrum_h__
-enum { /* ieee80211_basic_report.map */
- IEEE80211_BASIC_MAP_BSS = (1 << 0),
- IEEE80211_BASIC_MAP_OFDM = (1 << 1),
- IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2),
- IEEE80211_BASIC_MAP_RADAR = (1 << 3),
- IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4),
- /* Bits 5-7 are reserved */
-
-};
-struct ieee80211_basic_report {
- u8 channel;
- __le64 start_time;
- __le16 duration;
- u8 map;
-} __packed;
-
-enum { /* ieee80211_measurement_request.mode */
- /* Bit 0 is reserved */
- IEEE80211_MEASUREMENT_ENABLE = (1 << 1),
- IEEE80211_MEASUREMENT_REQUEST = (1 << 2),
- IEEE80211_MEASUREMENT_REPORT = (1 << 3),
- /* Bits 4-7 are reserved */
-};
-
-enum {
- IEEE80211_REPORT_BASIC = 0, /* required */
- IEEE80211_REPORT_CCA = 1, /* optional */
- IEEE80211_REPORT_RPI = 2, /* optional */
- /* 3-255 reserved */
-};
-
-struct ieee80211_measurement_params {
- u8 channel;
- __le64 start_time;
- __le16 duration;
-} __packed;
-
-struct ieee80211_info_element {
- u8 id;
- u8 len;
- u8 data[0];
-} __packed;
-
-struct ieee80211_measurement_request {
- struct ieee80211_info_element ie;
- u8 token;
- u8 mode;
- u8 type;
- struct ieee80211_measurement_params params[0];
-} __packed;
-
-struct ieee80211_measurement_report {
- struct ieee80211_info_element ie;
- u8 token;
- u8 mode;
- u8 type;
- union {
- struct ieee80211_basic_report basic[0];
- } u;
-} __packed;
-
-#endif
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 042eb77..85fca5e 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -100,7 +100,7 @@
struct mwifiex_bssdescriptor *bss_desc)
{
struct mwifiex_ie_types_tsf_timestamp tsf_tlv;
- long long tsf_val;
+ __le64 tsf_val;
/* Null Checks */
if (buffer == NULL)
@@ -116,6 +116,11 @@
memcpy(*buffer, &tsf_tlv, sizeof(tsf_tlv.header));
*buffer += sizeof(tsf_tlv.header);
+ /* TSF at the time when beacon/probe_response was received */
+ tsf_val = cpu_to_le64(bss_desc->network_tsf);
+ memcpy(*buffer, &tsf_val, sizeof(tsf_val));
+ *buffer += sizeof(tsf_val);
+
memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val));
dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - "
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 1b50303..5043fcd 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -280,7 +280,7 @@
* BAND_A(0X04): 'a' band
*/
u16 bss_band;
- long long network_tsf;
+ u64 network_tsf;
u8 time_stamp[8];
union ieee_types_phy_param_set phy_param_set;
union ieee_types_ss_param_set ss_param_set;
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index b21f8123..15237c2 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1797,6 +1797,7 @@
__set_bit(REQUIRE_COPY_IV, &rt2x00dev->cap_flags);
}
__set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
/*
* Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index d79c8fd..6ed646a 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1640,7 +1640,6 @@
struct channel_info *info)
{
u8 rfcsr;
- u16 eeprom;
rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
@@ -1670,11 +1669,10 @@
rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
if (rf->channel <= 14) {
int idx = rf->channel-1;
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) {
+ if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
/* r55/r59 value array of channel 1~14 */
static const char r55_bt_rev[] = {0x83, 0x83,
@@ -2917,8 +2915,7 @@
ant = (div_mode == 3) ? 1 : 0;
/* check if this is a Bluetooth combo card */
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) {
+ if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
u32 reg;
rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
@@ -3727,16 +3724,8 @@
}
/*
- * Read frequency offset and RF programming sequence.
+ * Determine external LNA informations.
*/
- rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
- rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
-
- /*
- * Read external LNA informations.
- */
- rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
-
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G))
__set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G))
@@ -3749,6 +3738,18 @@
__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
/*
+ * Detect if this device has Bluetooth co-existence.
+ */
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
+ __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
+
+ /*
+ * Read frequency offset and RF programming sequence.
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+ rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
+
+ /*
* Store led settings, for correct led behaviour.
*/
#ifdef CONFIG_RT2X00_LIB_LEDS
@@ -3756,7 +3757,7 @@
rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
- rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg);
+ rt2x00dev->led_mcu_reg = eeprom;
#endif /* CONFIG_RT2X00_LIB_LEDS */
/*
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 08d3947..cc4a54f 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -302,8 +302,8 @@
/*
* Write firmware to device.
*/
- rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
- data, len);
+ rt2x00pci_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
+ data, len);
rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000);
rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 0d4e8fa..0eb44cf 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -114,12 +114,12 @@
return false;
}
-static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
+static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
int urb_status, u32 tx_status)
{
if (urb_status) {
WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status);
- return;
+ return false;
}
/* try to read all TX_STA_FIFO entries before scheduling txdone_work */
@@ -129,13 +129,14 @@
"drop tx status report.\n");
queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
} else
- rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO,
- rt2800usb_tx_sta_fifo_read_completed);
+ return true;
} else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
} else if (rt2800usb_txstatus_pending(rt2x00dev)) {
- mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(20));
+ mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
}
+
+ return false;
}
static void rt2800usb_tx_dma_done(struct queue_entry *entry)
@@ -493,7 +494,7 @@
* also delayed -> use a timer to retrieve it.
*/
if (rt2800usb_txstatus_pending(rt2x00dev))
- mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(20));
+ mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
}
/*
@@ -633,6 +634,7 @@
__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
__set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
__set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
setup_timer(&rt2x00dev->txstatus_timer,
rt2800usb_tx_sta_fifo_timeout,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index acf561f..73d3332 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -662,6 +662,7 @@
* Driver configuration
*/
CONFIG_CHANNEL_HT40,
+ CONFIG_POWERSAVING,
};
/*
@@ -681,6 +682,7 @@
REQUIRE_TASKLET_CONTEXT,
REQUIRE_SW_SEQNO,
REQUIRE_HT_TX_DESC,
+ REQUIRE_PS_AUTOWAKE,
/*
* Capabilities
@@ -697,6 +699,7 @@
CAPABILITY_EXTERNAL_LNA_A,
CAPABILITY_EXTERNAL_LNA_BG,
CAPABILITY_DOUBLE_ANTENNA,
+ CAPABILITY_BT_COEXIST,
};
/*
@@ -874,10 +877,20 @@
u8 calibration[2];
/*
+ * Association id.
+ */
+ u16 aid;
+
+ /*
* Beacon interval.
*/
u16 beacon_int;
+ /**
+ * Timestamp of last received beacon
+ */
+ unsigned long last_beacon;
+
/*
* Low level statistics which will have
* to be kept up to date while device is running.
@@ -906,6 +919,11 @@
struct work_struct txdone_work;
/*
+ * Powersaving work
+ */
+ struct delayed_work autowakeup_work;
+
+ /*
* Data queue arrays for RX, TX, Beacon and ATIM.
*/
unsigned int data_queues;
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 2a313b6..edebbf0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -100,6 +100,10 @@
erp.basic_rates = bss_conf->basic_rates;
erp.beacon_int = bss_conf->beacon_int;
+ /* Update the AID, this is needed for dynamic PS support */
+ rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0;
+ rt2x00dev->last_beacon = bss_conf->timestamp;
+
/* Update global beacon interval time, this is needed for PS support */
rt2x00dev->beacon_int = bss_conf->beacon_int;
@@ -204,6 +208,9 @@
{
struct rt2x00lib_conf libconf;
u16 hw_value;
+ u16 autowake_timeout;
+ u16 beacon_int;
+ u16 beacon_diff;
memset(&libconf, 0, sizeof(libconf));
@@ -227,6 +234,10 @@
sizeof(libconf.channel));
}
+ if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
+ (ieee80211_flags & IEEE80211_CONF_CHANGE_PS))
+ cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
+
/*
* Start configuration.
*/
@@ -239,6 +250,26 @@
if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
rt2x00link_reset_tuner(rt2x00dev, false);
+ if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
+ (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) &&
+ (conf->flags & IEEE80211_CONF_PS)) {
+ beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon;
+ beacon_int = msecs_to_jiffies(rt2x00dev->beacon_int);
+
+ if (beacon_diff > beacon_int)
+ beacon_diff = 0;
+
+ autowake_timeout = (conf->max_sleep_period * beacon_int) - beacon_diff;
+ queue_delayed_work(rt2x00dev->workqueue,
+ &rt2x00dev->autowakeup_work,
+ autowake_timeout - 15);
+ }
+
+ if (conf->flags & IEEE80211_CONF_PS)
+ set_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+ else
+ clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+
rt2x00dev->curr_band = conf->channel->band;
rt2x00dev->curr_freq = conf->channel->center_freq;
rt2x00dev->tx_power = conf->power_level;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 7776d9f..2eb5196 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -141,6 +141,16 @@
rt2x00dev);
}
+static void rt2x00lib_autowakeup(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, autowakeup_work.work);
+
+ if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
+ ERROR(rt2x00dev, "Device failed to wakeup.\n");
+ clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+}
+
/*
* Interrupt context handlers.
*/
@@ -416,6 +426,77 @@
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo);
+static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos + 2 + pos[1] > end)
+ return NULL;
+
+ if (pos[0] == ie)
+ return pos;
+
+ pos += 2 + pos[1];
+ }
+
+ return NULL;
+}
+
+static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb,
+ struct rxdone_entry_desc *rxdesc)
+{
+ struct ieee80211_hdr *hdr = (void *) skb->data;
+ struct ieee80211_tim_ie *tim_ie;
+ u8 *tim;
+ u8 tim_len;
+ bool cam;
+
+ /* If this is not a beacon, or if mac80211 has no powersaving
+ * configured, or if the device is already in powersaving mode
+ * we can exit now. */
+ if (likely(!ieee80211_is_beacon(hdr->frame_control) ||
+ !(rt2x00dev->hw->conf.flags & IEEE80211_CONF_PS)))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (skb->len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (!(rxdesc->dev_flags & RXDONE_MY_BSS) ||
+ !rt2x00dev->aid)
+ return;
+
+ rt2x00dev->last_beacon = jiffies;
+
+ tim = rt2x00lib_find_ie(skb->data, skb->len - FCS_LEN, WLAN_EID_TIM);
+ if (!tim)
+ return;
+
+ if (tim[1] < sizeof(*tim_ie))
+ return;
+
+ tim_len = tim[1];
+ tim_ie = (struct ieee80211_tim_ie *) &tim[2];
+
+ /* Check whenever the PHY can be turned off again. */
+
+ /* 1. What about buffered unicast traffic for our AID? */
+ cam = ieee80211_check_tim(tim_ie, tim_len, rt2x00dev->aid);
+
+ /* 2. Maybe the AP wants to send multicast/broadcast data? */
+ cam |= (tim_ie->bitmap_ctrl & 0x01);
+
+ if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags))
+ rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf,
+ IEEE80211_CONF_CHANGE_PS);
+}
+
static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
struct rxdone_entry_desc *rxdesc)
{
@@ -531,6 +612,12 @@
rxdesc.flags |= RX_FLAG_HT;
/*
+ * Check if this is a beacon, and more frames have been
+ * buffered while we were in powersaving mode.
+ */
+ rt2x00lib_rxdone_check_ps(rt2x00dev, entry->skb, &rxdesc);
+
+ /*
* Update extra components
*/
rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc);
@@ -1017,6 +1104,7 @@
}
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
+ INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
/*
* Let the driver probe the device to detect the capabilities.
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 570184e..e027ebd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -170,19 +170,22 @@
__le32 reg;
struct usb_ctrlrequest cr;
struct rt2x00_dev *rt2x00dev;
- void (*callback)(struct rt2x00_dev *,int,u32);
+ bool (*callback)(struct rt2x00_dev *, int, u32);
};
static void rt2x00usb_register_read_async_cb(struct urb *urb)
{
struct rt2x00_async_read_data *rd = urb->context;
- rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg));
- kfree(urb->context);
+ if (rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg))) {
+ if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
+ kfree(rd);
+ } else
+ kfree(rd);
}
void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
- void (*callback)(struct rt2x00_dev*,int,u32))
+ bool (*callback)(struct rt2x00_dev*, int, u32))
{
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
struct urb *urb;
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 52b09d2..a69f187 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -349,10 +349,12 @@
* be called from atomic context. The callback will be called
* when the URB completes. Otherwise the function is similar
* to rt2x00usb_register_read().
+ * When the callback function returns false, the memory will be cleaned up,
+ * when it returns true, the urb will be fired again.
*/
void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
- void (*callback)(struct rt2x00_dev*,int,u32));
+ bool (*callback)(struct rt2x00_dev*, int, u32));
/*
* Radio handlers
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index a6ce7d6..ad20953 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2209,6 +2209,7 @@
if (!modparam_nohwcrypt)
__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
+ __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
/*
* Set the rssi offset.
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 367d9b4..3550c9f 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1069,7 +1069,7 @@
for (i = 0; i < entries; i++) {
nextdescaddress = (u32) dma +
- ((i + 11) % entries) *
+ ((i + 1) % entries) *
sizeof(*ring);
rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]),
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index b4b3733..06d15b6 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -46,40 +46,66 @@
if (!ccdev)
return;
bus = ccdev->bus;
+
+ /* We support SLOW only on 6..9 */
+ if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW)
+ mode = SSB_CLKMODE_DYNAMIC;
+
+ if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
+ return; /* PMU controls clockmode, separated function needed */
+ SSB_WARN_ON(ccdev->id.revision >= 20);
+
/* chipcommon cores prior to rev6 don't support dynamic clock control */
if (ccdev->id.revision < 6)
return;
- /* chipcommon cores rev10 are a whole new ball game */
+
+ /* ChipCommon cores rev10+ need testing */
if (ccdev->id.revision >= 10)
return;
+
if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
return;
switch (mode) {
- case SSB_CLKMODE_SLOW:
+ case SSB_CLKMODE_SLOW: /* For revs 6..9 only */
tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
break;
case SSB_CLKMODE_FAST:
- ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
- tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
- tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
- chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
+ if (ccdev->id.revision < 10) {
+ ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
+ tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
+ tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
+ chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
+ } else {
+ chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
+ (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) |
+ SSB_CHIPCO_SYSCLKCTL_FORCEHT));
+ /* udelay(150); TODO: not available in early init */
+ }
break;
case SSB_CLKMODE_DYNAMIC:
- tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
- tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
- if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
- tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
- chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
+ if (ccdev->id.revision < 10) {
+ tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
+ tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
+ if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=
+ SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
+ tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
+ chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
- /* for dynamic control, we have to release our xtal_pu "force on" */
- if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
- ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
+ /* For dynamic control, we have to release our xtal_pu
+ * "force on" */
+ if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
+ ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
+ } else {
+ chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
+ (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
+ ~SSB_CHIPCO_SYSCLKCTL_FORCEHT));
+ }
break;
default:
SSB_WARN_ON(1);
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index ca3c626..b510721 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -102,7 +102,8 @@
if (!ret) {
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
- if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
+ if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
+ (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
key->local->crypto_tx_tailroom_needed_cnt--;
return 0;
@@ -161,7 +162,8 @@
key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
- if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
+ if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
+ (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
key->local->crypto_tx_tailroom_needed_cnt++;
}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b04a437..81241e1 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2368,47 +2368,6 @@
return RX_QUEUED;
}
-static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr,
- struct ieee80211_rx_data *rx)
-{
- int keyidx;
- unsigned int hdrlen;
-
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
- if (rx->skb->len >= hdrlen + 4)
- keyidx = rx->skb->data[hdrlen + 3] >> 6;
- else
- keyidx = -1;
-
- if (!rx->sta) {
- /*
- * Some hardware seem to generate incorrect Michael MIC
- * reports; ignore them to avoid triggering countermeasures.
- */
- return;
- }
-
- if (!ieee80211_has_protected(hdr->frame_control))
- return;
-
- if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) {
- /*
- * APs with pairwise keys should never receive Michael MIC
- * errors for non-zero keyidx because these are reserved for
- * group keys and only the AP is sending real multicast
- * frames in the BSS.
- */
- return;
- }
-
- if (!ieee80211_is_data(hdr->frame_control) &&
- !ieee80211_is_auth(hdr->frame_control))
- return;
-
- mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL,
- GFP_ATOMIC);
-}
-
/* TODO: use IEEE80211_RX_FRAGMENTED */
static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
struct ieee80211_rate *rate)
@@ -2752,12 +2711,6 @@
if (!prepares)
return false;
- if (status->flag & RX_FLAG_MMIC_ERROR) {
- if (status->rx_flags & IEEE80211_RX_RA_MATCH)
- ieee80211_rx_michael_mic_report(hdr, rx);
- return false;
- }
-
if (!consume) {
skb = skb_copy(skb, GFP_ATOMIC);
if (!skb) {
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index f1765de..9dc3b5f 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -87,14 +87,50 @@
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- /* No way to verify the MIC if the hardware stripped it */
- if (status->flag & RX_FLAG_MMIC_STRIPPED)
+ /*
+ * it makes no sense to check for MIC errors on anything other
+ * than data frames.
+ */
+ if (!ieee80211_is_data_present(hdr->frame_control))
return RX_CONTINUE;
- if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
- !ieee80211_has_protected(hdr->frame_control) ||
- !ieee80211_is_data_present(hdr->frame_control))
+ /*
+ * No way to verify the MIC if the hardware stripped it or
+ * the IV with the key index. In this case we have solely rely
+ * on the driver to set RX_FLAG_MMIC_ERROR in the event of a
+ * MIC failure report.
+ */
+ if (status->flag & (RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED)) {
+ if (status->flag & RX_FLAG_MMIC_ERROR)
+ goto mic_fail;
+
+ if (!(status->flag & RX_FLAG_IV_STRIPPED))
+ goto update_iv;
+
return RX_CONTINUE;
+ }
+
+ /*
+ * Some hardware seems to generate Michael MIC failure reports; even
+ * though, the frame was not encrypted with TKIP and therefore has no
+ * MIC. Ignore the flag them to avoid triggering countermeasures.
+ */
+ if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP ||
+ !(status->flag & RX_FLAG_DECRYPTED))
+ return RX_CONTINUE;
+
+ if (rx->sdata->vif.type == NL80211_IFTYPE_AP && rx->key->conf.keyidx) {
+ /*
+ * APs with pairwise keys should never receive Michael MIC
+ * errors for non-zero keyidx because these are reserved for
+ * group keys and only the AP is sending real multicast
+ * frames in the BSS. (
+ */
+ return RX_DROP_UNUSABLE;
+ }
+
+ if (status->flag & RX_FLAG_MMIC_ERROR)
+ goto mic_fail;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
if (skb->len < hdrlen + MICHAEL_MIC_LEN)
@@ -102,27 +138,25 @@
data = skb->data + hdrlen;
data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
-
key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
michael_mic(key, hdr, data, data_len, mic);
- if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0) {
- if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
- return RX_DROP_UNUSABLE;
-
- mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
- (void *) skb->data, NULL,
- GFP_ATOMIC);
- return RX_DROP_UNUSABLE;
- }
+ if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0)
+ goto mic_fail;
/* remove Michael MIC from payload */
skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
+update_iv:
/* update IV in key information to be able to detect replays */
rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32;
rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16;
return RX_CONTINUE;
+
+mic_fail:
+ mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
+ (void *) skb->data, NULL, GFP_ATOMIC);
+ return RX_DROP_UNUSABLE;
}