iwlwifi: add debug information on queue stop / wake
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Thu, 10 Nov 2011 14:55:24 +0000 (06:55 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 11 Nov 2011 17:32:56 +0000 (12:32 -0500)
Users complain that the traffic gets stalled sometimes. This will
allow easier debugging.

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-rx.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-debug.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
drivers/net/wireless/iwlwifi/iwl-trans.h

index f0d6d9429be76e3ee8c720acb6d8e9dcce03c811..fdb4c3786114d799dd890ca24c3b883a241a8c7e 100644 (file)
@@ -800,7 +800,8 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
                                               ctx->active.bssid_addr))
                                continue;
                        ctx->last_tx_rejected = false;
-                       iwl_trans_wake_any_queue(trans(priv), ctx->ctxid);
+                       iwl_trans_wake_any_queue(trans(priv), ctx->ctxid,
+                               "channel got active");
                }
        }
 
index b73077fc4b2c4b86c9dacf29bf1af434a6b47032..8de97f5a1825f2f5818041f1f9bf6c7e3dc0a54a 100644 (file)
@@ -844,7 +844,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                        if (ctx->last_tx_rejected) {
                                ctx->last_tx_rejected = false;
                                iwl_trans_wake_any_queue(trans(priv),
-                                                        ctx->ctxid);
+                                                        ctx->ctxid,
+                                                        "Disassoc: flush queue");
                        }
                        ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 
index 014b98ab681665fd57eea7de6536ea07165ce538..e6a02e09ee18e1115ef83986e3bfaa998ec6d383 100644 (file)
@@ -813,7 +813,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                            iwl_is_associated_ctx(ctx) && ctx->vif &&
                            ctx->vif->type == NL80211_IFTYPE_STATION) {
                                ctx->last_tx_rejected = true;
-                               iwl_trans_stop_queue(trans(priv), txq_id);
+                               iwl_trans_stop_queue(trans(priv), txq_id,
+                                       "Tx on passive channel");
 
                                IWL_DEBUG_TX_REPLY(priv,
                                           "TXQ %d status %s (0x%08x) "
index a11e7aaeb14a962dd70ec4044fa9edfb1f636998..40ef97bac1aa232139d8d4274ee46fd9e7f64398 100644 (file)
@@ -166,7 +166,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
 #define IWL_DL_11H             (1 << 28)
 #define IWL_DL_STATS           (1 << 29)
 #define IWL_DL_TX_REPLY                (1 << 30)
-#define IWL_DL_UNUSED          (1 << 31)
+#define IWL_DL_TX_QUEUES       (1 << 31)
 
 #define IWL_DEBUG_INFO(p, f, a...)     IWL_DEBUG(p, IWL_DL_INFO, f, ## a)
 #define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a)
@@ -203,7 +203,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
 #define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a)
 #define IWL_DEBUG_TX_REPLY_LIMIT(p, f, a...) \
                IWL_DEBUG_LIMIT(p, IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_UNUSED(p, f, a...)   IWL_DEBUG(p, IWL_DL_UNUSED, f, ## a)
+#define IWL_DEBUG_TX_QUEUES(p, f, a...)        IWL_DEBUG(p, IWL_DL_TX_QUEUES, f, ## a)
 #define IWL_DEBUG_RADIO(p, f, a...)    IWL_DEBUG(p, IWL_DL_RADIO, f, ## a)
 #define IWL_DEBUG_POWER(p, f, a...)    IWL_DEBUG(p, IWL_DL_POWER, f, ## a)
 #define IWL_DEBUG_11H(p, f, a...)      IWL_DEBUG(p, IWL_DL_11H, f, ## a)
index 2b6756e8b8f97578394bdfd2a473f8acd0bd95d6..afaaa2a51b966e0bb93477f03fabfbb5590f0d40 100644 (file)
@@ -355,7 +355,7 @@ static inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq)
 }
 
 static inline void iwl_wake_queue(struct iwl_trans *trans,
-                                 struct iwl_tx_queue *txq)
+                                 struct iwl_tx_queue *txq, const char *msg)
 {
        u8 queue = txq->swq_id;
        u8 ac = queue & 3;
@@ -363,13 +363,22 @@ static inline void iwl_wake_queue(struct iwl_trans *trans,
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
-       if (test_and_clear_bit(hwq, trans_pcie->queue_stopped))
-               if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0)
+       if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) {
+               if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) {
                        iwl_wake_sw_queue(priv(trans), ac);
+                       IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s",
+                                           hwq, ac, msg);
+               } else {
+                       IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d"
+                                           " stop count %d. %s",
+                                           hwq, ac, atomic_read(&trans_pcie->
+                                           queue_stop_count[ac]), msg);
+               }
+       }
 }
 
 static inline void iwl_stop_queue(struct iwl_trans *trans,
-                                 struct iwl_tx_queue *txq)
+                                 struct iwl_tx_queue *txq, const char *msg)
 {
        u8 queue = txq->swq_id;
        u8 ac = queue & 3;
@@ -377,9 +386,23 @@ static inline void iwl_stop_queue(struct iwl_trans *trans,
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
-       if (!test_and_set_bit(hwq, trans_pcie->queue_stopped))
-               if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0)
+       if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) {
+               if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) {
                        iwl_stop_sw_queue(priv(trans), ac);
+                       IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d"
+                                           " stop count %d. %s",
+                                           hwq, ac, atomic_read(&trans_pcie->
+                                           queue_stop_count[ac]), msg);
+               } else {
+                       IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d"
+                                           " stop count %d. %s",
+                                           hwq, ac, atomic_read(&trans_pcie->
+                                           queue_stop_count[ac]), msg);
+               }
+       } else {
+               IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s",
+                                   hwq, msg);
+       }
 }
 
 #ifdef ieee80211_stop_queue
index a6d898b52b9f0013311e3db195236d274ca2de26..6dba1515023c89efcc95330da663c34c336ea3fd 100644 (file)
@@ -430,7 +430,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
 
        txq->sched_retry = scd_retry;
 
-       IWL_DEBUG_INFO(trans, "%s %s Queue %d on FIFO %d\n",
+       IWL_DEBUG_TX_QUEUES(trans, "%s %s Queue %d on FIFO %d\n",
                       active ? "Activate" : "Deactivate",
                       scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
 }
@@ -561,12 +561,13 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans,
 
        tid_data = &trans->shrd->tid_data[sta_id][tid];
        if (tid_data->tfds_in_queue == 0) {
-               IWL_DEBUG_HT(trans, "HW queue is empty\n");
+               IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n");
                tid_data->agg.state = IWL_AGG_ON;
                iwl_start_tx_ba_trans_ready(priv(trans), ctx, sta_id, tid);
        } else {
-               IWL_DEBUG_HT(trans, "HW queue is NOT empty: %d packets in HW"
-                            "queue\n", tid_data->tfds_in_queue);
+               IWL_DEBUG_TX_QUEUES(trans,
+                                   "HW queue is NOT empty: %d packets in HW"
+                                   " queue\n", tid_data->tfds_in_queue);
                tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
        }
        spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);
@@ -643,14 +644,15 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans,
 
        /* The queue is not empty */
        if (write_ptr != read_ptr) {
-               IWL_DEBUG_HT(trans, "Stopping a non empty AGG HW QUEUE\n");
+               IWL_DEBUG_TX_QUEUES(trans,
+                                   "Stopping a non empty AGG HW QUEUE\n");
                trans->shrd->tid_data[sta_id][tid].agg.state =
                        IWL_EMPTYING_HW_QUEUE_DELBA;
                spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);
                return 0;
        }
 
-       IWL_DEBUG_HT(trans, "HW queue is empty\n");
+       IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n");
 turn_off:
        trans->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;
 
index da3411057afca2d9debd63bbe1f2523c650f337d..a1a58330273f71683364d4117b7a9cb13a9c58ae 100644 (file)
@@ -1231,7 +1231,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                        txq->need_update = 1;
                        iwl_txq_update_write_ptr(trans, txq);
                } else {
-                       iwl_stop_queue(trans, txq);
+                       iwl_stop_queue(trans, txq, "Queue is full");
                }
        }
        return 0;
@@ -1283,20 +1283,21 @@ static int iwlagn_txq_check_empty(struct iwl_trans *trans,
                /* aggregated HW queue */
                if ((txq_id  == tid_data->agg.txq_id) &&
                    (q->read_ptr == q->write_ptr)) {
-                       IWL_DEBUG_HT(trans,
+                       IWL_DEBUG_TX_QUEUES(trans,
                                "HW queue empty: continue DELBA flow\n");
                        iwl_trans_pcie_txq_agg_disable(trans, txq_id);
                        tid_data->agg.state = IWL_AGG_OFF;
                        iwl_stop_tx_ba_trans_ready(priv(trans),
                                                   NUM_IWL_RXON_CTX,
                                                   sta_id, tid);
-                       iwl_wake_queue(trans, &trans_pcie->txq[txq_id]);
+                       iwl_wake_queue(trans, &trans_pcie->txq[txq_id],
+                                      "DELBA flow complete");
                }
                break;
        case IWL_EMPTYING_HW_QUEUE_ADDBA:
                /* We are reclaiming the last packet of the queue */
                if (tid_data->tfds_in_queue == 0) {
-                       IWL_DEBUG_HT(trans,
+                       IWL_DEBUG_TX_QUEUES(trans,
                                "HW queue empty: continue ADDBA flow\n");
                        tid_data->agg.state = IWL_AGG_ON;
                        iwl_start_tx_ba_trans_ready(priv(trans),
@@ -1354,7 +1355,7 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
                                ssn , tfd_num, txq_id, txq->swq_id);
                freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs);
                if (iwl_queue_space(&txq->q) > txq->q.low_mark && cond)
-                       iwl_wake_queue(trans, txq);
+                       iwl_wake_queue(trans, txq, "Packets reclaimed");
        }
 
        iwl_free_tfds_in_queue(trans, sta_id, tid, freed);
@@ -1418,7 +1419,8 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
 #endif /* CONFIG_PM_SLEEP */
 
 static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans,
-                                         enum iwl_rxon_context_id ctx)
+                                         enum iwl_rxon_context_id ctx,
+                                         const char *msg)
 {
        u8 ac, txq_id;
        struct iwl_trans_pcie *trans_pcie =
@@ -1426,11 +1428,11 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans,
 
        for (ac = 0; ac < AC_NUM; ac++) {
                txq_id = trans_pcie->ac_to_queue[ctx][ac];
-               IWL_DEBUG_INFO(trans, "Queue Status: Q[%d] %s\n",
+               IWL_DEBUG_TX_QUEUES(trans, "Queue Status: Q[%d] %s\n",
                        ac,
                        (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0)
                              ? "stopped" : "awake");
-               iwl_wake_queue(trans, &trans_pcie->txq[txq_id]);
+               iwl_wake_queue(trans, &trans_pcie->txq[txq_id], msg);
        }
 }
 
@@ -1453,11 +1455,12 @@ static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd)
        return iwl_trans;
 }
 
-static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id)
+static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id,
+                                     const char *msg)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
-       iwl_stop_queue(trans, &trans_pcie->txq[txq_id]);
+       iwl_stop_queue(trans, &trans_pcie->txq[txq_id], msg);
 }
 
 #define IWL_FLUSH_WAIT_MS      2000
index 1ecdd1c2943d9954d888e360e6edb2e56beec76c..7839362b9c0bd69562d3019b877d568f0b48deba 100644 (file)
@@ -171,7 +171,8 @@ struct iwl_trans_ops {
        void (*tx_start)(struct iwl_trans *trans);
 
        void (*wake_any_queue)(struct iwl_trans *trans,
-                              enum iwl_rxon_context_id ctx);
+                              enum iwl_rxon_context_id ctx,
+                              const char *msg);
 
        int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
 
@@ -196,7 +197,7 @@ struct iwl_trans_ops {
 
        void (*free)(struct iwl_trans *trans);
 
-       void (*stop_queue)(struct iwl_trans *trans, int q);
+       void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg);
 
        int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
        int (*check_stuck_queue)(struct iwl_trans *trans, int q);
@@ -277,9 +278,10 @@ static inline void iwl_trans_tx_start(struct iwl_trans *trans)
 }
 
 static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans,
-                                           enum iwl_rxon_context_id ctx)
+                                           enum iwl_rxon_context_id ctx,
+                                           const char *msg)
 {
-       trans->ops->wake_any_queue(trans, ctx);
+       trans->ops->wake_any_queue(trans, ctx, msg);
 }
 
 
@@ -339,9 +341,10 @@ static inline void iwl_trans_free(struct iwl_trans *trans)
        trans->ops->free(trans);
 }
 
-static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q)
+static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q,
+                                       const char *msg)
 {
-       trans->ops->stop_queue(trans, q);
+       trans->ops->stop_queue(trans, q, msg);
 }
 
 static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)