Browse Source

Merge "msm: ipa4: add ipa_wigig debugfs"

qctecmdr 5 years ago
parent
commit
6dc7f1de20

+ 8 - 7
ipa/ipa_api.c

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

+ 3 - 2
ipa/ipa_api.h

@@ -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,

+ 178 - 3
ipa/ipa_clients/ipa_wigig.c

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

+ 3 - 2
ipa/ipa_common_i.h

@@ -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,

+ 2 - 0
ipa/ipa_v3/ipa_debugfs.c

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

+ 5 - 2
ipa/ipa_v3/ipa_i.h

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

+ 1 - 1
ipa/ipa_v3/ipa_utils.c

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

+ 71 - 6
ipa/ipa_v3/ipa_wigig_i.c

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