Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4b110ec authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa3: Add IPA_USB status information to debugfs"

parents 3dc76568 0f1faf93
Loading
Loading
Loading
Loading
+82 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -114,6 +114,7 @@ static struct dentry *dfile_ip4_nat;
static struct dentry *dfile_rm_stats;
static struct dentry *dfile_status_stats;
static struct dentry *dfile_active_clients;
static struct dentry *dfile_ipa_usb;
static char dbg_buff[IPA_MAX_MSG_LEN];
static char *active_clients_buf;

@@ -1511,6 +1512,75 @@ static ssize_t ipa3_read_nat4(struct file *file,
	return 0;
}

static ssize_t ipa3_read_ipa_usb(struct file *file, char __user *ubuf,
		size_t count, loff_t *ppos)
{
	struct ipa3_usb_status_dbg_info status;
	int result;
	int nbytes;
	int cnt = 0;
	int i;

	result = ipa3_usb_get_status_dbg_info(&status);
	if (result) {
		nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
				"Fail to read IPA USB status\n");
		cnt += nbytes;
	} else {
		nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
			"Tethering Data State: %s\n"
			"DPL State: %s\n"
			"Protocols in Initialized State: ",
			status.teth_state,
			status.dpl_state);
		cnt += nbytes;

		for (i = 0 ; i < status.num_init_prot ; i++) {
			nbytes = scnprintf(dbg_buff + cnt,
					IPA_MAX_MSG_LEN - cnt,
					"%s ", status.inited_prots[i]);
			cnt += nbytes;
		}
		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
				status.num_init_prot ? "\n" : "None\n");
		cnt += nbytes;

		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
				"Protocols in Connected State: ");
		cnt += nbytes;
		if (status.teth_connected_prot) {
			nbytes = scnprintf(dbg_buff + cnt,
				IPA_MAX_MSG_LEN - cnt,
				"%s ", status.teth_connected_prot);
			cnt += nbytes;
		}
		if (status.dpl_connected_prot) {
			nbytes = scnprintf(dbg_buff + cnt,
				IPA_MAX_MSG_LEN - cnt,
				"%s ", status.dpl_connected_prot);
			cnt += nbytes;
		}
		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
				(status.teth_connected_prot ||
				status.dpl_connected_prot) ? "\n" : "None\n");
		cnt += nbytes;

		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
				"USB Tethering Consumer State: %s\n",
				status.teth_cons_state ?
				status.teth_cons_state : "Invalid");
		cnt += nbytes;

		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
				"DPL Consumer State: %s\n",
				status.dpl_cons_state ? status.dpl_cons_state :
				"Invalid");
		cnt += nbytes;
	}

	return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
}

static ssize_t ipa3_rm_read_stats(struct file *file, char __user *ubuf,
		size_t count, loff_t *ppos)
{
@@ -1712,6 +1782,10 @@ const struct file_operations ipa3_rm_stats = {
	.read = ipa3_rm_read_stats,
};

const struct file_operations ipa3_ipa_usb_ops = {
	.read = ipa3_read_ipa_usb,
};

const struct file_operations ipa3_active_clients = {
	.read = ipa3_print_active_clients_log,
	.write = ipa3_clear_active_clients_log,
@@ -1906,6 +1980,13 @@ void ipa3_debugfs_init(void)
		goto fail;
	}

	dfile_ipa_usb = debugfs_create_file("ipa_usb", read_only_mode, dent, 0,
		&ipa3_ipa_usb_ops);
	if (!dfile_ipa_usb || IS_ERR(dfile_ipa_usb)) {
		IPAERR("fail to create file for debug_fs ipa_usb\n");
		goto fail;
	}

	file = debugfs_create_u32("enable_clock_scaling", read_write_mode,
		dent, &ipa3_ctx->enable_clock_scaling);
	if (!file) {
+13 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -769,6 +769,16 @@ struct ipa_request_gsi_channel_params {
	union __packed gsi_channel_scratch chan_scratch;
};

struct ipa3_usb_status_dbg_info {
	const char *teth_state;
	const char *dpl_state;
	int num_init_prot;
	const char *inited_prots[IPA_USB_MAX_TETH_PROT_SIZE];
	const char *teth_connected_prot;
	const char *dpl_connected_prot;
	const char *teth_cons_state;
	const char *dpl_cons_state;
};

enum ipa3_sys_pipe_policy {
	IPA_POLICY_INTR_MODE,
@@ -1849,6 +1859,8 @@ int ipa3_usb_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
int ipa3_usb_xdci_resume(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
			enum ipa_usb_teth_prot teth_prot);

int ipa3_usb_get_status_dbg_info(struct ipa3_usb_status_dbg_info *status);

/*
 * Resume / Suspend
 */
+86 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2016 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -164,6 +164,18 @@ static DECLARE_WORK(ipa3_usb_dpl_notify_suspend_completed_work,

struct ipa3_usb_context *ipa3_usb_ctx;

static char *ipa3_usb_cons_state_to_string(enum ipa3_usb_cons_state state)
{
	switch (state) {
	case IPA_USB_CONS_GRANTED:
		return "CONS_GRANTED";
	case IPA_USB_CONS_RELEASED:
		return "CONS_RELEASED";
	}

	return "UNSUPPORTED";
}

static char *ipa3_usb_op_to_string(enum ipa3_usb_op op)
{
	switch (op) {
@@ -1769,6 +1781,79 @@ connect_ul_fail:
	return result;
}

int ipa3_usb_get_status_dbg_info(struct ipa3_usb_status_dbg_info *status)
{
	int res;
	int i;
	unsigned long flags;

	IPA_USB_DBG("entry\n");

	if (ipa3_usb_ctx == NULL) {
		IPA_USB_ERR("IPA USB was not inited yet\n");
		return -EFAULT;
	}

	mutex_lock(&ipa3_usb_ctx->general_mutex);

	if (!status) {
		IPA_USB_ERR("Invalid input\n");
		res = -EINVAL;
		goto bail;
	}

	memset(status, 0, sizeof(struct ipa3_usb_status_dbg_info));

	spin_lock_irqsave(&ipa3_usb_ctx->state_lock, flags);
	status->teth_state = ipa3_usb_state_to_string(
		ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_TETH].state);
	status->dpl_state = ipa3_usb_state_to_string(
		ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_DPL].state);
	if (ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_TETH].rm_ctx.cons_valid)
		status->teth_cons_state = ipa3_usb_cons_state_to_string(
			ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_TETH].
			rm_ctx.cons_state);
	if (ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_DPL].rm_ctx.cons_valid)
		status->dpl_cons_state = ipa3_usb_cons_state_to_string(
			ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_DPL].
			rm_ctx.cons_state);
	spin_unlock_irqrestore(&ipa3_usb_ctx->state_lock, flags);

	for (i = 0 ; i < IPA_USB_MAX_TETH_PROT_SIZE ; i++) {
		if (ipa3_usb_ctx->teth_prot_ctx[i].state ==
			IPA_USB_TETH_PROT_INITIALIZED) {
			if ((i == IPA_USB_RMNET) || (i == IPA_USB_MBIM))
				status->inited_prots[status->num_init_prot++] =
					ipa3_usb_teth_bridge_prot_to_string(i);
			else
				status->inited_prots[status->num_init_prot++] =
					ipa3_usb_teth_prot_to_string(i);
		} else if (ipa3_usb_ctx->teth_prot_ctx[i].state ==
			IPA_USB_TETH_PROT_CONNECTED) {
			switch (i) {
			case IPA_USB_RMNET:
			case IPA_USB_MBIM:
				status->teth_connected_prot =
					ipa3_usb_teth_bridge_prot_to_string(i);
				break;
			case IPA_USB_DIAG:
				status->dpl_connected_prot =
					ipa3_usb_teth_prot_to_string(i);
				break;
			default:
				status->teth_connected_prot =
					ipa3_usb_teth_prot_to_string(i);
			}
		}
	}

	res = 0;
	IPA_USB_DBG("exit\n");
bail:
	mutex_unlock(&ipa3_usb_ctx->general_mutex);
	return res;
}

int ipa3_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params,
			 struct ipa_usb_xdci_chan_params *dl_chan_params,
			 struct ipa_req_chan_out_params *ul_out_params,