aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h1
8 files changed, 44 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 00808ee5ce2..96a4888ea24 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -227,6 +227,7 @@ static struct iwl_lib_ops iwl1000_lib = {
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, 229 .txfifo_flush = iwlagn_txfifo_flush,
230 .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
230}; 231};
231 232
232static 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 1182498c1d8..648d53b65a7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -403,6 +403,7 @@ static struct iwl_lib_ops iwl5000_lib = {
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, 405 .txfifo_flush = iwlagn_txfifo_flush,
406 .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
406}; 407};
407 408
408static struct iwl_lib_ops iwl5150_lib = { 409static struct iwl_lib_ops iwl5150_lib = {
@@ -467,6 +468,7 @@ static struct iwl_lib_ops iwl5150_lib = {
467 .check_plcp_health = iwl_good_plcp_health, 468 .check_plcp_health = iwl_good_plcp_health,
468 .check_ack_health = iwl_good_ack_health, 469 .check_ack_health = iwl_good_ack_health,
469 .txfifo_flush = iwlagn_txfifo_flush, 470 .txfifo_flush = iwlagn_txfifo_flush,
471 .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
470}; 472};
471 473
472static 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 e1959fbafd0..79ba7adbcef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -328,6 +328,7 @@ static struct iwl_lib_ops iwl6000_lib = {
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, 330 .txfifo_flush = iwlagn_txfifo_flush,
331 .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
331}; 332};
332 333
333static const struct iwl_ops iwl6000_ops = { 334static const struct iwl_ops iwl6000_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 95666e565c7..74623e0d535 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
@@ -1498,3 +1500,18 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
1498 1500
1499 return iwl_send_cmd(priv, &cmd); 1501 return iwl_send_cmd(priv, &cmd);
1500} 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.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c735a39ec17..60af54210f9 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 *
@@ -3693,6 +3711,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3693 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); 3711 INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
3694 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); 3712 INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
3695 INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); 3713 INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
3714 INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
3696 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); 3715 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
3697 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); 3716 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
3698 3717
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 0298642d1d7..5c46b2cd8e9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -149,6 +149,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
149int iwlagn_hw_nic_init(struct iwl_priv *priv); 149int iwlagn_hw_nic_init(struct iwl_priv *priv);
150int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); 150int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
151int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); 151int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
152void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
152 153
153/* rx */ 154/* rx */
154void iwlagn_rx_queue_restock(struct iwl_priv *priv); 155void iwlagn_rx_queue_restock(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index db315b05f98..fcbba3d604d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -206,6 +206,7 @@ struct iwl_lib_ops {
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); 208 int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
209 void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
209 210
210 struct iwl_debugfs_ops debugfs_ops; 211 struct iwl_debugfs_ops debugfs_ops;
211}; 212};
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index df07a144c78..c637376a22d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1345,6 +1345,7 @@ struct iwl_priv {
1345 struct work_struct ct_enter; 1345 struct work_struct ct_enter;
1346 struct work_struct ct_exit; 1346 struct work_struct ct_exit;
1347 struct work_struct start_internal_scan; 1347 struct work_struct start_internal_scan;
1348 struct work_struct tx_flush;
1348 1349
1349 struct tasklet_struct irq_tasklet; 1350 struct tasklet_struct irq_tasklet;
1350 1351