iwlagn: add an API for TX stop
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Fri, 8 Jul 2011 15:46:12 +0000 (08:46 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 11 Jul 2011 19:02:01 +0000 (15:02 -0400)
Tx stop moves to transport layer.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-trans.c
drivers/net/wireless/iwlwifi/iwl-tx.c

index 25a592a656a4e6e7f8349de233f46de8dc1b3dd4..a926142f470f560d2c4e5af4f6c2718f4eebcb13 100644 (file)
@@ -2310,7 +2310,7 @@ void iwlagn_stop_device(struct iwl_priv *priv)
         * already dead.
         */
        if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
-               iwlagn_txq_ctx_stop(priv);
+               priv->trans.ops->tx_stop(priv);
                priv->trans.ops->rx_stop(priv);
 
                /* Power-down device's busmaster DMA clocks */
index c90c78a081dd37f5a7c87778897d3e7ce2f81310..f29b31d73be6826d59f5b983cd7e67d844ec20a9 100644 (file)
@@ -851,39 +851,6 @@ static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv,
        memset(ptr, 0, sizeof(*ptr));
 }
 
-/**
- * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
- */
-void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
-{
-       int ch, txq_id;
-       unsigned long flags;
-
-       /* Turn off all Tx DMA fifos */
-       spin_lock_irqsave(&priv->lock, flags);
-
-       iwlagn_txq_set_sched(priv, 0);
-
-       /* Stop each Tx DMA channel, and wait for it to be idle */
-       for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
-               iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
-               if (iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
-                                   FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
-                                   1000))
-                       IWL_ERR(priv, "Failing on timeout while stopping"
-                           " DMA channel %d [0x%08x]", ch,
-                           iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG));
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       if (!priv->txq)
-               return;
-
-       /* Unmap DMA from host system and free skb's */
-       for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
-               iwl_tx_queue_unmap(priv, txq_id);
-}
-
 /*
  * Find first available (lowest unused) Tx Queue, mark it "active".
  * Called only when finding queue for aggregation.
index 0fa379b4f46b42afe3f5ab68247ab0baca54d2e7..ff0b2ed712373e84dc094d984460f3fa695d8281 100644 (file)
@@ -217,7 +217,6 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
 void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
                                struct iwl_rx_mem_buffer *rxb);
 int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
-void iwlagn_txq_ctx_stop(struct iwl_priv *priv);
 
 static inline u32 iwl_tx_status_to_mac80211(u32 status)
 {
index 7d8be6b26acd18d40adce3849767aa62fdc93a56..76f65350ebc30f3035ae29f60886a8b6c4b9db31 100644 (file)
@@ -384,7 +384,6 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success);
 void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
                          int count, int slots_num, u32 id);
-void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id);
 void iwl_setup_watchdog(struct iwl_priv *priv);
 /*****************************************************
  * TX power
index 8611cf0e555652db7b6ba1caa9cbefa4e04fa045..85e4fa3503710ae48cd875567c19b677f0fea778 100644 (file)
@@ -694,8 +694,6 @@ struct iwl_hw_params {
  ****************************************************************************/
 extern void iwl_update_chain_flags(struct iwl_priv *priv);
 extern const u8 iwl_bcast_addr[ETH_ALEN];
-extern int iwl_rxq_stop(struct iwl_priv *priv);
-extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
 extern int iwl_queue_space(const struct iwl_queue *q);
 static inline int iwl_queue_used(const struct iwl_queue *q, int i)
 {
@@ -1234,6 +1232,7 @@ struct iwl_trans;
  * @rx_stop: stop the rx
  * @rx_free: frees the rx memory
  * @tx_init:inits the tx memory, allocate if needed
+ * @tx_stop: stop the tx
  * @tx_free: frees the tx memory
  */
 struct iwl_trans_ops {
@@ -1242,6 +1241,7 @@ struct iwl_trans_ops {
        void (*rx_free)(struct iwl_priv *priv);
 
        int (*tx_init)(struct iwl_priv *priv);
+       int (*tx_stop)(struct iwl_priv *priv);
        void (*tx_free)(struct iwl_priv *priv);
 };
 
index c4cd363d81f2f028ec17cb81716b16698eb5bb46..81716fdd593aa13fa3c1cea8e397184c41e477e5 100644 (file)
@@ -327,6 +327,24 @@ static int iwl_trans_txq_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
        return 0;
 }
 
+/**
+ * iwl_tx_queue_unmap -  Unmap any remaining DMA mappings and free skb's
+ */
+static void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id)
+{
+       struct iwl_tx_queue *txq = &priv->txq[txq_id];
+       struct iwl_queue *q = &txq->q;
+
+       if (!q->n_bd)
+               return;
+
+       while (q->write_ptr != q->read_ptr) {
+               /* The read_ptr needs to bound by q->n_window */
+               iwlagn_txq_free_tfd(priv, txq, get_cmd_index(q, q->read_ptr));
+               q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
+       }
+}
+
 /**
  * iwl_tx_queue_free - Deallocate DMA queue.
  * @txq: Transmit queue to deallocate.
@@ -497,12 +515,50 @@ error:
        return ret;
 }
 
+/**
+ * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
+ */
+static int iwl_trans_tx_stop(struct iwl_priv *priv)
+{
+       int ch, txq_id;
+       unsigned long flags;
+
+       /* Turn off all Tx DMA fifos */
+       spin_lock_irqsave(&priv->lock, flags);
+
+       iwlagn_txq_set_sched(priv, 0);
+
+       /* Stop each Tx DMA channel, and wait for it to be idle */
+       for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
+               iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
+               if (iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
+                                   FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
+                                   1000))
+                       IWL_ERR(priv, "Failing on timeout while stopping"
+                           " DMA channel %d [0x%08x]", ch,
+                           iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG));
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       if (!priv->txq) {
+               IWL_WARN(priv, "Stopping tx queues that aren't allocated...");
+               return 0;
+       }
+
+       /* Unmap DMA from host system and free skb's */
+       for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
+               iwl_tx_queue_unmap(priv, txq_id);
+
+       return 0;
+}
+
 static const struct iwl_trans_ops trans_ops = {
        .rx_init = iwl_trans_rx_init,
        .rx_stop = iwl_trans_rx_stop,
        .rx_free = iwl_trans_rx_free,
 
        .tx_init = iwl_trans_tx_init,
+       .tx_stop = iwl_trans_tx_stop,
        .tx_free = iwl_trans_tx_free,
 };
 
index 36b643a385be123dd9c543dd19095f03f1deb6db..b62d03235b8c4e662e420d4539d5fcc42e955a3f 100644 (file)
@@ -221,23 +221,6 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv,
        return 0;
 }
 
-/**
- * iwl_tx_queue_unmap -  Unmap any remaining DMA mappings and free skb's
- */
-void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id)
-{
-       struct iwl_tx_queue *txq = &priv->txq[txq_id];
-       struct iwl_queue *q = &txq->q;
-
-       if (q->n_bd == 0)
-               return;
-
-        while (q->write_ptr != q->read_ptr) {
-               iwlagn_txq_free_tfd(priv, txq, get_cmd_index(q, q->read_ptr));
-               q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
-       }
-}
-
 /*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
  * DMA services
  *