aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-07-13 15:57:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-07-13 15:57:29 -0400
commite300d955debdadf599c36e47eb0bc16f5976215c (patch)
tree8fafcc789dc06e90665e6eee6388af228bbd2fd7 /drivers/net/wireless/iwlwifi
parent242647bcf8464860f173f3d4d4ab3490d3558518 (diff)
parent815868e7b5c207ba42d5b317ccc51f8112732268 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/wl12xx/wl1271_cmd.h
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c133
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c82
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c209
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h85
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h11
20 files changed, 583 insertions, 105 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 6491e27baac5..a51e4da1bdfc 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -87,10 +87,15 @@ config IWL4965
87 This option enables support for Intel Wireless WiFi Link 4965AGN 87 This option enables support for Intel Wireless WiFi Link 4965AGN
88 88
89config IWL5000 89config IWL5000
90 bool "Intel Wireless WiFi 5000AGN; Intel WiFi Link 1000, 6000, and 6050 Series" 90 bool "Intel Wireless-N/Advanced-N/Ultimate-N WiFi Link"
91 depends on IWLAGN 91 depends on IWLAGN
92 ---help--- 92 ---help---
93 This option enables support for Intel Wireless WiFi Link 5000AGN Family 93 This option enables support for use with the following hardware:
94 Intel Wireless WiFi Link 6250AGN Adapter
95 Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN)
96 Intel WiFi Link 1000BGN
97 Intel Wireless WiFi 5150AGN
98 Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN
94 99
95config IWL3945 100config IWL3945
96 tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" 101 tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 1daf159914ad..c281d07ec5e5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -129,8 +129,8 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
129 priv->cfg->num_of_queues * 129 priv->cfg->num_of_queues *
130 sizeof(struct iwlagn_scd_bc_tbl); 130 sizeof(struct iwlagn_scd_bc_tbl);
131 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 131 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
132 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 132 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
133 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 133 priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
134 134
135 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; 135 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
136 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; 136 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -226,6 +226,8 @@ static struct iwl_lib_ops iwl1000_lib = {
226 .recover_from_tx_stall = iwl_bg_monitor_recover, 226 .recover_from_tx_stall = iwl_bg_monitor_recover,
227 .check_plcp_health = iwl_good_plcp_health, 227 .check_plcp_health = iwl_good_plcp_health,
228 .check_ack_health = iwl_good_ack_health, 228 .check_ack_health = iwl_good_ack_health,
229 .txfifo_flush = iwlagn_txfifo_flush,
230 .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
229}; 231};
230 232
231static const struct iwl_ops iwl1000_ops = { 233static const struct iwl_ops iwl1000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index b8f3e20f2c80..7d89d99ce19c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -179,8 +179,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
179 priv->cfg->num_of_queues * 179 priv->cfg->num_of_queues *
180 sizeof(struct iwlagn_scd_bc_tbl); 180 sizeof(struct iwlagn_scd_bc_tbl);
181 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 181 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
182 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 182 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
183 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 183 priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
184 184
185 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; 185 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
186 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; 186 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -226,8 +226,8 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
226 priv->cfg->num_of_queues * 226 priv->cfg->num_of_queues *
227 sizeof(struct iwlagn_scd_bc_tbl); 227 sizeof(struct iwlagn_scd_bc_tbl);
228 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 228 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
229 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 229 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
230 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 230 priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
231 231
232 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; 232 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
233 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; 233 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -402,6 +402,8 @@ static struct iwl_lib_ops iwl5000_lib = {
402 .recover_from_tx_stall = iwl_bg_monitor_recover, 402 .recover_from_tx_stall = iwl_bg_monitor_recover,
403 .check_plcp_health = iwl_good_plcp_health, 403 .check_plcp_health = iwl_good_plcp_health,
404 .check_ack_health = iwl_good_ack_health, 404 .check_ack_health = iwl_good_ack_health,
405 .txfifo_flush = iwlagn_txfifo_flush,
406 .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
405}; 407};
406 408
407static struct iwl_lib_ops iwl5150_lib = { 409static struct iwl_lib_ops iwl5150_lib = {
@@ -465,6 +467,8 @@ static struct iwl_lib_ops iwl5150_lib = {
465 .recover_from_tx_stall = iwl_bg_monitor_recover, 467 .recover_from_tx_stall = iwl_bg_monitor_recover,
466 .check_plcp_health = iwl_good_plcp_health, 468 .check_plcp_health = iwl_good_plcp_health,
467 .check_ack_health = iwl_good_ack_health, 469 .check_ack_health = iwl_good_ack_health,
470 .txfifo_flush = iwlagn_txfifo_flush,
471 .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
468}; 472};
469 473
470static const struct iwl_ops iwl5000_ops = { 474static const struct iwl_ops iwl5000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 8577664da77c..095521952bbe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -160,8 +160,8 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
160 priv->cfg->num_of_queues * 160 priv->cfg->num_of_queues *
161 sizeof(struct iwlagn_scd_bc_tbl); 161 sizeof(struct iwlagn_scd_bc_tbl);
162 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 162 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
163 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 163 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
164 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 164 priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
165 165
166 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; 166 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
167 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; 167 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
@@ -327,6 +327,8 @@ static struct iwl_lib_ops iwl6000_lib = {
327 .recover_from_tx_stall = iwl_bg_monitor_recover, 327 .recover_from_tx_stall = iwl_bg_monitor_recover,
328 .check_plcp_health = iwl_good_plcp_health, 328 .check_plcp_health = iwl_good_plcp_health,
329 .check_ack_health = iwl_good_ack_health, 329 .check_ack_health = iwl_good_ack_health,
330 .txfifo_flush = iwlagn_txfifo_flush,
331 .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
330}; 332};
331 333
332static const struct iwl_ops iwl6000_ops = { 334static const struct iwl_ops iwl6000_ops = {
@@ -827,6 +829,44 @@ struct iwl_cfg iwl6050_2agn_cfg = {
827 .need_dc_calib = true, 829 .need_dc_calib = true,
828}; 830};
829 831
832struct iwl_cfg iwl6050g2_bgn_cfg = {
833 .name = "6050 Series 1x2 BGN Gen2",
834 .fw_name_pre = IWL6050_FW_PRE,
835 .ucode_api_max = IWL6050_UCODE_API_MAX,
836 .ucode_api_min = IWL6050_UCODE_API_MIN,
837 .sku = IWL_SKU_G|IWL_SKU_N,
838 .ops = &iwl6000_ops,
839 .eeprom_size = OTP_LOW_IMAGE_SIZE,
840 .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION,
841 .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION,
842 .num_of_queues = IWLAGN_NUM_QUEUES,
843 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
844 .mod_params = &iwlagn_mod_params,
845 .valid_tx_ant = ANT_A,
846 .valid_rx_ant = ANT_AB,
847 .pll_cfg_val = 0,
848 .set_l0s = true,
849 .use_bsm = false,
850 .pa_type = IWL_PA_SYSTEM,
851 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
852 .shadow_ram_support = true,
853 .ht_greenfield_support = true,
854 .led_compensation = 51,
855 .use_rts_for_ht = true, /* use rts/cts protection */
856 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
857 .supports_idle = true,
858 .adv_thermal_throttle = true,
859 .support_ct_kill_exit = true,
860 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
861 .chain_noise_scale = 1500,
862 .monitor_recover_period = IWL_MONITORING_PERIOD,
863 .max_event_log_size = 1024,
864 .ucode_tracing = true,
865 .sensitivity_calib_by_driver = true,
866 .chain_noise_calib_by_driver = true,
867 .need_dc_calib = true,
868};
869
830struct iwl_cfg iwl6050_2abg_cfg = { 870struct iwl_cfg iwl6050_2abg_cfg = {
831 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", 871 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
832 .fw_name_pre = IWL6050_FW_PRE, 872 .fw_name_pre = IWL6050_FW_PRE,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index eb052b05e790..90033e8752bb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -409,46 +409,34 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
409 return 0; 409 return 0;
410} 410}
411 411
412/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ 412static void iwl_prepare_legacy_sensitivity_tbl(struct iwl_priv *priv,
413static int iwl_sensitivity_write(struct iwl_priv *priv) 413 struct iwl_sensitivity_data *data,
414 __le16 *tbl)
414{ 415{
415 struct iwl_sensitivity_cmd cmd ; 416 tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] =
416 struct iwl_sensitivity_data *data = NULL;
417 struct iwl_host_cmd cmd_out = {
418 .id = SENSITIVITY_CMD,
419 .len = sizeof(struct iwl_sensitivity_cmd),
420 .flags = CMD_ASYNC,
421 .data = &cmd,
422 };
423
424 data = &(priv->sensitivity_data);
425
426 memset(&cmd, 0, sizeof(cmd));
427
428 cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] =
429 cpu_to_le16((u16)data->auto_corr_ofdm); 417 cpu_to_le16((u16)data->auto_corr_ofdm);
430 cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] = 418 tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] =
431 cpu_to_le16((u16)data->auto_corr_ofdm_mrc); 419 cpu_to_le16((u16)data->auto_corr_ofdm_mrc);
432 cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] = 420 tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] =
433 cpu_to_le16((u16)data->auto_corr_ofdm_x1); 421 cpu_to_le16((u16)data->auto_corr_ofdm_x1);
434 cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] = 422 tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] =
435 cpu_to_le16((u16)data->auto_corr_ofdm_mrc_x1); 423 cpu_to_le16((u16)data->auto_corr_ofdm_mrc_x1);
436 424
437 cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] = 425 tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] =
438 cpu_to_le16((u16)data->auto_corr_cck); 426 cpu_to_le16((u16)data->auto_corr_cck);
439 cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] = 427 tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] =
440 cpu_to_le16((u16)data->auto_corr_cck_mrc); 428 cpu_to_le16((u16)data->auto_corr_cck_mrc);
441 429
442 cmd.table[HD_MIN_ENERGY_CCK_DET_INDEX] = 430 tbl[HD_MIN_ENERGY_CCK_DET_INDEX] =
443 cpu_to_le16((u16)data->nrg_th_cck); 431 cpu_to_le16((u16)data->nrg_th_cck);
444 cmd.table[HD_MIN_ENERGY_OFDM_DET_INDEX] = 432 tbl[HD_MIN_ENERGY_OFDM_DET_INDEX] =
445 cpu_to_le16((u16)data->nrg_th_ofdm); 433 cpu_to_le16((u16)data->nrg_th_ofdm);
446 434
447 cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] = 435 tbl[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
448 cpu_to_le16(data->barker_corr_th_min); 436 cpu_to_le16(data->barker_corr_th_min);
449 cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] = 437 tbl[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
450 cpu_to_le16(data->barker_corr_th_min_mrc); 438 cpu_to_le16(data->barker_corr_th_min_mrc);
451 cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] = 439 tbl[HD_OFDM_ENERGY_TH_IN_INDEX] =
452 cpu_to_le16(data->nrg_th_cca); 440 cpu_to_le16(data->nrg_th_cca);
453 441
454 IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n", 442 IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
@@ -459,6 +447,25 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
459 IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n", 447 IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n",
460 data->auto_corr_cck, data->auto_corr_cck_mrc, 448 data->auto_corr_cck, data->auto_corr_cck_mrc,
461 data->nrg_th_cck); 449 data->nrg_th_cck);
450}
451
452/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
453static int iwl_sensitivity_write(struct iwl_priv *priv)
454{
455 struct iwl_sensitivity_cmd cmd;
456 struct iwl_sensitivity_data *data = NULL;
457 struct iwl_host_cmd cmd_out = {
458 .id = SENSITIVITY_CMD,
459 .len = sizeof(struct iwl_sensitivity_cmd),
460 .flags = CMD_ASYNC,
461 .data = &cmd,
462 };
463
464 data = &(priv->sensitivity_data);
465
466 memset(&cmd, 0, sizeof(cmd));
467
468 iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.table[0]);
462 469
463 /* Update uCode's "work" table, and copy it to DSP */ 470 /* Update uCode's "work" table, and copy it to DSP */
464 cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE; 471 cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
@@ -477,6 +484,70 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
477 return iwl_send_cmd(priv, &cmd_out); 484 return iwl_send_cmd(priv, &cmd_out);
478} 485}
479 486
487/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
488static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
489{
490 struct iwl_enhance_sensitivity_cmd cmd;
491 struct iwl_sensitivity_data *data = NULL;
492 struct iwl_host_cmd cmd_out = {
493 .id = SENSITIVITY_CMD,
494 .len = sizeof(struct iwl_enhance_sensitivity_cmd),
495 .flags = CMD_ASYNC,
496 .data = &cmd,
497 };
498
499 data = &(priv->sensitivity_data);
500
501 memset(&cmd, 0, sizeof(cmd));
502
503 iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]);
504
505 cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
506 HD_INA_NON_SQUARE_DET_OFDM_DATA;
507 cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
508 HD_INA_NON_SQUARE_DET_CCK_DATA;
509 cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] =
510 HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA;
511 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
512 HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA;
513 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
514 HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA;
515 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] =
516 HD_OFDM_NON_SQUARE_DET_SLOPE_DATA;
517 cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] =
518 HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA;
519 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
520 HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA;
521 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
522 HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA;
523 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] =
524 HD_CCK_NON_SQUARE_DET_SLOPE_DATA;
525 cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] =
526 HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA;
527
528 /* Update uCode's "work" table, and copy it to DSP */
529 cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
530
531 /* Don't send command to uCode if nothing has changed */
532 if (!memcmp(&cmd.enhance_table[0], &(priv->sensitivity_tbl[0]),
533 sizeof(u16)*HD_TABLE_SIZE) &&
534 !memcmp(&cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX],
535 &(priv->enhance_sensitivity_tbl[0]),
536 sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES)) {
537 IWL_DEBUG_CALIB(priv, "No change in SENSITIVITY_CMD\n");
538 return 0;
539 }
540
541 /* Copy table for comparison next time */
542 memcpy(&(priv->sensitivity_tbl[0]), &(cmd.enhance_table[0]),
543 sizeof(u16)*HD_TABLE_SIZE);
544 memcpy(&(priv->enhance_sensitivity_tbl[0]),
545 &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]),
546 sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES);
547
548 return iwl_send_cmd(priv, &cmd_out);
549}
550
480void iwl_init_sensitivity(struct iwl_priv *priv) 551void iwl_init_sensitivity(struct iwl_priv *priv)
481{ 552{
482 int ret = 0; 553 int ret = 0;
@@ -527,7 +598,10 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
527 data->last_bad_plcp_cnt_cck = 0; 598 data->last_bad_plcp_cnt_cck = 0;
528 data->last_fa_cnt_cck = 0; 599 data->last_fa_cnt_cck = 0;
529 600
530 ret |= iwl_sensitivity_write(priv); 601 if (priv->enhance_sensitivity_table)
602 ret |= iwl_enhance_sensitivity_write(priv);
603 else
604 ret |= iwl_sensitivity_write(priv);
531 IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret); 605 IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
532} 606}
533 607
@@ -633,7 +707,10 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
633 707
634 iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); 708 iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
635 iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); 709 iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
636 iwl_sensitivity_write(priv); 710 if (priv->enhance_sensitivity_table)
711 iwl_enhance_sensitivity_write(priv);
712 else
713 iwl_sensitivity_write(priv);
637} 714}
638 715
639static inline u8 find_first_chain(u8 mask) 716static inline u8 find_first_chain(u8 mask)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 5f1e7d802cbf..74623e0d535f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -205,7 +205,9 @@ void iwl_check_abort_status(struct iwl_priv *priv,
205 u8 frame_count, u32 status) 205 u8 frame_count, u32 status)
206{ 206{
207 if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { 207 if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) {
208 IWL_ERR(priv, "TODO: Implement Tx flush command!!!\n"); 208 IWL_ERR(priv, "Tx flush command to flush out all frames\n");
209 if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
210 queue_work(priv->workqueue, &priv->tx_flush);
209 } 211 }
210} 212}
211 213
@@ -1435,3 +1437,81 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
1435 priv->stations[sta_id].tid[tid].tfds_in_queue = 0; 1437 priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
1436 } 1438 }
1437} 1439}
1440
1441#define IWL_FLUSH_WAIT_MS 2000
1442
1443int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv)
1444{
1445 struct iwl_tx_queue *txq;
1446 struct iwl_queue *q;
1447 int cnt;
1448 unsigned long now = jiffies;
1449 int ret = 0;
1450
1451 /* waiting for all the tx frames complete might take a while */
1452 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
1453 if (cnt == IWL_CMD_QUEUE_NUM)
1454 continue;
1455 txq = &priv->txq[cnt];
1456 q = &txq->q;
1457 while (q->read_ptr != q->write_ptr && !time_after(jiffies,
1458 now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS)))
1459 msleep(1);
1460
1461 if (q->read_ptr != q->write_ptr) {
1462 IWL_ERR(priv, "fail to flush all tx fifo queues\n");
1463 ret = -ETIMEDOUT;
1464 break;
1465 }
1466 }
1467 return ret;
1468}
1469
1470#define IWL_TX_QUEUE_MSK 0xfffff
1471
1472/**
1473 * iwlagn_txfifo_flush: send REPLY_TXFIFO_FLUSH command to uCode
1474 *
1475 * pre-requirements:
1476 * 1. acquire mutex before calling
1477 * 2. make sure rf is on and not in exit state
1478 */
1479int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
1480{
1481 struct iwl_txfifo_flush_cmd flush_cmd;
1482 struct iwl_host_cmd cmd = {
1483 .id = REPLY_TXFIFO_FLUSH,
1484 .len = sizeof(struct iwl_txfifo_flush_cmd),
1485 .flags = CMD_SYNC,
1486 .data = &flush_cmd,
1487 };
1488
1489 might_sleep();
1490
1491 memset(&flush_cmd, 0, sizeof(flush_cmd));
1492 flush_cmd.fifo_control = IWL_TX_FIFO_VO_MSK | IWL_TX_FIFO_VI_MSK |
1493 IWL_TX_FIFO_BE_MSK | IWL_TX_FIFO_BK_MSK;
1494 if (priv->cfg->sku & IWL_SKU_N)
1495 flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
1496
1497 IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
1498 flush_cmd.fifo_control);
1499 flush_cmd.flush_control = cpu_to_le16(flush_control);
1500
1501 return iwl_send_cmd(priv, &cmd);
1502}
1503
1504void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
1505{
1506 mutex_lock(&priv->mutex);
1507 ieee80211_stop_queues(priv->hw);
1508 if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) {
1509 IWL_ERR(priv, "flush request fail\n");
1510 goto done;
1511 }
1512 IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n");
1513 iwlagn_wait_tx_queue_empty(priv);
1514done:
1515 ieee80211_wake_queues(priv->hw);
1516 mutex_unlock(&priv->mutex);
1517}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 2573234e4db1..55a1b31fd09a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -950,9 +950,12 @@ void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
950 /* Stop each Tx DMA channel, and wait for it to be idle */ 950 /* Stop each Tx DMA channel, and wait for it to be idle */
951 for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { 951 for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
952 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); 952 iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
953 iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, 953 if (iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
954 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 954 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
955 1000); 955 1000))
956 IWL_ERR(priv, "Failing on timeout while stopping"
957 " DMA channel %d [0x%08x]", ch,
958 iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG));
956 } 959 }
957 spin_unlock_irqrestore(&priv->lock, flags); 960 spin_unlock_irqrestore(&priv->lock, flags);
958} 961}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3368cfd25a99..7391c63fb024 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -859,6 +859,24 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
859 return 0; 859 return 0;
860} 860}
861 861
862static void iwl_bg_tx_flush(struct work_struct *work)
863{
864 struct iwl_priv *priv =
865 container_of(work, struct iwl_priv, tx_flush);
866
867 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
868 return;
869
870 /* do nothing if rf-kill is on */
871 if (!iwl_is_ready_rf(priv))
872 return;
873
874 if (priv->cfg->ops->lib->txfifo_flush) {
875 IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
876 iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
877 }
878}
879
862/** 880/**
863 * iwl_setup_rx_handlers - Initialize Rx handler callbacks 881 * iwl_setup_rx_handlers - Initialize Rx handler callbacks
864 * 882 *
@@ -1806,12 +1824,21 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1806 const u8 *data; 1824 const u8 *data;
1807 int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp; 1825 int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp;
1808 u64 alternatives; 1826 u64 alternatives;
1827 u32 tlv_len;
1828 enum iwl_ucode_tlv_type tlv_type;
1829 const u8 *tlv_data;
1830 int ret = 0;
1809 1831
1810 if (len < sizeof(*ucode)) 1832 if (len < sizeof(*ucode)) {
1833 IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
1811 return -EINVAL; 1834 return -EINVAL;
1835 }
1812 1836
1813 if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) 1837 if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
1838 IWL_ERR(priv, "invalid uCode magic: 0X%x\n",
1839 le32_to_cpu(ucode->magic));
1814 return -EINVAL; 1840 return -EINVAL;
1841 }
1815 1842
1816 /* 1843 /*
1817 * Check which alternatives are present, and "downgrade" 1844 * Check which alternatives are present, and "downgrade"
@@ -1836,11 +1863,9 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1836 1863
1837 len -= sizeof(*ucode); 1864 len -= sizeof(*ucode);
1838 1865
1839 while (len >= sizeof(*tlv)) { 1866 while (len >= sizeof(*tlv) && !ret) {
1840 u32 tlv_len;
1841 enum iwl_ucode_tlv_type tlv_type;
1842 u16 tlv_alt; 1867 u16 tlv_alt;
1843 const u8 *tlv_data; 1868 u32 fixed_tlv_size = 4;
1844 1869
1845 len -= sizeof(*tlv); 1870 len -= sizeof(*tlv);
1846 tlv = (void *)data; 1871 tlv = (void *)data;
@@ -1850,8 +1875,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1850 tlv_alt = le16_to_cpu(tlv->alternative); 1875 tlv_alt = le16_to_cpu(tlv->alternative);
1851 tlv_data = tlv->data; 1876 tlv_data = tlv->data;
1852 1877
1853 if (len < tlv_len) 1878 if (len < tlv_len) {
1879 IWL_ERR(priv, "invalid TLV len: %zd/%u\n",
1880 len, tlv_len);
1854 return -EINVAL; 1881 return -EINVAL;
1882 }
1855 len -= ALIGN(tlv_len, 4); 1883 len -= ALIGN(tlv_len, 4);
1856 data += sizeof(*tlv) + ALIGN(tlv_len, 4); 1884 data += sizeof(*tlv) + ALIGN(tlv_len, 4);
1857 1885
@@ -1885,56 +1913,77 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1885 pieces->boot_size = tlv_len; 1913 pieces->boot_size = tlv_len;
1886 break; 1914 break;
1887 case IWL_UCODE_TLV_PROBE_MAX_LEN: 1915 case IWL_UCODE_TLV_PROBE_MAX_LEN:
1888 if (tlv_len != 4) 1916 if (tlv_len != fixed_tlv_size)
1889 return -EINVAL; 1917 ret = -EINVAL;
1890 capa->max_probe_length = 1918 else
1891 le32_to_cpup((__le32 *)tlv_data); 1919 capa->max_probe_length =
1920 le32_to_cpup((__le32 *)tlv_data);
1892 break; 1921 break;
1893 case IWL_UCODE_TLV_INIT_EVTLOG_PTR: 1922 case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
1894 if (tlv_len != 4) 1923 if (tlv_len != fixed_tlv_size)
1895 return -EINVAL; 1924 ret = -EINVAL;
1896 pieces->init_evtlog_ptr = 1925 else
1897 le32_to_cpup((__le32 *)tlv_data); 1926 pieces->init_evtlog_ptr =
1927 le32_to_cpup((__le32 *)tlv_data);
1898 break; 1928 break;
1899 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: 1929 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
1900 if (tlv_len != 4) 1930 if (tlv_len != fixed_tlv_size)
1901 return -EINVAL; 1931 ret = -EINVAL;
1902 pieces->init_evtlog_size = 1932 else
1903 le32_to_cpup((__le32 *)tlv_data); 1933 pieces->init_evtlog_size =
1934 le32_to_cpup((__le32 *)tlv_data);
1904 break; 1935 break;
1905 case IWL_UCODE_TLV_INIT_ERRLOG_PTR: 1936 case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
1906 if (tlv_len != 4) 1937 if (tlv_len != fixed_tlv_size)
1907 return -EINVAL; 1938 ret = -EINVAL;
1908 pieces->init_errlog_ptr = 1939 else
1909 le32_to_cpup((__le32 *)tlv_data); 1940 pieces->init_errlog_ptr =
1941 le32_to_cpup((__le32 *)tlv_data);
1910 break; 1942 break;
1911 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: 1943 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
1912 if (tlv_len != 4) 1944 if (tlv_len != fixed_tlv_size)
1913 return -EINVAL; 1945 ret = -EINVAL;
1914 pieces->inst_evtlog_ptr = 1946 else
1915 le32_to_cpup((__le32 *)tlv_data); 1947 pieces->inst_evtlog_ptr =
1948 le32_to_cpup((__le32 *)tlv_data);
1916 break; 1949 break;
1917 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: 1950 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
1918 if (tlv_len != 4) 1951 if (tlv_len != fixed_tlv_size)
1919 return -EINVAL; 1952 ret = -EINVAL;
1920 pieces->inst_evtlog_size = 1953 else
1921 le32_to_cpup((__le32 *)tlv_data); 1954 pieces->inst_evtlog_size =
1955 le32_to_cpup((__le32 *)tlv_data);
1922 break; 1956 break;
1923 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: 1957 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
1924 if (tlv_len != 4) 1958 if (tlv_len != fixed_tlv_size)
1925 return -EINVAL; 1959 ret = -EINVAL;
1926 pieces->inst_errlog_ptr = 1960 else
1927 le32_to_cpup((__le32 *)tlv_data); 1961 pieces->inst_errlog_ptr =
1962 le32_to_cpup((__le32 *)tlv_data);
1963 break;
1964 case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
1965 if (tlv_len)
1966 ret = -EINVAL;
1967 else
1968 priv->enhance_sensitivity_table = true;
1928 break; 1969 break;
1929 default: 1970 default:
1971 IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
1930 break; 1972 break;
1931 } 1973 }
1932 } 1974 }
1933 1975
1934 if (len) 1976 if (len) {
1935 return -EINVAL; 1977 IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
1978 iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
1979 ret = -EINVAL;
1980 } else if (ret) {
1981 IWL_ERR(priv, "TLV %d has invalid size: %u\n",
1982 tlv_type, tlv_len);
1983 iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)tlv_data, tlv_len);
1984 }
1936 1985
1937 return 0; 1986 return ret;
1938} 1987}
1939 1988
1940/** 1989/**
@@ -2247,17 +2296,41 @@ static const char *desc_lookup_text[] = {
2247 "DEBUG_1", 2296 "DEBUG_1",
2248 "DEBUG_2", 2297 "DEBUG_2",
2249 "DEBUG_3", 2298 "DEBUG_3",
2250 "ADVANCED SYSASSERT"
2251}; 2299};
2252 2300
2253static const char *desc_lookup(int i) 2301static struct { char *name; u8 num; } advanced_lookup[] = {
2302 { "NMI_INTERRUPT_WDG", 0x34 },
2303 { "SYSASSERT", 0x35 },
2304 { "UCODE_VERSION_MISMATCH", 0x37 },
2305 { "BAD_COMMAND", 0x38 },
2306 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
2307 { "FATAL_ERROR", 0x3D },
2308 { "NMI_TRM_HW_ERR", 0x46 },
2309 { "NMI_INTERRUPT_TRM", 0x4C },
2310 { "NMI_INTERRUPT_BREAK_POINT", 0x54 },
2311 { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
2312 { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
2313 { "NMI_INTERRUPT_HOST", 0x66 },
2314 { "NMI_INTERRUPT_ACTION_PT", 0x7C },
2315 { "NMI_INTERRUPT_UNKNOWN", 0x84 },
2316 { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
2317 { "ADVANCED_SYSASSERT", 0 },
2318};
2319
2320static const char *desc_lookup(u32 num)
2254{ 2321{
2255 int max = ARRAY_SIZE(desc_lookup_text) - 1; 2322 int i;
2323 int max = ARRAY_SIZE(desc_lookup_text);
2256 2324
2257 if (i < 0 || i > max) 2325 if (num < max)
2258 i = max; 2326 return desc_lookup_text[num];
2259 2327
2260 return desc_lookup_text[i]; 2328 max = ARRAY_SIZE(advanced_lookup) - 1;
2329 for (i = 0; i < max; i++) {
2330 if (advanced_lookup[i].num == num)
2331 break;;
2332 }
2333 return advanced_lookup[i].name;
2261} 2334}
2262 2335
2263#define ERROR_START_OFFSET (1 * sizeof(u32)) 2336#define ERROR_START_OFFSET (1 * sizeof(u32))
@@ -3614,6 +3687,44 @@ out_exit:
3614 IWL_DEBUG_MAC80211(priv, "leave\n"); 3687 IWL_DEBUG_MAC80211(priv, "leave\n");
3615} 3688}
3616 3689
3690static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop)
3691{
3692 struct iwl_priv *priv = hw->priv;
3693
3694 mutex_lock(&priv->mutex);
3695 IWL_DEBUG_MAC80211(priv, "enter\n");
3696
3697 /* do not support "flush" */
3698 if (!priv->cfg->ops->lib->txfifo_flush)
3699 goto done;
3700
3701 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
3702 IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n");
3703 goto done;
3704 }
3705 if (iwl_is_rfkill(priv)) {
3706 IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n");
3707 goto done;
3708 }
3709
3710 /*
3711 * mac80211 will not push any more frames for transmit
3712 * until the flush is completed
3713 */
3714 if (drop) {
3715 IWL_DEBUG_MAC80211(priv, "send flush command\n");
3716 if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) {
3717 IWL_ERR(priv, "flush request fail\n");
3718 goto done;
3719 }
3720 }
3721 IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
3722 iwlagn_wait_tx_queue_empty(priv);
3723done:
3724 mutex_unlock(&priv->mutex);
3725 IWL_DEBUG_MAC80211(priv, "leave\n");
3726}
3727
3617/***************************************************************************** 3728/*****************************************************************************
3618 * 3729 *
3619 * driver setup and teardown 3730 * driver setup and teardown
@@ -3630,6 +3741,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3630 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); 3741 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
3631 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); 3742 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
3632 INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); 3743 INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
3744 INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
3633 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); 3745 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
3634 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); 3746 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
3635 3747
@@ -3787,6 +3899,7 @@ static struct ieee80211_ops iwl_hw_ops = {
3787 .sta_add = iwlagn_mac_sta_add, 3899 .sta_add = iwlagn_mac_sta_add,
3788 .sta_remove = iwl_mac_sta_remove, 3900 .sta_remove = iwl_mac_sta_remove,
3789 .channel_switch = iwl_mac_channel_switch, 3901 .channel_switch = iwl_mac_channel_switch,
3902 .flush = iwl_mac_flush,
3790}; 3903};
3791 3904
3792static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3905static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -4234,6 +4347,14 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
4234 {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)}, 4347 {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)},
4235 {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)}, 4348 {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)},
4236 4349
4350/* 6x50 WiFi/WiMax Series Gen2 */
4351 {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6050g2_bgn_cfg)},
4352 {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6050g2_bgn_cfg)},
4353 {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6050g2_bgn_cfg)},
4354 {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6050g2_bgn_cfg)},
4355 {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6050g2_bgn_cfg)},
4356 {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6050g2_bgn_cfg)},
4357
4237/* 1000 Series WiFi */ 4358/* 1000 Series WiFi */
4238 {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, 4359 {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)},
4239 {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)}, 4360 {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index be9d298cae2c..cc6464dc72e5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -89,6 +89,7 @@ extern struct iwl_cfg iwl6000i_2bg_cfg;
89extern struct iwl_cfg iwl6000_3agn_cfg; 89extern struct iwl_cfg iwl6000_3agn_cfg;
90extern struct iwl_cfg iwl6050_2agn_cfg; 90extern struct iwl_cfg iwl6050_2agn_cfg;
91extern struct iwl_cfg iwl6050_2abg_cfg; 91extern struct iwl_cfg iwl6050_2abg_cfg;
92extern struct iwl_cfg iwl6050g2_bgn_cfg;
92extern struct iwl_cfg iwl1000_bgn_cfg; 93extern struct iwl_cfg iwl1000_bgn_cfg;
93extern struct iwl_cfg iwl1000_bg_cfg; 94extern struct iwl_cfg iwl1000_bg_cfg;
94 95
@@ -147,6 +148,9 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
147void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 148void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
148int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 149int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
149int iwlagn_hw_nic_init(struct iwl_priv *priv); 150int iwlagn_hw_nic_init(struct iwl_priv *priv);
151int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
152int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
153void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
150 154
151/* rx */ 155/* rx */
152void iwlagn_rx_queue_restock(struct iwl_priv *priv); 156void iwlagn_rx_queue_restock(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index acf8e980b1fe..8d2db9d22045 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -97,6 +97,7 @@ enum {
97 REPLY_ADD_STA = 0x18, 97 REPLY_ADD_STA = 0x18,
98 REPLY_REMOVE_STA = 0x19, 98 REPLY_REMOVE_STA = 0x19,
99 REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ 99 REPLY_REMOVE_ALL_STA = 0x1a, /* not used */
100 REPLY_TXFIFO_FLUSH = 0x1e,
100 101
101 /* Security */ 102 /* Security */
102 REPLY_WEPKEY = 0x20, 103 REPLY_WEPKEY = 0x20,
@@ -957,8 +958,8 @@ struct iwl_qosparam_cmd {
957#define IWL3945_STATION_COUNT 25 958#define IWL3945_STATION_COUNT 25
958#define IWL4965_BROADCAST_ID 31 959#define IWL4965_BROADCAST_ID 31
959#define IWL4965_STATION_COUNT 32 960#define IWL4965_STATION_COUNT 32
960#define IWL5000_BROADCAST_ID 15 961#define IWLAGN_BROADCAST_ID 15
961#define IWL5000_STATION_COUNT 16 962#define IWLAGN_STATION_COUNT 16
962 963
963#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ 964#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
964#define IWL_INVALID_STATION 255 965#define IWL_INVALID_STATION 255
@@ -1209,6 +1210,43 @@ struct iwl_rem_sta_cmd {
1209 u8 reserved2[2]; 1210 u8 reserved2[2];
1210} __packed; 1211} __packed;
1211 1212
1213#define IWL_TX_FIFO_BK_MSK cpu_to_le32(BIT(0))
1214#define IWL_TX_FIFO_BE_MSK cpu_to_le32(BIT(1))
1215#define IWL_TX_FIFO_VI_MSK cpu_to_le32(BIT(2))
1216#define IWL_TX_FIFO_VO_MSK cpu_to_le32(BIT(3))
1217#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00)
1218
1219#define IWL_DROP_SINGLE 0
1220#define IWL_DROP_SELECTED 1
1221#define IWL_DROP_ALL 2
1222
1223/*
1224 * REPLY_TXFIFO_FLUSH = 0x1e(command and response)
1225 *
1226 * When using full FIFO flush this command checks the scheduler HW block WR/RD
1227 * pointers to check if all the frames were transferred by DMA into the
1228 * relevant TX FIFO queue. Only when the DMA is finished and the queue is
1229 * empty the command can finish.
1230 * This command is used to flush the TXFIFO from transmit commands, it may
1231 * operate on single or multiple queues, the command queue can't be flushed by
1232 * this command. The command response is returned when all the queue flush
1233 * operations are done. Each TX command flushed return response with the FLUSH
1234 * status set in the TX response status. When FIFO flush operation is used,
1235 * the flush operation ends when both the scheduler DMA done and TXFIFO empty
1236 * are set.
1237 *
1238 * @fifo_control: bit mask for which queues to flush
1239 * @flush_control: flush controls
1240 * 0: Dump single MSDU
1241 * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable.
1242 * 2: Dump all FIFO
1243 */
1244struct iwl_txfifo_flush_cmd {
1245 __le32 fifo_control;
1246 __le16 flush_control;
1247 __le16 reserved;
1248} __attribute__ ((packed));
1249
1212/* 1250/*
1213 * REPLY_WEP_KEY = 0x20 1251 * REPLY_WEP_KEY = 0x20
1214 */ 1252 */
@@ -3452,6 +3490,41 @@ struct iwl_missed_beacon_notif {
3452#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) 3490#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9)
3453#define HD_OFDM_ENERGY_TH_IN_INDEX (10) 3491#define HD_OFDM_ENERGY_TH_IN_INDEX (10)
3454 3492
3493/*
3494 * Additional table entries in enhance SENSITIVITY_CMD
3495 */
3496#define HD_INA_NON_SQUARE_DET_OFDM_INDEX (11)
3497#define HD_INA_NON_SQUARE_DET_CCK_INDEX (12)
3498#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX (13)
3499#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX (14)
3500#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX (15)
3501#define HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX (16)
3502#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX (17)
3503#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX (18)
3504#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX (19)
3505#define HD_CCK_NON_SQUARE_DET_SLOPE_INDEX (20)
3506#define HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX (21)
3507#define HD_RESERVED (22)
3508
3509/* number of entries for enhanced tbl */
3510#define ENHANCE_HD_TABLE_SIZE (23)
3511
3512/* number of additional entries for enhanced tbl */
3513#define ENHANCE_HD_TABLE_ENTRIES (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE)
3514
3515#define HD_INA_NON_SQUARE_DET_OFDM_DATA cpu_to_le16(0)
3516#define HD_INA_NON_SQUARE_DET_CCK_DATA cpu_to_le16(0)
3517#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA cpu_to_le16(0)
3518#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA cpu_to_le16(668)
3519#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA cpu_to_le16(4)
3520#define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA cpu_to_le16(486)
3521#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA cpu_to_le16(37)
3522#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA cpu_to_le16(853)
3523#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA cpu_to_le16(4)
3524#define HD_CCK_NON_SQUARE_DET_SLOPE_DATA cpu_to_le16(476)
3525#define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA cpu_to_le16(99)
3526
3527
3455/* Control field in struct iwl_sensitivity_cmd */ 3528/* Control field in struct iwl_sensitivity_cmd */
3456#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE cpu_to_le16(0) 3529#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE cpu_to_le16(0)
3457#define SENSITIVITY_CMD_CONTROL_WORK_TABLE cpu_to_le16(1) 3530#define SENSITIVITY_CMD_CONTROL_WORK_TABLE cpu_to_le16(1)
@@ -3468,6 +3541,14 @@ struct iwl_sensitivity_cmd {
3468 __le16 table[HD_TABLE_SIZE]; /* use HD_* as index */ 3541 __le16 table[HD_TABLE_SIZE]; /* use HD_* as index */
3469} __packed; 3542} __packed;
3470 3543
3544/*
3545 *
3546 */
3547struct iwl_enhance_sensitivity_cmd {
3548 __le16 control; /* always use "1" */
3549 __le16 enhance_table[ENHANCE_HD_TABLE_SIZE]; /* use HD_* as index */
3550} __attribute__ ((packed));
3551
3471 3552
3472/** 3553/**
3473 * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response) 3554 * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index a56fb466d0b6..f73eb08a9494 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2627,7 +2627,7 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
2627} 2627}
2628 2628
2629 2629
2630int iwl_force_reset(struct iwl_priv *priv, int mode) 2630int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
2631{ 2631{
2632 struct iwl_force_reset *force_reset; 2632 struct iwl_force_reset *force_reset;
2633 2633
@@ -2640,12 +2640,14 @@ int iwl_force_reset(struct iwl_priv *priv, int mode)
2640 } 2640 }
2641 force_reset = &priv->force_reset[mode]; 2641 force_reset = &priv->force_reset[mode];
2642 force_reset->reset_request_count++; 2642 force_reset->reset_request_count++;
2643 if (force_reset->last_force_reset_jiffies && 2643 if (!external) {
2644 time_after(force_reset->last_force_reset_jiffies + 2644 if (force_reset->last_force_reset_jiffies &&
2645 force_reset->reset_duration, jiffies)) { 2645 time_after(force_reset->last_force_reset_jiffies +
2646 IWL_DEBUG_INFO(priv, "force reset rejected\n"); 2646 force_reset->reset_duration, jiffies)) {
2647 force_reset->reset_reject_count++; 2647 IWL_DEBUG_INFO(priv, "force reset rejected\n");
2648 return -EAGAIN; 2648 force_reset->reset_reject_count++;
2649 return -EAGAIN;
2650 }
2649 } 2651 }
2650 force_reset->reset_success_count++; 2652 force_reset->reset_success_count++;
2651 force_reset->last_force_reset_jiffies = jiffies; 2653 force_reset->last_force_reset_jiffies = jiffies;
@@ -2655,6 +2657,19 @@ int iwl_force_reset(struct iwl_priv *priv, int mode)
2655 iwl_force_rf_reset(priv); 2657 iwl_force_rf_reset(priv);
2656 break; 2658 break;
2657 case IWL_FW_RESET: 2659 case IWL_FW_RESET:
2660 /*
2661 * if the request is from external(ex: debugfs),
2662 * then always perform the request in regardless the module
2663 * parameter setting
2664 * if the request is from internal (uCode error or driver
2665 * detect failure), then fw_restart module parameter
2666 * need to be check before performing firmware reload
2667 */
2668 if (!external && !priv->cfg->mod_params->restart_fw) {
2669 IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
2670 "module parameter setting\n");
2671 break;
2672 }
2658 IWL_ERR(priv, "On demand firmware reload\n"); 2673 IWL_ERR(priv, "On demand firmware reload\n");
2659 /* Set the FW error flag -- cleared on iwl_down */ 2674 /* Set the FW error flag -- cleared on iwl_down */
2660 set_bit(STATUS_FW_ERROR, &priv->status); 2675 set_bit(STATUS_FW_ERROR, &priv->status);
@@ -2713,7 +2728,7 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
2713 "queue %d stuck %d time. Fw reload.\n", 2728 "queue %d stuck %d time. Fw reload.\n",
2714 q->id, q->repeat_same_read_ptr); 2729 q->id, q->repeat_same_read_ptr);
2715 q->repeat_same_read_ptr = 0; 2730 q->repeat_same_read_ptr = 0;
2716 iwl_force_reset(priv, IWL_FW_RESET); 2731 iwl_force_reset(priv, IWL_FW_RESET, false);
2717 } else { 2732 } else {
2718 q->repeat_same_read_ptr++; 2733 q->repeat_same_read_ptr++;
2719 IWL_DEBUG_RADIO(priv, 2734 IWL_DEBUG_RADIO(priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 15930e064022..fcbba3d604de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -205,6 +205,9 @@ struct iwl_lib_ops {
205 /* check for ack health */ 205 /* check for ack health */
206 bool (*check_ack_health)(struct iwl_priv *priv, 206 bool (*check_ack_health)(struct iwl_priv *priv,
207 struct iwl_rx_packet *pkt); 207 struct iwl_rx_packet *pkt);
208 int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
209 void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
210
208 struct iwl_debugfs_ops debugfs_ops; 211 struct iwl_debugfs_ops debugfs_ops;
209}; 212};
210 213
@@ -525,7 +528,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
525 struct cfg80211_scan_request *req); 528 struct cfg80211_scan_request *req);
526void iwl_bg_start_internal_scan(struct work_struct *work); 529void iwl_bg_start_internal_scan(struct work_struct *work);
527void iwl_internal_short_hw_scan(struct iwl_priv *priv); 530void iwl_internal_short_hw_scan(struct iwl_priv *priv);
528int iwl_force_reset(struct iwl_priv *priv, int mode); 531int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
529u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, 532u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
530 const u8 *ta, const u8 *ie, int ie_len, int left); 533 const u8 *ta, const u8 *ie, int ie_len, int left);
531void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); 534void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 254c35ae8b38..ecf98e7ac4ed 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -298,6 +298,7 @@
298#define CSR_HW_REV_TYPE_1000 (0x0000060) 298#define CSR_HW_REV_TYPE_1000 (0x0000060)
299#define CSR_HW_REV_TYPE_6x00 (0x0000070) 299#define CSR_HW_REV_TYPE_6x00 (0x0000070)
300#define CSR_HW_REV_TYPE_6x50 (0x0000080) 300#define CSR_HW_REV_TYPE_6x50 (0x0000080)
301#define CSR_HW_REV_TYPE_6x50g2 (0x0000084)
301#define CSR_HW_REV_TYPE_6x00g2 (0x00000B0) 302#define CSR_HW_REV_TYPE_6x00g2 (0x00000B0)
302#define CSR_HW_REV_TYPE_NONE (0x00000F0) 303#define CSR_HW_REV_TYPE_NONE (0x00000F0)
303 304
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 7d9ffc1575de..088a2c13f59b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1487,7 +1487,7 @@ static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
1487 switch (reset) { 1487 switch (reset) {
1488 case IWL_RF_RESET: 1488 case IWL_RF_RESET:
1489 case IWL_FW_RESET: 1489 case IWL_FW_RESET:
1490 ret = iwl_force_reset(priv, reset); 1490 ret = iwl_force_reset(priv, reset, true);
1491 break; 1491 break;
1492 default: 1492 default:
1493 return -EINVAL; 1493 return -EINVAL;
@@ -1495,6 +1495,30 @@ static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
1495 return ret ? ret : count; 1495 return ret ? ret : count;
1496} 1496}
1497 1497
1498static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
1499 const char __user *user_buf,
1500 size_t count, loff_t *ppos) {
1501
1502 struct iwl_priv *priv = file->private_data;
1503 char buf[8];
1504 int buf_size;
1505 int flush;
1506
1507 memset(buf, 0, sizeof(buf));
1508 buf_size = min(count, sizeof(buf) - 1);
1509 if (copy_from_user(buf, user_buf, buf_size))
1510 return -EFAULT;
1511 if (sscanf(buf, "%d", &flush) != 1)
1512 return -EINVAL;
1513
1514 if (iwl_is_rfkill(priv))
1515 return -EFAULT;
1516
1517 priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL);
1518
1519 return count;
1520}
1521
1498DEBUGFS_READ_FILE_OPS(rx_statistics); 1522DEBUGFS_READ_FILE_OPS(rx_statistics);
1499DEBUGFS_READ_FILE_OPS(tx_statistics); 1523DEBUGFS_READ_FILE_OPS(tx_statistics);
1500DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 1524DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1516,6 +1540,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
1516DEBUGFS_READ_WRITE_FILE_OPS(force_reset); 1540DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1517DEBUGFS_READ_FILE_OPS(rxon_flags); 1541DEBUGFS_READ_FILE_OPS(rxon_flags);
1518DEBUGFS_READ_FILE_OPS(rxon_filter_flags); 1542DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
1543DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
1519 1544
1520/* 1545/*
1521 * Create the debugfs files and directories 1546 * Create the debugfs files and directories
@@ -1574,6 +1599,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1574 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); 1599 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1575 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); 1600 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1576 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); 1601 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1602 if (priv->cfg->ops->lib->dev_txfifo_flush)
1603 DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
1577 1604
1578 if (priv->cfg->sensitivity_calib_by_driver) 1605 if (priv->cfg->sensitivity_calib_by_driver)
1579 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); 1606 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 728752aa1bb5..c4dba62b74af 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -570,6 +570,7 @@ enum iwl_ucode_tlv_type {
570 IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, 570 IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11,
571 IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, 571 IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12,
572 IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, 572 IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
573 IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14,
573}; 574};
574 575
575struct iwl_ucode_tlv { 576struct iwl_ucode_tlv {
@@ -1193,7 +1194,9 @@ struct iwl_priv {
1193 u8 start_calib; 1194 u8 start_calib;
1194 struct iwl_sensitivity_data sensitivity_data; 1195 struct iwl_sensitivity_data sensitivity_data;
1195 struct iwl_chain_noise_data chain_noise_data; 1196 struct iwl_chain_noise_data chain_noise_data;
1197 bool enhance_sensitivity_table;
1196 __le16 sensitivity_tbl[HD_TABLE_SIZE]; 1198 __le16 sensitivity_tbl[HD_TABLE_SIZE];
1199 __le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES];
1197 1200
1198 struct iwl_ht_config current_ht_config; 1201 struct iwl_ht_config current_ht_config;
1199 1202
@@ -1345,6 +1348,7 @@ struct iwl_priv {
1345 struct work_struct ct_enter; 1348 struct work_struct ct_enter;
1346 struct work_struct ct_exit; 1349 struct work_struct ct_exit;
1347 struct work_struct start_internal_scan; 1350 struct work_struct start_internal_scan;
1351 struct work_struct tx_flush;
1348 1352
1349 struct tasklet_struct irq_tasklet; 1353 struct tasklet_struct irq_tasklet;
1350 1354
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 5488006491a2..3452dfa7b571 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -276,6 +276,10 @@ struct iwl_eeprom_enhanced_txpwr {
276#define EEPROM_6050_TX_POWER_VERSION (4) 276#define EEPROM_6050_TX_POWER_VERSION (4)
277#define EEPROM_6050_EEPROM_VERSION (0x532) 277#define EEPROM_6050_EEPROM_VERSION (0x532)
278 278
279/* 6x50g2 Specific */
280#define EEPROM_6050G2_TX_POWER_VERSION (6)
281#define EEPROM_6050G2_EEPROM_VERSION (0x553)
282
279/* 6x00g2 Specific */ 283/* 6x00g2 Specific */
280#define EEPROM_6000G2_TX_POWER_VERSION (6) 284#define EEPROM_6000G2_TX_POWER_VERSION (6)
281#define EEPROM_6000G2_EEPROM_VERSION (0x709) 285#define EEPROM_6000G2_EEPROM_VERSION (0x709)
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index a3fcbb5f2c70..55b8370bc6d4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -398,12 +398,7 @@
398 */ 398 */
399#define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018) 399#define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018)
400 400
401#define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24) 401#define FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_chnl) ((1 << (_chnl)) << 16)
402#define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16)
403
404#define FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_chnl) \
405 (FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) | \
406 FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl))
407 402
408/* Tx service channels */ 403/* Tx service channels */
409#define FH_SRVC_CHNL (9) 404#define FH_SRVC_CHNL (9)
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 51f89e7ba681..258d059ef41f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -49,6 +49,7 @@ const char *get_cmd_string(u8 cmd)
49 IWL_CMD(REPLY_ADD_STA); 49 IWL_CMD(REPLY_ADD_STA);
50 IWL_CMD(REPLY_REMOVE_STA); 50 IWL_CMD(REPLY_REMOVE_STA);
51 IWL_CMD(REPLY_REMOVE_ALL_STA); 51 IWL_CMD(REPLY_REMOVE_ALL_STA);
52 IWL_CMD(REPLY_TXFIFO_FLUSH);
52 IWL_CMD(REPLY_WEPKEY); 53 IWL_CMD(REPLY_WEPKEY);
53 IWL_CMD(REPLY_3945_RX); 54 IWL_CMD(REPLY_3945_RX);
54 IWL_CMD(REPLY_TX); 55 IWL_CMD(REPLY_TX);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index b437f317b979..79773e353baa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -238,7 +238,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
238 */ 238 */
239 IWL_ERR(priv, "low ack count detected, " 239 IWL_ERR(priv, "low ack count detected, "
240 "restart firmware\n"); 240 "restart firmware\n");
241 if (!iwl_force_reset(priv, IWL_FW_RESET)) 241 if (!iwl_force_reset(priv, IWL_FW_RESET, false))
242 return; 242 return;
243 } 243 }
244 } 244 }
@@ -249,7 +249,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
249 * high plcp error detected 249 * high plcp error detected
250 * reset Radio 250 * reset Radio
251 */ 251 */
252 iwl_force_reset(priv, IWL_RF_RESET); 252 iwl_force_reset(priv, IWL_RF_RESET, false);
253 } 253 }
254 } 254 }
255 } 255 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index ba95b1a590a5..d38a350ba0bd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -98,6 +98,17 @@ static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
98 spin_lock_irqsave(&priv->sta_lock, flags); 98 spin_lock_irqsave(&priv->sta_lock, flags);
99 memset(priv->stations, 0, sizeof(priv->stations)); 99 memset(priv->stations, 0, sizeof(priv->stations));
100 priv->num_stations = 0; 100 priv->num_stations = 0;
101
102 /*
103 * Remove all key information that is not stored as part of station
104 * information since mac80211 may not have had a
105 * chance to remove all the keys. When device is reconfigured by
106 * mac80211 after an error all keys will be reconfigured.
107 */
108 priv->ucode_key_table = 0;
109 priv->key_mapping_key = 0;
110 memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
111
101 spin_unlock_irqrestore(&priv->sta_lock, flags); 112 spin_unlock_irqrestore(&priv->sta_lock, flags);
102} 113}
103 114