]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ath11k: Supporting RX ring backpressure HTT event and stats handling
authorSriram R <srirrama@codeaurora.org>
Mon, 16 Mar 2020 09:28:40 +0000 (14:58 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Wed, 18 Mar 2020 11:43:54 +0000 (13:43 +0200)
The Firmware sends HTT event to host whenever there is a
backpressure on RX rings, Handling such event and dumping
info on the console under the "ATH11K_DBG_DP_HTT"  debug level.

Fetching RX ring backpressure histogram from FW via htt_stats debugfs.

 #echo "24" > /sys/kernel/debug/ath11k/ipq8074/macX/htt_stats_type
 #cat /sys/kernel/debug/ath11k/ipq8074/macX/htt_stats

Signed-off-by: Vikas Patel <vikpatel@codeaurora.org>
Signed-off-by: Sriram R <srirrama@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/ath11k/debug.h
drivers/net/wireless/ath/ath11k/debug_htt_stats.c
drivers/net/wireless/ath/ath11k/debug_htt_stats.h
drivers/net/wireless/ath/ath11k/dp.h
drivers/net/wireless/ath/ath11k/dp_rx.c

index 427d3ac5c909be90af0f5edc11252828abc6a9ef..97e7306c506d9eb1d9f6739612d6b8156c820809 100644 (file)
@@ -53,6 +53,8 @@ enum ath11k_dbg_htt_ext_stats_type {
        ATH11K_DBG_HTT_EXT_STATS_TWT_SESSIONS               =  20,
        ATH11K_DBG_HTT_EXT_STATS_REO_RESOURCE_STATS         =  21,
        ATH11K_DBG_HTT_EXT_STATS_TX_SOUNDING_INFO           =  22,
+       ATH11K_DBG_HTT_EXT_STATS_PDEV_OBSS_PD_STATS         =  23,
+       ATH11K_DBG_HTT_EXT_STATS_RING_BACKPRESSURE_STATS    =  24,
 
        /* keep this last */
        ATH11K_DBG_HTT_NUM_EXT_STATS,
index f44dec839e70818669965cf7b7c83ca8751f735f..5db0c27de4753ecf68f92a26f2763252d47dd5b0 100644 (file)
@@ -3854,6 +3854,47 @@ htt_print_pdev_obss_pd_stats_tlv_v(const void *tag_buf,
        stats_req->buf_len = len;
 }
 
+static inline void htt_print_backpressure_stats_tlv_v(const u32 *tag_buf,
+                                                     u8 *data)
+{
+       struct debug_htt_stats_req *stats_req =
+                       (struct debug_htt_stats_req *)data;
+       struct htt_ring_backpressure_stats_tlv *htt_stats_buf =
+                       (struct htt_ring_backpressure_stats_tlv *)tag_buf;
+       int i;
+       u8 *buf = stats_req->buf;
+       u32 len = stats_req->buf_len;
+       u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
+
+       len += HTT_DBG_OUT(buf + len, buf_len - len, "pdev_id = %u",
+                          htt_stats_buf->pdev_id);
+       len += HTT_DBG_OUT(buf + len, buf_len - len, "current_head_idx = %u",
+                          htt_stats_buf->current_head_idx);
+       len += HTT_DBG_OUT(buf + len, buf_len - len, "current_tail_idx = %u",
+                          htt_stats_buf->current_tail_idx);
+       len += HTT_DBG_OUT(buf + len, buf_len - len, "num_htt_msgs_sent = %u",
+                          htt_stats_buf->num_htt_msgs_sent);
+       len += HTT_DBG_OUT(buf + len, buf_len - len,
+                          "backpressure_time_ms = %u",
+                          htt_stats_buf->backpressure_time_ms);
+
+       for (i = 0; i < 5; i++)
+               len += HTT_DBG_OUT(buf + len, buf_len - len,
+                                  "backpressure_hist_%u = %u",
+                                  i + 1, htt_stats_buf->backpressure_hist[i]);
+
+       len += HTT_DBG_OUT(buf + len, buf_len - len,
+                          "============================");
+
+       if (len >= buf_len) {
+               buf[buf_len - 1] = 0;
+               stats_req->buf_len = buf_len - 1;
+       } else {
+               buf[len] = 0;
+               stats_req->buf_len = len;
+       }
+}
+
 static inline void htt_htt_stats_debug_dump(const u32 *tag_buf,
                                            struct debug_htt_stats_req *stats_req)
 {
@@ -4246,6 +4287,9 @@ static int ath11k_dbg_htt_ext_stats_parse(struct ath11k_base *ab,
        case HTT_STATS_PDEV_OBSS_PD_TAG:
                htt_print_pdev_obss_pd_stats_tlv_v(tag_buf, stats_req);
                break;
+       case HTT_STATS_RING_BACKPRESSURE_STATS_TAG:
+               htt_print_backpressure_stats_tlv_v(tag_buf, user_data);
+               break;
        default:
                break;
        }
index 4bdb62dd7b8dcb467edd02a4e0b72757ee0a599d..23a6baa9e95a2e9c7f3f845a41bf5bb765080c41 100644 (file)
@@ -100,6 +100,8 @@ enum htt_tlv_tag_t {
        HTT_STATS_SCHED_TXQ_SCHED_ORDER_SU_TAG              = 86,
        HTT_STATS_SCHED_TXQ_SCHED_INELIGIBILITY_TAG         = 87,
        HTT_STATS_PDEV_OBSS_PD_TAG                          = 88,
+       HTT_STATS_HW_WAR_TAG                                = 89,
+       HTT_STATS_RING_BACKPRESSURE_STATS_TAG               = 90,
 
        HTT_STATS_MAX_TAG,
 };
@@ -1659,4 +1661,30 @@ struct htt_pdev_obss_pd_stats_tlv {
 };
 
 void ath11k_debug_htt_stats_init(struct ath11k *ar);
+
+struct htt_ring_backpressure_stats_tlv {
+       u32 pdev_id;
+       u32 current_head_idx;
+       u32 current_tail_idx;
+       u32 num_htt_msgs_sent;
+       /* Time in milliseconds for which the ring has been in
+        * its current backpressure condition
+        */
+       u32 backpressure_time_ms;
+       /* backpressure_hist - histogram showing how many times
+        * different degrees of backpressure duration occurred:
+        * Index 0 indicates the number of times ring was
+        * continuously in backpressure state for 100 - 200ms.
+        * Index 1 indicates the number of times ring was
+        * continuously in backpressure state for 200 - 300ms.
+        * Index 2 indicates the number of times ring was
+        * continuously in backpressure state for 300 - 400ms.
+        * Index 3 indicates the number of times ring was
+        * continuously in backpressure state for 400 - 500ms.
+        * Index 4 indicates the number of times ring was
+        * continuously in backpressure state beyond 500ms.
+        */
+       u32 backpressure_hist[5];
+};
+
 #endif
index ed11728478e970d24aeb398017ab0fff76144221..f504077086da512c66be5b39fc223339fe1ba69f 100644 (file)
@@ -936,6 +936,7 @@ enum htt_t2h_msg_type {
        HTT_T2H_MSG_TYPE_PEER_UNMAP     = 0x1f,
        HTT_T2H_MSG_TYPE_PPDU_STATS_IND = 0x1d,
        HTT_T2H_MSG_TYPE_EXT_STATS_CONF = 0x1c,
+       HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND = 0x24,
 };
 
 #define HTT_TARGET_VERSION_MAJOR 3
@@ -984,6 +985,13 @@ struct htt_resp_msg {
        };
 } __packed;
 
+#define HTT_BACKPRESSURE_EVENT_PDEV_ID_M GENMASK(15, 8)
+#define HTT_BACKPRESSURE_EVENT_RING_TYPE_M GENMASK(23, 16)
+#define HTT_BACKPRESSURE_EVENT_RING_ID_M GENMASK(31, 24)
+
+#define HTT_BACKPRESSURE_EVENT_HP_M GENMASK(15, 0)
+#define HTT_BACKPRESSURE_EVENT_TP_M GENMASK(31, 16)
+
 /* ppdu stats
  *
  * @details
index 320fec2aede36740af8ac8525d45a8e2b895671c..61ff9a9a32cffb79f61812a6dd9ef69b94baa9b6 100644 (file)
@@ -1499,6 +1499,29 @@ static void ath11k_htt_pktlog(struct ath11k_base *ab, struct sk_buff *skb)
        trace_ath11k_htt_pktlog(ar, data->payload, hdr->size);
 }
 
+static void ath11k_htt_backpressure_event_handler(struct ath11k_base *ab,
+                                                 struct sk_buff *skb)
+{
+       u32 *data = (u32 *)skb->data;
+       u8 pdev_id, ring_type, ring_id;
+       u16 hp, tp;
+       u32 backpressure_time;
+
+       pdev_id = FIELD_GET(HTT_BACKPRESSURE_EVENT_PDEV_ID_M, *data);
+       ring_type = FIELD_GET(HTT_BACKPRESSURE_EVENT_RING_TYPE_M, *data);
+       ring_id = FIELD_GET(HTT_BACKPRESSURE_EVENT_RING_ID_M, *data);
+       ++data;
+
+       hp = FIELD_GET(HTT_BACKPRESSURE_EVENT_HP_M, *data);
+       tp = FIELD_GET(HTT_BACKPRESSURE_EVENT_TP_M, *data);
+       ++data;
+
+       backpressure_time = *data;
+
+       ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt backpressure event, pdev %d, ring type %d,ring id %d, hp %d tp %d, backpressure time %d\n",
+                  pdev_id, ring_type, ring_id, hp, tp, backpressure_time);
+}
+
 void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab,
                                       struct sk_buff *skb)
 {
@@ -1548,6 +1571,9 @@ void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab,
        case HTT_T2H_MSG_TYPE_PKTLOG:
                ath11k_htt_pktlog(ab, skb);
                break;
+       case HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND:
+               ath11k_htt_backpressure_event_handler(ab, skb);
+               break;
        default:
                ath11k_warn(ab, "htt event %d not handled\n", type);
                break;