From 466f147d05c180309d7c4fdbd7a5afcd6c389232 Mon Sep 17 00:00:00 2001 From: Shivani Soni Date: Thu, 13 Aug 2020 12:32:09 +0530 Subject: [PATCH] qcacmn: Debugfs support for HTT stats Debugfs support for HTT stats under compile time flag "HTT_STATS_DEBUGFS_SUPPORT". Change-Id: I44c4f11265fdb3b9d53a9ac545e2945854bb9a57 CRs-Fixed: 2760947 --- dp/wifi3.0/dp_htt.c | 61 ++++++++++++++++++++++++++++++++++---- dp/wifi3.0/dp_internal.h | 64 ++++++++++++++++++++++++++++++++++++++++ dp/wifi3.0/dp_main.c | 25 +++++++++++----- dp/wifi3.0/dp_types.h | 42 +++++++++++++++++++++++++- 4 files changed, 178 insertions(+), 14 deletions(-) diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 3203cf4bec..1ad9c2a1ff 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -1950,6 +1950,47 @@ dp_send_htt_stat_resp(struct htt_stats_context *htt_stats, return QDF_STATUS_E_NOSUPPORT; } #endif + +#ifdef HTT_STATS_DEBUGFS_SUPPORT +/* dp_send_htt_stats_dbgfs_msg() - Function to send htt data to upper layer + * @pdev: dp pdev handle + * @msg_word: HTT msg + * @msg_len: Length of HTT msg sent + * + * Return: none + */ +static inline void +dp_htt_stats_dbgfs_send_msg(struct dp_pdev *pdev, uint32_t *msg_word, + uint32_t msg_len) +{ + struct htt_dbgfs_cfg dbgfs_cfg; + int done = 0; + + /* send 5th word of HTT msg to upper layer */ + dbgfs_cfg.msg_word = (msg_word + 4); + dbgfs_cfg.m = pdev->dbgfs_cfg->m; + msg_len = qdf_min(msg_len, (uint32_t)DP_EXT_MSG_LENGTH); + + if (pdev->dbgfs_cfg->htt_stats_dbgfs_msg_process) + pdev->dbgfs_cfg->htt_stats_dbgfs_msg_process(&dbgfs_cfg, + (msg_len + 4)); + + /* Get TLV Done bit from 4th msg word */ + done = HTT_T2H_EXT_STATS_CONF_TLV_DONE_GET(*(msg_word + 3)); + if (done) { + if (qdf_event_set(&pdev->dbgfs_cfg->htt_stats_dbgfs_event)) + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Failed to set event for debugfs htt stats"); + } +} +#else +static inline void +dp_htt_stats_dbgfs_send_msg(struct dp_pdev *pdev, uint32_t *msg_word, + uint32_t msg_len) +{ +} +#endif /* HTT_STATS_DEBUGFS_SUPPORT */ + /** * dp_process_htt_stat_msg(): Process the list of buffers of HTT EXT stats * @htt_stats: htt stats info @@ -1981,8 +2022,8 @@ static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats, uint32_t msg_remain_len = 0; uint32_t tlv_remain_len = 0; uint32_t *tlv_start; - int cookie_val; - int cookie_msb; + int cookie_val = 0; + int cookie_msb = 0; int pdev_id; bool copy_stats = false; struct dp_pdev *pdev; @@ -2007,10 +2048,16 @@ static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats, pdev_id = *(msg_word + 2) & HTT_PID_BIT_MASK; pdev = soc->pdev_list[pdev_id]; - if (cookie_msb >> 2) { - copy_stats = true; + if (!cookie_val && (cookie_msb & DBG_STATS_COOKIE_HTT_DBGFS)) { + dp_htt_stats_dbgfs_send_msg(pdev, msg_word, + htt_stats->msg_len); + qdf_nbuf_free(htt_msg); + continue; } + if (cookie_msb & DBG_STATS_COOKIE_DP_STATS) + copy_stats = true; + /* read 5th word */ msg_word = msg_word + 4; msg_remain_len = qdf_min(htt_stats->msg_len, @@ -5011,8 +5058,10 @@ QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev, /* word 7 */ msg_word++; *msg_word = 0; - /*Using last 2 bits for pdev_id */ - cookie_msb = ((cookie_msb << 2) | pdev->pdev_id); + /* Currently Using last 2 bits for pdev_id + * For future reference, reserving 3 bits in cookie_msb for pdev_id + */ + cookie_msb = (cookie_msb | pdev->pdev_id); HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, cookie_msb); pkt = htt_htc_pkt_alloc(soc); diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 0ba04c0859..9330b77f5b 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -40,6 +40,28 @@ /* Macro For NYSM value received in VHT TLV */ #define VHT_SGI_NYSM 3 +/* struct htt_dbgfs_cfg - structure to maintain required htt data + * @msg_word: htt msg sent to upper layer + * @m: qdf debugfs file pointer + */ +struct htt_dbgfs_cfg { + uint32_t *msg_word; + qdf_debugfs_file_t m; +}; + +/* Cookie MSB bits assigned for different use case. + * Note: User can't use last 3 bits, as it is reserved for pdev_id. + * If in future number of pdev are more than 3. + */ +/* Reserve for default case */ +#define DBG_STATS_COOKIE_DEFAULT 0x0 + +/* Reserve for DP Stats: 3rd bit */ +#define DBG_STATS_COOKIE_DP_STATS 0x8 + +/* Reserve for HTT Stats debugfs support: 4th bit */ +#define DBG_STATS_COOKIE_HTT_DBGFS 0x10 + /** * Bitmap of HTT PPDU TLV types for Default mode */ @@ -2329,4 +2351,46 @@ dp_hmwds_ast_add_notify(struct dp_peer *peer, { } #endif + +#ifdef HTT_STATS_DEBUGFS_SUPPORT +/* dp_pdev_htt_stats_dbgfs_init() - Function to allocate memory and initialize + * debugfs for HTT stats + * @pdev: dp pdev handle + * + * Return: QDF_STATUS + */ +QDF_STATUS dp_pdev_htt_stats_dbgfs_init(struct dp_pdev *pdev); + +/* dp_pdev_htt_stats_dbgfs_deinit() - Function to remove debugfs entry for + * HTT stats + * @pdev: dp pdev handle + * + * Return: none + */ +void dp_pdev_htt_stats_dbgfs_deinit(struct dp_pdev *pdev); +#else + +/* dp_pdev_htt_stats_dbgfs_init() - Function to allocate memory and initialize + * debugfs for HTT stats + * @pdev: dp pdev handle + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +dp_pdev_htt_stats_dbgfs_init(struct dp_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} + +/* dp_pdev_htt_stats_dbgfs_deinit() - Function to remove debugfs entry for + * HTT stats + * @pdev: dp pdev handle + * + * Return: none + */ +static inline void +dp_pdev_htt_stats_dbgfs_deinit(struct dp_pdev *pdev) +{ +} +#endif /* HTT_STATS_DEBUGFS_SUPPORT */ #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 4c945d93e2..20739a441e 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4250,6 +4250,8 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force) if (pdev->filter) dp_mon_filter_dealloc(pdev); + dp_pdev_htt_stats_dbgfs_deinit(pdev); + dp_pdev_srng_deinit(pdev); dp_ipa_uc_detach(pdev->soc, pdev); @@ -8141,14 +8143,14 @@ dp_get_fw_peer_stats(struct cdp_soc_t *soc, uint8_t pdev_id, dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO, config_param0, config_param1, config_param2, config_param3, - 0, 1, 0); + 0, DBG_STATS_COOKIE_DP_STATS, 0); qdf_wait_single_event(&pdev->fw_peer_stats_event, DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC); } else { dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PEER_INFO, config_param0, config_param1, config_param2, config_param3, - 0, 0, 0); + 0, DBG_STATS_COOKIE_DEFAULT, 0); } return QDF_STATUS_SUCCESS; @@ -8191,7 +8193,7 @@ dp_get_htt_stats(struct cdp_soc_t *soc, uint8_t pdev_id, void *data, dp_h2t_ext_stats_msg_send(pdev, req->stats_id, req->config_param0, req->config_param1, req->config_param2, req->config_param3, - req->cookie, 0, 0); + req->cookie, DBG_STATS_COOKIE_DEFAULT, 0); return QDF_STATUS_SUCCESS; } @@ -9175,7 +9177,7 @@ dp_txrx_stats_publish(struct cdp_soc_t *soc, uint8_t pdev_id, dp_aggregate_pdev_stats(pdev); req.stats = (enum cdp_stats)HTT_DBG_EXT_STATS_PDEV_TX; - req.cookie_val = 1; + req.cookie_val = DBG_STATS_COOKIE_DP_STATS; dp_h2t_ext_stats_msg_send(pdev, req.stats, req.param0, req.param1, req.param2, req.param3, 0, req.cookie_val, 0); @@ -9183,7 +9185,7 @@ dp_txrx_stats_publish(struct cdp_soc_t *soc, uint8_t pdev_id, msleep(DP_MAX_SLEEP_TIME); req.stats = (enum cdp_stats)HTT_DBG_EXT_STATS_PDEV_RX; - req.cookie_val = 1; + req.cookie_val = DBG_STATS_COOKIE_DP_STATS; dp_h2t_ext_stats_msg_send(pdev, req.stats, req.param0, req.param1, req.param2, req.param3, 0, req.cookie_val, 0); @@ -9272,11 +9274,12 @@ static int dp_fw_stats_process(struct dp_vdev *vdev, return dp_h2t_ext_stats_msg_send(pdev, HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT, req->param0, req->param1, req->param2, - req->param3, 0, 0, mac_id); + req->param3, 0, DBG_STATS_COOKIE_DEFAULT, + mac_id); } else { return dp_h2t_ext_stats_msg_send(pdev, stats, req->param0, req->param1, req->param2, req->param3, - 0, 0, mac_id); + 0, DBG_STATS_COOKIE_DEFAULT, mac_id); } } @@ -13176,6 +13179,12 @@ static inline QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc, goto fail9; } + if (dp_pdev_htt_stats_dbgfs_init(pdev)) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "Failed to initialize pdev HTT stats debugfs"); + goto fail10; + } + /* initialize sw rx descriptors */ dp_rx_pdev_desc_pool_init(pdev); /* initialize sw monitor rx descriptors */ @@ -13194,6 +13203,8 @@ static inline QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc, qdf_skb_mem_stats_read()); return QDF_STATUS_SUCCESS; +fail10: + dp_rx_fst_detach(soc, pdev); fail9: dp_ipa_uc_detach(soc, pdev); fail8: diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 78a3e2faf0..f6b9eab0ac 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -28,7 +28,7 @@ #include #include #include - +#include #include #ifdef DP_MOB_DEFS #include @@ -1717,6 +1717,42 @@ struct dp_rx_mon_enh_trailer_data { }; #endif /* WLAN_RX_PKT_CAPTURE_ENH */ +#ifdef HTT_STATS_DEBUGFS_SUPPORT +/* Number of debugfs entries created for HTT stats */ +#define PDEV_HTT_STATS_DBGFS_SIZE HTT_DBG_NUM_EXT_STATS + +/* struct pdev_htt_stats_dbgfs_priv - Structure to maintain debugfs information + * of HTT stats + * @pdev: dp pdev of debugfs entry + * @stats_id: stats id of debugfs entry + */ +struct pdev_htt_stats_dbgfs_priv { + struct dp_pdev *pdev; + uint16_t stats_id; +}; + +/* struct pdev_htt_stats_dbgfs_cfg - PDEV level data structure for debugfs + * support for HTT stats + * @debugfs_entry: qdf_debugfs directory entry + * @m: qdf debugfs file handler + * @pdev_htt_stats_dbgfs_ops: File operations of entry created + * @priv: HTT stats debugfs private object + * @htt_stats_dbgfs_event: HTT stats event for debugfs support + * @lock: HTT stats debugfs lock + * @htt_stats_dbgfs_msg_process: Function callback to print HTT stats + */ +struct pdev_htt_stats_dbgfs_cfg { + qdf_dentry_t debugfs_entry[PDEV_HTT_STATS_DBGFS_SIZE]; + qdf_debugfs_file_t m; + struct qdf_debugfs_fops + pdev_htt_stats_dbgfs_ops[PDEV_HTT_STATS_DBGFS_SIZE - 1]; + struct pdev_htt_stats_dbgfs_priv priv[PDEV_HTT_STATS_DBGFS_SIZE - 1]; + qdf_event_t htt_stats_dbgfs_event; + qdf_mutex_t lock; + void (*htt_stats_dbgfs_msg_process)(void *data, A_INT32 len); +}; +#endif /* HTT_STATS_DEBUGFS_SUPPORT */ + /* PDEV level structure for data path */ struct dp_pdev { /** @@ -2091,6 +2127,10 @@ struct dp_pdev { /* Maintains first status buffer's paddr of a PPDU */ uint64_t status_buf_addr; +#ifdef HTT_STATS_DEBUGFS_SUPPORT + /* HTT stats debugfs params */ + struct pdev_htt_stats_dbgfs_cfg *dbgfs_cfg; +#endif }; struct dp_peer;