From 18fe5c3f029fef0ba33252cc0546f8b677eb2815 Mon Sep 17 00:00:00 2001 From: sandhu Date: Thu, 9 Sep 2021 10:14:46 -0700 Subject: [PATCH] qcacmn: Add dp functionality to support stats sysfs Add dp functionality to collect stats for sysfs buffer. Add both host and fw stats. Change-Id: I64f84804d36cccec9d701925d96cc7ee96943b7a CRs-Fixed: 3035864 --- dp/inc/cdp_txrx_cmn_struct.h | 2 +- dp/inc/cdp_txrx_ops.h | 7 + dp/wifi3.0/dp_htt.c | 70 +++++++- dp/wifi3.0/dp_internal.h | 77 +++++++-- dp/wifi3.0/dp_main.c | 310 +++++++++++++++++++++++++++++++++-- dp/wifi3.0/dp_types.h | 42 ++++- 6 files changed, 477 insertions(+), 31 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 9b4bc84d3d..99f9e26d4d 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -2411,7 +2411,7 @@ struct cdp_txrx_stats_req { uint32_t param3; uint32_t cookie_val; uint8_t mac_id; - char *peer_addr; + char *peer_addr; }; /** diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 85289265e6..1bae788916 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -580,6 +580,13 @@ struct cdp_cmn_ops { #endif /* QCA_SUPPORT_WDS_EXTENDED */ void (*txrx_drain)(ol_txrx_soc_handle soc); int (*get_free_desc_poolsize)(struct cdp_soc_t *soc); +#ifdef WLAN_SYSFS_DP_STATS + QDF_STATUS (*txrx_sysfs_fill_stats)(ol_txrx_soc_handle soc, + char *buf, uint32_t buf_size); + QDF_STATUS (*txrx_sysfs_set_stat_type)(ol_txrx_soc_handle soc, + uint32_t stat_type, + uint32_t mac_id); +#endif /* WLAN_SYSFS_DP_STATS */ }; struct cdp_ctrl_ops { diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 4427b5f85b..aef229d68c 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -1592,7 +1592,7 @@ dp_send_htt_stat_resp(struct htt_stats_context *htt_stats, #endif #ifdef HTT_STATS_DEBUGFS_SUPPORT -/* dp_send_htt_stats_dbgfs_msg() - Function to send htt data to upper layer +/* 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 @@ -1633,6 +1633,67 @@ dp_htt_stats_dbgfs_send_msg(struct dp_pdev *pdev, uint32_t *msg_word, } #endif /* HTT_STATS_DEBUGFS_SUPPORT */ +#ifdef WLAN_SYSFS_DP_STATS +/* dp_htt_stats_sysfs_update_config() - Function to send htt data to upper layer. + * @pdev: dp pdev handle + * + * This function sets the process id and printing mode within the sysfs config + * struct. which enables DP_PRINT statements within this process to write to the + * console buffer provided by the user space. + * + * Return: None + */ +static inline void +dp_htt_stats_sysfs_update_config(struct dp_pdev *pdev) +{ + struct dp_soc *soc = pdev->soc; + + if (!soc) { + dp_htt_err("soc is null"); + return; + } + + if (!soc->sysfs_config) { + dp_htt_err("soc->sysfs_config is NULL"); + return; + } + + /* set sysfs config parameters */ + soc->sysfs_config->process_id = qdf_get_current_pid(); + soc->sysfs_config->printing_mode = PRINTING_MODE_ENABLED; +} + +/* + * dp_htt_stats_sysfs_set_event() - Set sysfs stats event. + * @soc: soc handle. + * @msg_word: Pointer to htt msg word. + * + * @return: void + */ +static inline void +dp_htt_stats_sysfs_set_event(struct dp_soc *soc, uint32_t *msg_word) +{ + int done = 0; + + done = HTT_T2H_EXT_STATS_CONF_TLV_DONE_GET(*(msg_word + 3)); + if (done) { + if (qdf_event_set(&soc->sysfs_config->sysfs_txrx_fw_request_done)) + dp_htt_err("%pK:event compl Fail to set event ", + soc); + } +} +#else /* WLAN_SYSFS_DP_STATS */ +static inline void +dp_htt_stats_sysfs_update_config(struct dp_pdev *pdev) +{ +} + +static inline void +dp_htt_stats_sysfs_set_event(struct dp_soc *dp_soc, uint32_t *msg_word) +{ +} +#endif /* WLAN_SYSFS_DP_STATS */ + /** * dp_process_htt_stat_msg(): Process the list of buffers of HTT EXT stats * @htt_stats: htt stats info @@ -1697,6 +1758,9 @@ static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats, continue; } + if (!cookie_val && (cookie_msb & DBG_SYSFS_STATS_COOKIE)) + dp_htt_stats_sysfs_update_config(pdev); + if (cookie_msb & DBG_STATS_COOKIE_DP_STATS) copy_stats = true; @@ -1800,6 +1864,10 @@ static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats, htt_stats->msg_len -= DP_EXT_MSG_LENGTH; } + /* indicate event completion in case the event is done */ + if (!cookie_val && (cookie_msb & DBG_SYSFS_STATS_COOKIE)) + dp_htt_stats_sysfs_set_event(soc, msg_word); + qdf_nbuf_free(htt_msg); } return; diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index b0e8b35bfe..ea37845807 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -57,10 +57,13 @@ struct htt_dbgfs_cfg { #define DBG_STATS_COOKIE_DEFAULT 0x0 /* Reserve for DP Stats: 3rd bit */ -#define DBG_STATS_COOKIE_DP_STATS 0x8 +#define DBG_STATS_COOKIE_DP_STATS BIT(3) /* Reserve for HTT Stats debugfs support: 4th bit */ -#define DBG_STATS_COOKIE_HTT_DBGFS 0x10 +#define DBG_STATS_COOKIE_HTT_DBGFS BIT(4) + +/*Reserve for HTT Stats debugfs support: 5th bit */ +#define DBG_SYSFS_STATS_COOKIE BIT(5) /** * Bitmap of HTT PPDU TLV types for Default mode @@ -612,6 +615,19 @@ void dp_monitor_pdev_reset_scan_spcl_vap_stats_enable(struct dp_pdev *pdev, } #endif +/** + * cdp_soc_t_to_dp_soc() - typecast cdp_soc_t to + * dp soc handle + * @psoc: CDP psoc handle + * + * Return: struct dp_soc pointer + */ +static inline +struct dp_soc *cdp_soc_t_to_dp_soc(struct cdp_soc_t *psoc) +{ + return (struct dp_soc *)psoc; +} + #define DP_MAX_TIMER_EXEC_TIME_TICKS \ (QDF_LOG_TIMESTAMP_CYCLES_PER_10_US * 100 * 20) @@ -666,6 +682,48 @@ while (0) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_##LVL, \ fmt, ## args) +#ifdef WLAN_SYSFS_DP_STATS +static +inline void DP_PRINT_STATS(const char *fmt, ...) +{ + void *soc_void = NULL; + va_list val; + uint16_t buf_written = 0; + uint16_t curr_len = 0; + uint16_t max_len = 0; + struct dp_soc *soc = NULL; + + soc_void = cds_get_context(QDF_MODULE_ID_SOC); + soc = cdp_soc_t_to_dp_soc(soc_void); + va_start(val, fmt); + QDF_VTRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, (char *)fmt, val); + /* writing to the buffer */ + if (soc->sysfs_config && soc->sysfs_config->printing_mode == PRINTING_MODE_ENABLED) { + if (soc->sysfs_config->process_id == qdf_get_current_pid()) { + curr_len = soc->sysfs_config->curr_buffer_length; + max_len = soc->sysfs_config->max_buffer_length; + if ((max_len - curr_len) <= 1) + return; + + qdf_spinlock_acquire(&soc->sysfs_config->sysfs_write_user_buffer); + if (soc->sysfs_config->buf) { + buf_written = vscnprintf(soc->sysfs_config->buf + curr_len, + max_len - curr_len, fmt, val); + curr_len += buf_written; + if ((max_len - curr_len) <= 1) + return; + + buf_written += scnprintf(soc->sysfs_config->buf + curr_len, + max_len - curr_len, "\n"); + soc->sysfs_config->curr_buffer_length += buf_written; + } + qdf_spinlock_release(&soc->sysfs_config->sysfs_write_user_buffer); + } + } + va_end(val); +} + +#else /* WLAN_SYSFS_DP_STATS */ #ifdef DP_PRINT_NO_CONSOLE /* Stat prints should not go to console or kernel logs.*/ #define DP_PRINT_STATS(fmt, args ...)\ @@ -676,6 +734,8 @@ while (0) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,\ fmt, ## args) #endif +#endif /* WLAN_SYSFS_DP_STATS */ + #define DP_STATS_INIT(_handle) \ qdf_mem_zero(&((_handle)->stats), sizeof((_handle)->stats)) @@ -2479,19 +2539,6 @@ struct cdp_soc_t *dp_soc_to_cdp_soc_t(struct dp_soc *psoc) return (struct cdp_soc_t *)psoc; } -/** - * cdp_soc_t_to_dp_soc() - typecast cdp_soc_t to - * dp soc handle - * @psoc: CDP psoc handle - * - * Return: struct dp_soc pointer - */ -static inline -struct dp_soc *cdp_soc_t_to_dp_soc(struct cdp_soc_t *psoc) -{ - return (struct dp_soc *)psoc; -} - #if defined(WLAN_SUPPORT_RX_FLOW_TAG) || defined(WLAN_SUPPORT_RX_FISA) /** * dp_rx_flow_update_fse_stats() - Update a flow's statistics diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 6882a3981d..209f16b4f7 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -105,6 +105,11 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc) #define SET_PEER_REF_CNT_ONE(_peer) #endif +#ifdef WLAN_SYSFS_DP_STATS +/* sysfs event wait time for firmware stat request unit millseconds */ +#define WLAN_SYSFS_STAT_REQ_WAIT_MS 3000 +#endif + QDF_COMPILE_TIME_ASSERT(max_rx_rings_check, MAX_REO_DEST_RINGS == CDP_MAX_RX_RINGS); @@ -159,6 +164,9 @@ QDF_COMPILE_TIME_ASSERT(wlan_cfg_num_int_ctxs, WLAN_CFG_INT_NUM_CONTEXTS_MAX >= WLAN_CFG_INT_NUM_CONTEXTS); +static QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl); +static QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl); + static void dp_pdev_srng_deinit(struct dp_pdev *pdev); static QDF_STATUS dp_pdev_srng_init(struct dp_pdev *pdev); static void dp_pdev_srng_free(struct dp_pdev *pdev); @@ -5350,6 +5358,7 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc) soc->arch_ops.txrx_soc_detach(soc); + dp_sysfs_deinitialize_stats(soc); dp_soc_swlm_detach(soc); dp_soc_tx_desc_sw_pools_free(soc); dp_soc_srng_free(soc); @@ -9436,25 +9445,91 @@ dp_set_pdev_dscp_tid_map_wifi3(struct cdp_soc_t *soc_handle, return QDF_STATUS_SUCCESS; } +#ifdef WLAN_SYSFS_DP_STATS +/* + * dp_sysfs_event_trigger(): Trigger event to wait for firmware + * stats request response. + * @soc: soc handle + * @cookie_val: cookie value + * + * @Return: QDF_STATUS + */ +static QDF_STATUS +dp_sysfs_event_trigger(struct dp_soc *soc, uint32_t cookie_val) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + /* wait for firmware response for sysfs stats request */ + if (cookie_val == DBG_SYSFS_STATS_COOKIE) { + if (!soc) { + dp_cdp_err("soc is NULL"); + return QDF_STATUS_E_FAILURE; + } + /* wait for event completion */ + status = qdf_wait_single_event(&soc->sysfs_config->sysfs_txrx_fw_request_done, + WLAN_SYSFS_STAT_REQ_WAIT_MS); + if (status == QDF_STATUS_SUCCESS) + dp_cdp_info("sysfs_txrx_fw_request_done event completed"); + else if (status == QDF_STATUS_E_TIMEOUT) + dp_cdp_warn("sysfs_txrx_fw_request_done event expired"); + else + dp_cdp_warn("sysfs_txrx_fw_request_done event erro code %d", status); + } + + return status; +} +#else /* WLAN_SYSFS_DP_STATS */ +/* + * dp_sysfs_event_trigger(): Trigger event to wait for firmware + * stats request response. + * @soc: soc handle + * @cookie_val: cookie value + * + * @Return: QDF_STATUS + */ +static QDF_STATUS +dp_sysfs_event_trigger(struct dp_soc *soc, uint32_t cookie_val) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_SYSFS_DP_STATS */ + /** - * dp_fw_stats_process(): Process TxRX FW stats request + * dp_fw_stats_process(): Process TXRX FW stats request. * @vdev_handle: DP VDEV handle * @req: stats request * - * return: int + * return: QDF_STATUS */ -static int dp_fw_stats_process(struct dp_vdev *vdev, - struct cdp_txrx_stats_req *req) +static QDF_STATUS +dp_fw_stats_process(struct dp_vdev *vdev, + struct cdp_txrx_stats_req *req) { struct dp_pdev *pdev = NULL; + struct dp_soc *soc = NULL; uint32_t stats = req->stats; uint8_t mac_id = req->mac_id; + uint32_t cookie_val = DBG_STATS_COOKIE_DEFAULT; if (!vdev) { DP_TRACE(NONE, "VDEV not found"); - return 1; + return QDF_STATUS_E_FAILURE; } + pdev = vdev->pdev; + if (!pdev) { + DP_TRACE(NONE, "PDEV not found"); + return QDF_STATUS_E_FAILURE; + } + + soc = pdev->soc; + if (!soc) { + DP_TRACE(NONE, "soc not found"); + return QDF_STATUS_E_FAILURE; + } + + /* In case request is from host sysfs for displaying stats on console */ + if (req->cookie_val == DBG_SYSFS_STATS_COOKIE) + cookie_val = DBG_SYSFS_STATS_COOKIE; /* * For HTT_DBG_EXT_STATS_RESET command, FW need to config @@ -9476,16 +9551,20 @@ static int dp_fw_stats_process(struct dp_vdev *vdev, } if (req->stats == (uint8_t)HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT) { - 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, DBG_STATS_COOKIE_DEFAULT, - mac_id); + dp_h2t_ext_stats_msg_send(pdev, + HTT_DBG_EXT_STATS_PDEV_RX_RATE_EXT, + req->param0, req->param1, req->param2, + req->param3, 0, cookie_val, + mac_id); } else { - return dp_h2t_ext_stats_msg_send(pdev, stats, req->param0, - req->param1, req->param2, req->param3, - 0, DBG_STATS_COOKIE_DEFAULT, mac_id); + dp_h2t_ext_stats_msg_send(pdev, stats, req->param0, + req->param1, req->param2, req->param3, + 0, cookie_val, mac_id); } + + dp_sysfs_event_trigger(soc, cookie_val); + + return QDF_STATUS_SUCCESS; } /** @@ -9628,6 +9707,202 @@ static QDF_STATUS dp_txrx_dump_stats(struct cdp_soc_t *psoc, uint16_t value, } +#ifdef WLAN_SYSFS_DP_STATS +static +void dp_sysfs_get_stat_type(struct dp_soc *soc, uint32_t *mac_id, + uint32_t *stat_type) +{ + qdf_spinlock_acquire(&soc->sysfs_config->rw_stats_lock); + *stat_type = soc->sysfs_config->stat_type_requested; + *mac_id = soc->sysfs_config->mac_id; + + qdf_spinlock_release(&soc->sysfs_config->rw_stats_lock); +} + +static +void dp_sysfs_update_config_buf_params(struct dp_soc *soc, + uint32_t curr_len, + uint32_t max_buf_len, + char *buf) +{ + qdf_spinlock_acquire(&soc->sysfs_config->sysfs_write_user_buffer); + /* set sysfs_config parameters */ + soc->sysfs_config->buf = buf; + soc->sysfs_config->curr_buffer_length = curr_len; + soc->sysfs_config->max_buffer_length = max_buf_len; + qdf_spinlock_release(&soc->sysfs_config->sysfs_write_user_buffer); +} + +static +QDF_STATUS dp_sysfs_fill_stats(ol_txrx_soc_handle soc_hdl, + char *buf, uint32_t buf_size) +{ + uint32_t mac_id = 0; + uint32_t stat_type = 0; + uint32_t fw_stats = 0; + uint32_t host_stats = 0; + enum cdp_stats stats; + struct cdp_txrx_stats_req req; + struct dp_soc *soc = NULL; + + if (!soc_hdl) { + dp_cdp_err("%pK: soc_hdl is NULL", soc_hdl); + return QDF_STATUS_E_INVAL; + } + + soc = cdp_soc_t_to_dp_soc(soc_hdl); + + if (!soc) { + dp_cdp_err("%pK: soc is NULL", soc); + return QDF_STATUS_E_INVAL; + } + + dp_sysfs_get_stat_type(soc, &mac_id, &stat_type); + + stats = stat_type; + if (stats >= CDP_TXRX_MAX_STATS) { + dp_cdp_info("sysfs stat type requested is invalid"); + return QDF_STATUS_E_INVAL; + } + /* + * DP_CURR_FW_STATS_AVAIL: no of FW stats currently available + * has to be updated if new FW HTT stats added + */ + if (stats > CDP_TXRX_MAX_STATS) + stats = stats + DP_CURR_FW_STATS_AVAIL - DP_HTT_DBG_EXT_STATS_MAX; + + /* build request */ + fw_stats = dp_stats_mapping_table[stats][STATS_FW]; + host_stats = dp_stats_mapping_table[stats][STATS_HOST]; + + req.stats = stat_type; + req.mac_id = mac_id; + /* request stats to be printed */ + qdf_mutex_acquire(&soc->sysfs_config->sysfs_read_lock); + + if (fw_stats != TXRX_FW_STATS_INVALID) { + /* update request with FW stats type */ + req.cookie_val = DBG_SYSFS_STATS_COOKIE; + } else if ((host_stats != TXRX_HOST_STATS_INVALID) && + (host_stats <= TXRX_HOST_STATS_MAX)) { + req.cookie_val = DBG_STATS_COOKIE_DEFAULT; + soc->sysfs_config->process_id = qdf_get_current_pid(); + soc->sysfs_config->printing_mode = PRINTING_MODE_ENABLED; + } + + dp_sysfs_update_config_buf_params(soc, 0, buf_size, buf); + + dp_txrx_stats_request(soc_hdl, mac_id, &req); + soc->sysfs_config->process_id = 0; + soc->sysfs_config->printing_mode = PRINTING_MODE_DISABLED; + + dp_sysfs_update_config_buf_params(soc, 0, 0, NULL); + + qdf_mutex_release(&soc->sysfs_config->sysfs_read_lock); + return QDF_STATUS_SUCCESS; +} + +static +QDF_STATUS dp_sysfs_set_stat_type(ol_txrx_soc_handle soc_hdl, + uint32_t stat_type, uint32_t mac_id) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + + if (!soc_hdl) { + dp_cdp_err("%pK: soc is NULL", soc); + return QDF_STATUS_E_INVAL; + } + + qdf_spinlock_acquire(&soc->sysfs_config->rw_stats_lock); + + soc->sysfs_config->stat_type_requested = stat_type; + soc->sysfs_config->mac_id = mac_id; + + qdf_spinlock_release(&soc->sysfs_config->rw_stats_lock); + + return QDF_STATUS_SUCCESS; +} + +static +QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl) +{ + struct dp_soc *soc; + QDF_STATUS status; + + if (!soc_hdl) { + dp_cdp_err("%pK: soc_hdl is NULL", soc_hdl); + return QDF_STATUS_E_INVAL; + } + + soc = soc_hdl; + + soc->sysfs_config = qdf_mem_malloc(sizeof(struct sysfs_stats_config)); + if (!soc->sysfs_config) { + dp_cdp_err("failed to allocate memory for sysfs_config no memory"); + return QDF_STATUS_E_NOMEM; + } + + status = qdf_event_create(&soc->sysfs_config->sysfs_txrx_fw_request_done); + /* create event for fw stats request from sysfs */ + if (status != QDF_STATUS_SUCCESS) { + dp_cdp_err("failed to create event sysfs_txrx_fw_request_done"); + qdf_mem_free(soc->sysfs_config); + soc->sysfs_config = NULL; + return QDF_STATUS_E_FAILURE; + } + + qdf_spinlock_create(&soc->sysfs_config->rw_stats_lock); + qdf_mutex_create(&soc->sysfs_config->sysfs_read_lock); + qdf_spinlock_create(&soc->sysfs_config->sysfs_write_user_buffer); + + return QDF_STATUS_SUCCESS; +} + +static +QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl) +{ + struct dp_soc *soc; + QDF_STATUS status; + + if (!soc_hdl) { + dp_cdp_err("%pK: soc_hdl is NULL", soc_hdl); + return QDF_STATUS_E_INVAL; + } + + soc = soc_hdl; + if (!soc->sysfs_config) { + dp_cdp_err("soc->sysfs_config is NULL"); + return QDF_STATUS_E_FAILURE; + } + + status = qdf_event_destroy(&soc->sysfs_config->sysfs_txrx_fw_request_done); + if (status != QDF_STATUS_SUCCESS) + dp_cdp_err("Failed to detroy event sysfs_txrx_fw_request_done "); + + qdf_mutex_destroy(&soc->sysfs_config->sysfs_read_lock); + qdf_spinlock_destroy(&soc->sysfs_config->rw_stats_lock); + qdf_spinlock_destroy(&soc->sysfs_config->sysfs_write_user_buffer); + + qdf_mem_free(soc->sysfs_config); + + return QDF_STATUS_SUCCESS; +} + +#else /* WLAN_SYSFS_DP_STATS */ + +static +QDF_STATUS dp_sysfs_deinitialize_stats(struct dp_soc *soc_hdl) +{ + return QDF_STATUS_SUCCESS; +} + +static +QDF_STATUS dp_sysfs_initialize_stats(struct dp_soc *soc_hdl) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_SYSFS_DP_STATS */ + /** * dp_txrx_clear_dump_stats() - clear dumpStats * @soc- soc handle @@ -10788,6 +11063,10 @@ static struct cdp_cmn_ops dp_ops_cmn = { #if defined(FEATURE_RUNTIME_PM) || defined(DP_POWER_SAVE) .txrx_drain = dp_drain_txrx, #endif +#ifdef WLAN_SYSFS_DP_STATS + .txrx_sysfs_fill_stats = dp_sysfs_fill_stats, + .txrx_sysfs_set_stat_type = dp_sysfs_set_stat_type, +#endif /* WLAN_SYSFS_DP_STATS */ }; static struct cdp_ctrl_ops dp_ops_ctrl = { @@ -11773,6 +12052,11 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, } } + if (dp_sysfs_initialize_stats(soc) != QDF_STATUS_SUCCESS) { + dp_err("failed to initialize dp stats sysfs file"); + dp_sysfs_deinitialize_stats(soc); + } + dp_soc_swlm_attach(soc); dp_soc_set_interrupt_mode(soc); dp_soc_set_def_pdev(soc); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index f09259b3ff..c3b59a4e38 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1664,6 +1664,43 @@ struct dp_soc_features { uint8_t pn_in_reo_dest; }; +enum sysfs_printing_mode { + PRINTING_MODE_DISABLED = 0, + PRINTING_MODE_ENABLED +}; + +#ifdef WLAN_SYSFS_DP_STATS +/** + * struct sysfs_stats_config: Data structure holding stats sysfs config. + * @rw_stats_lock: Lock to read and write to stat_type and pdev_id. + * @sysfs_read_lock: Lock held while another stat req is being executed. + * @sysfs_write_user_buffer: Lock to change buff len, max buf len + * and *buf. + * @sysfs_txrx_fw_request_done: Event to wait for firmware response. + * @stat_type_requested: stat type requested. + * @mac_id: mac id for which stat type are requested. + * @printing_mode: Should a print go through. + * @process_id: Process allowed to write to buffer. + * @curr_buffer_length: Curr length of buffer written + * @max_buffer_length: Max buffer length. + * @buf: Sysfs buffer. + */ +struct sysfs_stats_config { + /* lock held to read stats */ + qdf_spinlock_t rw_stats_lock; + qdf_mutex_t sysfs_read_lock; + qdf_spinlock_t sysfs_write_user_buffer; + qdf_event_t sysfs_txrx_fw_request_done; + uint32_t stat_type_requested; + uint32_t mac_id; + enum sysfs_printing_mode printing_mode; + int process_id; + uint16_t curr_buffer_length; + uint16_t max_buffer_length; + char *buf; +}; +#endif + /* SOC level structure for data path */ struct dp_soc { /** @@ -1896,7 +1933,10 @@ struct dp_soc { /* SoC level data path statistics */ struct dp_soc_stats stats; - +#ifdef WLAN_SYSFS_DP_STATS + /* sysfs config for DP stats */ + struct sysfs_stats_config *sysfs_config; +#endif /* timestamp to keep track of msdu buffers received on reo err ring */ uint64_t rx_route_err_start_pkt_ts;