diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-1000.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-6000.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 1 |
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 00808ee5ce2a..96a4888ea242 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 | ||
232 | static const struct iwl_ops iwl1000_ops = { | 233 | static 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 1182498c1d8f..648d53b65a78 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 | ||
408 | static struct iwl_lib_ops iwl5150_lib = { | 409 | static 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 | ||
472 | static const struct iwl_ops iwl5000_ops = { | 474 | static 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 e1959fbafd00..79ba7adbcef9 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 | ||
333 | static const struct iwl_ops iwl6000_ops = { | 334 | static 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 95666e565c77..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 | ||
@@ -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 | |||
1504 | void 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); | ||
1514 | done: | ||
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 c735a39ec176..60af54210f99 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 | ||
862 | static 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 0298642d1d75..5c46b2cd8e91 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); | |||
149 | int iwlagn_hw_nic_init(struct iwl_priv *priv); | 149 | int iwlagn_hw_nic_init(struct iwl_priv *priv); |
150 | int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); | 150 | int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); |
151 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 151 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); |
152 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | ||
152 | 153 | ||
153 | /* rx */ | 154 | /* rx */ |
154 | void iwlagn_rx_queue_restock(struct iwl_priv *priv); | 155 | void 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 db315b05f988..fcbba3d604de 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 df07a144c786..c637376a22db 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 | ||