aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c20
4 files changed, 58 insertions, 15 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 384b45c519f1..c465c8590833 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -512,10 +512,13 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv)
512 512
513 spin_unlock_irqrestore(&priv->lock, flags); 513 spin_unlock_irqrestore(&priv->lock, flags);
514 514
515 /* Allocate and init all Tx and Command queues */ 515 /* Allocate or reset and init all Tx and Command queues */
516 ret = iwlagn_txq_ctx_reset(priv); 516 if (!priv->txq) {
517 if (ret) 517 ret = iwlagn_txq_ctx_alloc(priv);
518 return ret; 518 if (ret)
519 return ret;
520 } else
521 iwlagn_txq_ctx_reset(priv);
519 522
520 set_bit(STATUS_INIT, &priv->status); 523 set_bit(STATUS_INIT, &priv->status);
521 524
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index a76e14351b5a..3077eac58880 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -809,8 +809,7 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv)
809 809
810 /* Tx queues */ 810 /* Tx queues */
811 if (priv->txq) { 811 if (priv->txq) {
812 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; 812 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
813 txq_id++)
814 if (txq_id == IWL_CMD_QUEUE_NUM) 813 if (txq_id == IWL_CMD_QUEUE_NUM)
815 iwl_cmd_queue_free(priv); 814 iwl_cmd_queue_free(priv);
816 else 815 else
@@ -825,15 +824,15 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv)
825} 824}
826 825
827/** 826/**
828 * iwlagn_txq_ctx_reset - Reset TX queue context 827 * iwlagn_txq_ctx_alloc - allocate TX queue context
829 * Destroys all DMA structures and initialize them again 828 * Allocate all Tx DMA structures and initialize them
830 * 829 *
831 * @param priv 830 * @param priv
832 * @return error code 831 * @return error code
833 */ 832 */
834int iwlagn_txq_ctx_reset(struct iwl_priv *priv) 833int iwlagn_txq_ctx_alloc(struct iwl_priv *priv)
835{ 834{
836 int ret = 0; 835 int ret;
837 int txq_id, slots_num; 836 int txq_id, slots_num;
838 unsigned long flags; 837 unsigned long flags;
839 838
@@ -891,8 +890,31 @@ int iwlagn_txq_ctx_reset(struct iwl_priv *priv)
891 return ret; 890 return ret;
892} 891}
893 892
893void iwlagn_txq_ctx_reset(struct iwl_priv *priv)
894{
895 int txq_id, slots_num;
896 unsigned long flags;
897
898 spin_lock_irqsave(&priv->lock, flags);
899
900 /* Turn off all Tx DMA fifos */
901 priv->cfg->ops->lib->txq_set_sched(priv, 0);
902
903 /* Tell NIC where to find the "keep warm" buffer */
904 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
905
906 spin_unlock_irqrestore(&priv->lock, flags);
907
908 /* Alloc and init all Tx queues, including the command queue (#4) */
909 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
910 slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
911 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
912 iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
913 }
914}
915
894/** 916/**
895 * iwlagn_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory 917 * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
896 */ 918 */
897void iwlagn_txq_ctx_stop(struct iwl_priv *priv) 919void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
898{ 920{
@@ -912,9 +934,6 @@ void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
912 1000); 934 1000);
913 } 935 }
914 spin_unlock_irqrestore(&priv->lock, flags); 936 spin_unlock_irqrestore(&priv->lock, flags);
915
916 /* Deallocate memory for all Tx queues */
917 iwlagn_hw_txq_ctx_free(priv);
918} 937}
919 938
920/* 939/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 608060abe80c..5d3142287e14 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -145,7 +145,8 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
145 struct iwl_rx_mem_buffer *rxb); 145 struct iwl_rx_mem_buffer *rxb);
146int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index); 146int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
147void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv); 147void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv);
148int iwlagn_txq_ctx_reset(struct iwl_priv *priv); 148int iwlagn_txq_ctx_alloc(struct iwl_priv *priv);
149void iwlagn_txq_ctx_reset(struct iwl_priv *priv);
149void iwlagn_txq_ctx_stop(struct iwl_priv *priv); 150void iwlagn_txq_ctx_stop(struct iwl_priv *priv);
150 151
151static inline u32 iwl_tx_status_to_mac80211(u32 status) 152static inline u32 iwl_tx_status_to_mac80211(u32 status)
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index aea6a2eee9c3..c3c6505a8c69 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -394,6 +394,26 @@ out_free_arrays:
394} 394}
395EXPORT_SYMBOL(iwl_tx_queue_init); 395EXPORT_SYMBOL(iwl_tx_queue_init);
396 396
397void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
398 int slots_num, u32 txq_id)
399{
400 int actual_slots = slots_num;
401
402 if (txq_id == IWL_CMD_QUEUE_NUM)
403 actual_slots++;
404
405 memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
406
407 txq->need_update = 0;
408
409 /* Initialize queue's high/low-water marks, and head/tail indexes */
410 iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
411
412 /* Tell device where to find queue */
413 priv->cfg->ops->lib->txq_init(priv, txq);
414}
415EXPORT_SYMBOL(iwl_tx_queue_reset);
416
397/*************** HOST COMMAND QUEUE FUNCTIONS *****/ 417/*************** HOST COMMAND QUEUE FUNCTIONS *****/
398 418
399/** 419/**