msm: ipa4: add ipa_wigig debugfs

Add debugging capabilities to ipa_wigig.

Change-Id: I41ce94bbb2af597aa11848869261d8d432fa0e04
Signed-off-by: Arnav Sharma <arnav_s@codeaurora.org>
This commit is contained in:
Amir Levy 2019-07-14 10:10:33 +03:00 committed by Arnav Sharma
parent e0745d4cc5
commit 4dcae9f2d5
8 changed files with 271 additions and 23 deletions

View File

@ -2071,29 +2071,29 @@ int ipa_uc_reg_rdyCB(
EXPORT_SYMBOL(ipa_uc_reg_rdyCB);
/**
* ipa_wigig_uc_init() - get uc db and register uC
* ipa_wigig_internal_init() - get uc db and register uC
* ready CB if uC not ready, wigig only.
* @inout: [in/out] uc ready input/output parameters
* from/to client
* @int_notify: [in] wigig misc interrupt handler function
* @uc_db_pa: [out] uC db physical address
*
* Returns: 0 on success, negative on failure
*
*/
int ipa_wigig_uc_init(
int ipa_wigig_internal_init(
struct ipa_wdi_uc_ready_params *inout,
ipa_wigig_misc_int_cb int_notify,
phys_addr_t *uc_db_pa)
{
int ret;
IPA_API_DISPATCH_RETURN(ipa_wigig_uc_init, inout,
IPA_API_DISPATCH_RETURN(ipa_wigig_internal_init, inout,
int_notify, uc_db_pa);
return ret;
}
EXPORT_SYMBOL(ipa_wigig_uc_init);
EXPORT_SYMBOL(ipa_wigig_internal_init);
/**
* ipa_uc_dereg_rdyCB() - To de-register uC ready CB
@ -3549,11 +3549,12 @@ EXPORT_SYMBOL(ipa_wigig_uc_msi_init);
/**
* ipa_conn_wigig_rx_pipe_i() - connect wigig rx pipe
*/
int ipa_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out)
int ipa_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out,
struct dentry **parent)
{
int ret;
IPA_API_DISPATCH_RETURN(ipa_conn_wigig_rx_pipe_i, in, out);
IPA_API_DISPATCH_RETURN(ipa_conn_wigig_rx_pipe_i, in, out, parent);
return ret;
}

View File

@ -432,13 +432,14 @@ struct ipa_api_controller {
struct ipa_smmu_out_params *out);
int (*ipa_is_vlan_mode)(enum ipa_vlan_ifaces iface, bool *res);
int (*ipa_wigig_uc_init)(
int (*ipa_wigig_internal_init)(
struct ipa_wdi_uc_ready_params *inout,
ipa_wigig_misc_int_cb int_notify,
phys_addr_t *uc_db_pa);
int (*ipa_conn_wigig_rx_pipe_i)(void *in,
struct ipa_wigig_conn_out_params *out);
struct ipa_wigig_conn_out_params *out,
struct dentry **parent);
int (*ipa_conn_wigig_client_i)(void *in,
struct ipa_wigig_conn_out_params *out,

View File

@ -4,6 +4,7 @@
*/
#include <linux/ipa_wigig.h>
#include <linux/debugfs.h>
#include <linux/string.h>
#include "../ipa_common_i.h"
#include "../ipa_v3/ipa_pm.h"
@ -105,10 +106,21 @@ struct ipa_wigig_context {
bool smmu_en;
bool shared_cb;
u8 conn_pipes;
struct dentry *parent;
struct dentry *dent_conn_clients;
struct dentry *dent_smmu;
};
static struct ipa_wigig_context *ipa_wigig_ctx;
#ifdef CONFIG_DEBUG_FS
static int ipa_wigig_init_debugfs(struct dentry *parent);
static inline void ipa_wigig_deinit_debugfs(void);
#else
static int ipa_wigig_init_debugfs(struct dentry *parent) { return 0; }
static inline void ipa_wigig_deinit_debugfs(void) { }
#endif
int ipa_wigig_init(struct ipa_wigig_init_in_params *in,
struct ipa_wigig_init_out_params *out)
{
@ -148,7 +160,8 @@ int ipa_wigig_init(struct ipa_wigig_init_in_params *in,
inout.notify = in->notify;
inout.priv = in->priv;
if (ipa_wigig_uc_init(&inout, in->int_notify, &out->uc_db_pa)) {
if (ipa_wigig_internal_init(&inout, in->int_notify,
&out->uc_db_pa)) {
kfree(ipa_wigig_ctx);
ipa_wigig_ctx = NULL;
return -EFAULT;
@ -182,6 +195,9 @@ int ipa_wigig_cleanup(void)
}
mutex_destroy(&ipa_wigig_ctx->lock);
ipa_wigig_deinit_debugfs();
kfree(ipa_wigig_ctx);
ipa_wigig_ctx = NULL;
@ -708,7 +724,7 @@ int ipa_wigig_conn_rx_pipe(struct ipa_wigig_conn_rx_in_params *in,
goto fail_msi;
}
if (ipa_conn_wigig_rx_pipe_i(in, out)) {
if (ipa_conn_wigig_rx_pipe_i(in, out, &ipa_wigig_ctx->parent)) {
IPA_WIGIG_ERR("fail to connect rx pipe\n");
ret = -EFAULT;
goto fail_connect_pipe;
@ -717,6 +733,9 @@ int ipa_wigig_conn_rx_pipe(struct ipa_wigig_conn_rx_in_params *in,
ipa_wigig_ctx->tx_notify = in->notify;
ipa_wigig_ctx->priv = in->priv;
if (ipa_wigig_ctx->parent)
ipa_wigig_init_debugfs(ipa_wigig_ctx->parent);
ipa_wigig_store_pipe_info(ipa_wigig_ctx->pipes.flat,
IPA_CLIENT_WIGIG_PROD_IDX);
@ -1453,12 +1472,15 @@ int ipa_wigig_conn_rx_pipe_smmu(
goto fail_msi;
}
if (ipa_conn_wigig_rx_pipe_i(in, out)) {
if (ipa_conn_wigig_rx_pipe_i(in, out, &ipa_wigig_ctx->parent)) {
IPA_WIGIG_ERR("fail to connect rx pipe\n");
ret = -EFAULT;
goto fail_connect_pipe;
}
if (ipa_wigig_ctx->parent)
ipa_wigig_init_debugfs(ipa_wigig_ctx->parent);
if (ipa_wigig_store_rx_smmu_info(in)) {
IPA_WIGIG_ERR("fail to store smmu data for rx pipe\n");
ret = -EFAULT;
@ -1913,3 +1935,156 @@ int ipa_wigig_tx_dp(enum ipa_client_type dst, struct sk_buff *skb)
return 0;
}
EXPORT_SYMBOL(ipa_wigig_tx_dp);
#ifdef CONFIG_DEBUG_FS
#define IPA_MAX_MSG_LEN 4096
static ssize_t ipa_wigig_read_conn_clients(struct file *file,
char __user *ubuf, size_t count, loff_t *ppos)
{
int i;
int nbytes = 0;
u8 pipe_connected;
char *dbg_buff;
ssize_t ret;
dbg_buff = kzalloc(IPA_MAX_MSG_LEN, GFP_KERNEL);
if (!dbg_buff)
return -ENOMEM;
if (!ipa_wigig_ctx) {
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
"IPA WIGIG not initialized\n");
goto finish;
}
if (!ipa_wigig_ctx->conn_pipes) {
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
"no WIGIG pipes connected\n");
goto finish;
}
for (i = 0; i < IPA_WIGIG_MAX_PIPES; i++) {
pipe_connected = (ipa_wigig_ctx->conn_pipes & (0x1 << i));
switch (i) {
case 0:
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
"IPA_CLIENT_WIGIG_PROD");
break;
case 1:
case 2:
case 3:
case 4:
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
"IPA_CLIENT_WIGIG%d_CONS",
i);
break;
default:
IPA_WIGIG_ERR("invalid pipe %d\n", i);
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
"invalid pipe %d",
i);
break;
}
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
" %s connected\n", pipe_connected ? "is" : "not");
}
finish:
ret = simple_read_from_buffer(
ubuf, count, ppos, dbg_buff, nbytes);
kfree(dbg_buff);
return ret;
}
static ssize_t ipa_wigig_read_smmu_status(struct file *file,
char __user *ubuf, size_t count, loff_t *ppos)
{
int nbytes = 0;
char *dbg_buff;
ssize_t ret;
dbg_buff = kzalloc(IPA_MAX_MSG_LEN, GFP_KERNEL);
if (!dbg_buff)
return -ENOMEM;
if (!ipa_wigig_ctx) {
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
"IPA WIGIG not initialized\n");
goto finish;
}
if (ipa_wigig_ctx->smmu_en) {
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
"SMMU enabled\n");
if (ipa_wigig_ctx->shared_cb) {
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
"CB shared\n");
} else {
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
"CB not shared\n");
}
} else {
nbytes += scnprintf(dbg_buff + nbytes,
IPA_MAX_MSG_LEN - nbytes,
"SMMU in S1 bypass\n");
}
finish:
ret = simple_read_from_buffer(
ubuf, count, ppos, dbg_buff, nbytes);
kfree(dbg_buff);
return ret;
}
static const struct file_operations ipa_wigig_conn_clients_ops = {
.read = ipa_wigig_read_conn_clients,
};
static const struct file_operations ipa_wigig_smmu_ops = {
.read = ipa_wigig_read_smmu_status,
};
static inline void ipa_wigig_deinit_debugfs(void)
{
debugfs_remove(ipa_wigig_ctx->dent_conn_clients);
debugfs_remove(ipa_wigig_ctx->dent_smmu);
}
static int ipa_wigig_init_debugfs(struct dentry *parent)
{
const mode_t read_only_mode = 0444;
ipa_wigig_ctx->dent_conn_clients =
debugfs_create_file("conn_clients", read_only_mode, parent,
NULL, &ipa_wigig_conn_clients_ops);
if (IS_ERR_OR_NULL(ipa_wigig_ctx->dent_conn_clients)) {
IPA_WIGIG_ERR("fail to create file %s\n", "conn_clients");
goto fail_conn_clients;
}
ipa_wigig_ctx->dent_smmu =
debugfs_create_file("smmu", read_only_mode, parent, NULL,
&ipa_wigig_smmu_ops);
if (IS_ERR_OR_NULL(ipa_wigig_ctx->dent_smmu)) {
IPA_WIGIG_ERR("fail to create file %s\n", "smmu");
goto fail_smmu;
}
return 0;
fail_smmu:
debugfs_remove(ipa_wigig_ctx->dent_conn_clients);
fail_conn_clients:
return -EFAULT;
}
#endif

View File

@ -435,12 +435,13 @@ int ipa_smmu_free_sgt(struct sg_table **out_sgt_ptr);
int ipa_ut_module_init(void);
void ipa_ut_module_exit(void);
int ipa_wigig_uc_init(
int ipa_wigig_internal_init(
struct ipa_wdi_uc_ready_params *inout,
ipa_wigig_misc_int_cb int_notify,
phys_addr_t *uc_db_pa);
int ipa_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out);
int ipa_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out,
struct dentry **parent);
int ipa_conn_wigig_client_i(void *in, struct ipa_wigig_conn_out_params *out,
ipa_notify_cb tx_notify,

View File

@ -2524,6 +2524,8 @@ void ipa3_debugfs_init(void)
ipa_debugfs_init_stats(dent);
ipa3_wigig_init_debugfs_i(dent);
return;
fail:

View File

@ -2490,7 +2490,8 @@ int ipa3_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx);
int ipa3_disable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx);
int ipa3_conn_wigig_rx_pipe_i(void *in,
struct ipa_wigig_conn_out_params *out);
struct ipa_wigig_conn_out_params *out,
struct dentry **parent);
int ipa3_conn_wigig_client_i(void *in,
struct ipa_wigig_conn_out_params *out,
@ -2512,6 +2513,8 @@ int ipa3_enable_wigig_pipe_i(enum ipa_client_type client);
int ipa3_disable_wigig_pipe_i(enum ipa_client_type client);
int ipa3_wigig_init_debugfs_i(struct dentry *dent);
/*
* To retrieve doorbell physical address of
* wlan pipes
@ -2834,7 +2837,7 @@ const struct ipa_gsi_ep_config *ipa3_get_gsi_ep_info
(enum ipa_client_type client);
int ipa3_wigig_init_i(void);
int ipa3_wigig_uc_init(
int ipa3_wigig_internal_init(
struct ipa_wdi_uc_ready_params *inout,
ipa_wigig_misc_int_cb int_notify,
phys_addr_t *uc_db_pa);

View File

@ -6974,7 +6974,7 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type,
api_ctrl->ipa_tz_unlock_reg = ipa3_tz_unlock_reg;
api_ctrl->ipa_get_smmu_params = ipa3_get_smmu_params;
api_ctrl->ipa_is_vlan_mode = ipa3_is_vlan_mode;
api_ctrl->ipa_wigig_uc_init = ipa3_wigig_uc_init;
api_ctrl->ipa_wigig_internal_init = ipa3_wigig_internal_init;
api_ctrl->ipa_conn_wigig_rx_pipe_i = ipa3_conn_wigig_rx_pipe_i;
api_ctrl->ipa_conn_wigig_client_i = ipa3_conn_wigig_client_i;
api_ctrl->ipa_disconn_wigig_pipe_i = ipa3_disconn_wigig_pipe_i;

View File

@ -6,6 +6,7 @@
#include "ipa_i.h"
#include <linux/if_ether.h>
#include <linux/log2.h>
#include <linux/debugfs.h>
#include <linux/ipa_wigig.h>
#define IPA_WIGIG_DESC_RING_EL_SIZE 32
@ -30,6 +31,7 @@
static LIST_HEAD(smmu_reg_addr_list);
static LIST_HEAD(smmu_ring_addr_list);
static DEFINE_MUTEX(smmu_lock);
struct dentry *wigig_dent;
struct ipa_wigig_smmu_reg_addr {
struct list_head link;
@ -86,7 +88,7 @@ int ipa3_wigig_init_i(void)
return 0;
}
int ipa3_wigig_uc_init(
int ipa3_wigig_internal_init(
struct ipa_wdi_uc_ready_params *inout,
ipa_wigig_misc_int_cb int_notify,
phys_addr_t *uc_db_pa)
@ -587,6 +589,11 @@ static void ipa_gsi_evt_ring_err_cb(struct gsi_evt_err_notify *notify)
ipa_assert();
}
static uint16_t int_modt = 15;
static uint8_t int_modc = 200;
static uint8_t tx_hwtail_mod_threshold = 200;
static uint8_t rx_hwtail_mod_threshold = 200;
static int ipa3_wigig_config_gsi(bool Rx,
bool smmu_en,
void *pipe_info,
@ -616,8 +623,8 @@ static int ipa3_wigig_config_gsi(bool Rx,
evt_props.exclusive = true;
evt_props.err_cb = ipa_gsi_evt_ring_err_cb;
evt_props.user_data = NULL;
evt_props.int_modc = 200;
evt_props.int_modt = 15;
evt_props.int_modc = int_modc;
evt_props.int_modt = int_modt;
evt_props.ring_base_vaddr = NULL;
if (smmu_en) {
@ -646,7 +653,8 @@ static int ipa3_wigig_config_gsi(bool Rx,
union __packed gsi_evt_scratch evt_scratch;
memset(&evt_scratch, 0, sizeof(evt_scratch));
evt_scratch.w11ad.update_status_hwtail_mod_threshold = 200;
evt_scratch.w11ad.update_status_hwtail_mod_threshold =
rx_hwtail_mod_threshold;
gsi_res = gsi_write_evt_ring_scratch(ep->gsi_evt_ring_hdl,
evt_scratch);
if (gsi_res != GSI_STATUS_SUCCESS) {
@ -792,7 +800,8 @@ static int ipa3_wigig_config_gsi(bool Rx,
gsi_scratch.tx_11ad.fixed_data_buffer_size_pow_2 =
ilog2(tx_dbuff->data_buffer_size);
}
gsi_scratch.tx_11ad.update_status_hwtail_mod_threshold = 200;
gsi_scratch.tx_11ad.update_status_hwtail_mod_threshold =
tx_hwtail_mod_threshold;
IPADBG("tx scratch: status_ring_hwtail_address_lsb 0x%X\n",
gsi_scratch.tx_11ad.status_ring_hwtail_address_lsb);
IPADBG("tx scratch: status_ring_hwhead_address_lsb 0x%X\n",
@ -926,7 +935,8 @@ static int ipa3_wigig_config_uc(bool init,
return result;
}
int ipa3_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out)
int ipa3_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out,
struct dentry **parent)
{
int ipa_ep_idx;
struct ipa3_ep_context *ep;
@ -943,6 +953,8 @@ int ipa3_conn_wigig_rx_pipe_i(void *in, struct ipa_wigig_conn_out_params *out)
IPADBG("\n");
*parent = wigig_dent;
ipa_ep_idx = ipa_get_ep_mapping(rx_client);
if (ipa_ep_idx == IPA_EP_NOT_ALLOCATED ||
ipa_ep_idx >= IPA3_MAX_NUM_PIPES) {
@ -1847,3 +1859,56 @@ fail_stop_channel:
ipa_assert();
return res;
}
#ifndef CONFIG_DEBUG_FS
int ipa3_wigig_init_debugfs_i(struct dentry *parent) { return 0; }
#else
int ipa3_wigig_init_debugfs_i(struct dentry *parent)
{
const mode_t read_write_mode = 0664;
struct dentry *file = NULL;
struct dentry *dent;
dent = debugfs_create_dir("ipa_wigig", parent);
if (IS_ERR_OR_NULL(dent)) {
IPAERR("fail to create folder in debug_fs\n");
return -EFAULT;
}
wigig_dent = dent;
file = debugfs_create_u8("modc", read_write_mode, dent,
&int_modc);
if (IS_ERR_OR_NULL(file)) {
IPAERR("fail to create file modc\n");
goto fail;
}
file = debugfs_create_u16("modt", read_write_mode, dent,
&int_modt);
if (IS_ERR_OR_NULL(file)) {
IPAERR("fail to create file modt\n");
goto fail;
}
file = debugfs_create_u8("rx_mod_th", read_write_mode, dent,
&rx_hwtail_mod_threshold);
if (IS_ERR_OR_NULL(file)) {
IPAERR("fail to create file rx_mod_th\n");
goto fail;
}
file = debugfs_create_u8("tx_mod_th", read_write_mode, dent,
&tx_hwtail_mod_threshold);
if (IS_ERR_OR_NULL(file)) {
IPAERR("fail to create file tx_mod_th\n");
goto fail;
}
return 0;
fail:
debugfs_remove_recursive(dent);
wigig_dent = NULL;
return -EFAULT;
}
#endif