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
This commit is contained in:
sandhu
2021-09-09 10:14:46 -07:00
committad av Madan Koyyalamudi
förälder f2ec3b8c25
incheckning 18fe5c3f02
6 ändrade filer med 477 tillägg och 31 borttagningar

Visa fil

@@ -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);