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

Commit 60d292b4 authored by Mohammed Javid's avatar Mohammed Javid Committed by Akshay Pandit
Browse files

msm: ipa: Add IOCTL support to get ep_pair info



For QMI dpm port to open, control manager needs
to know about usb/mhi ep details corresponding to
RMNET and RMNET_CV2X tethering.
IPA driver has all endpoint info at one place.
So provide IOCTL interface to get ep_pair info.

Change-Id: Ia5ec0df955ef7794ca992129dab538f65af36211
Signed-off-by: default avatarMohammed Javid <mjavid@codeaurora.org>
parent 2462a36a
Loading
Loading
Loading
Loading
+220 −0
Original line number Diff line number Diff line
@@ -645,6 +645,169 @@ static void ipa3_gsb_msg_free_cb(void *buff, u32 len, u32 type)
	kfree(buff);
}

static void ipa3_get_usb_ep_info(
		struct ipa_ioc_get_ep_info *ep_info,
		struct ipa_ep_pair_info *pair_info
		)
{
	int ep_index = -1, i;

	ep_info->num_ep_pairs = 0;
	for (i = 0; i < ep_info->max_ep_pairs; i++) {
		pair_info[i].consumer_pipe_num = -1;
		pair_info[i].producer_pipe_num = -1;
		pair_info[i].ep_id = -1;
	}

	ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);

	if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) {
		pair_info[ep_info->num_ep_pairs].consumer_pipe_num = ep_index;
		ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB_CONS);
		if ((ep_index != -1) && (ipa3_ctx->ep[ep_index].valid)) {
			pair_info[ep_info->num_ep_pairs].producer_pipe_num =
				ep_index;
			pair_info[ep_info->num_ep_pairs].ep_id =
				IPA_USB0_EP_ID;

			IPADBG("ep_pair_info consumer_pipe_num %d",
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num);
			IPADBG(" producer_pipe_num %d ep_id %d\n",
			pair_info[ep_info->num_ep_pairs].producer_pipe_num,
				pair_info[ep_info->num_ep_pairs].ep_id);
			ep_info->num_ep_pairs++;
		} else {
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num = -1;
			IPADBG("ep_pair_info consumer_pipe_num %d",
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num);
			IPADBG(" producer_pipe_num %d ep_id %d\n",
			pair_info[ep_info->num_ep_pairs].producer_pipe_num,
				pair_info[ep_info->num_ep_pairs].ep_id);
		}
	}

	ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB2_PROD);

	if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) {
		pair_info[ep_info->num_ep_pairs].consumer_pipe_num = ep_index;
		ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB2_CONS);
		if ((ep_index != -1) && (ipa3_ctx->ep[ep_index].valid)) {
			pair_info[ep_info->num_ep_pairs].producer_pipe_num =
				ep_index;
			pair_info[ep_info->num_ep_pairs].ep_id =
				IPA_USB1_EP_ID;

			IPADBG("ep_pair_info consumer_pipe_num %d",
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num);
			IPADBG(" producer_pipe_num %d ep_id %d\n",
			pair_info[ep_info->num_ep_pairs].producer_pipe_num,
				pair_info[ep_info->num_ep_pairs].ep_id);
			ep_info->num_ep_pairs++;
		} else {
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num = -1;
			IPADBG("ep_pair_info consumer_pipe_num %d",
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num);
			IPADBG(" producer_pipe_num %d ep_id %d\n",
			pair_info[ep_info->num_ep_pairs].producer_pipe_num,
				pair_info[ep_info->num_ep_pairs].ep_id);
		}
	}
}

static void ipa3_get_pcie_ep_info(
			struct ipa_ioc_get_ep_info *ep_info,
			struct ipa_ep_pair_info *pair_info
			)
{
	int ep_index = -1, i;

	ep_info->num_ep_pairs = 0;
	for (i = 0; i < ep_info->max_ep_pairs; i++) {
		pair_info[i].consumer_pipe_num = -1;
		pair_info[i].producer_pipe_num = -1;
		pair_info[i].ep_id = -1;
	}

	ep_index = ipa3_get_ep_mapping(IPA_CLIENT_MHI_PROD);

	if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) {
		pair_info[ep_info->num_ep_pairs].consumer_pipe_num = ep_index;
		ep_index = ipa3_get_ep_mapping(IPA_CLIENT_MHI_CONS);
		if ((ep_index != -1) && (ipa3_ctx->ep[ep_index].valid)) {
			pair_info[ep_info->num_ep_pairs].producer_pipe_num =
				ep_index;
			pair_info[ep_info->num_ep_pairs].ep_id =
				IPA_PCIE0_EP_ID;

			IPADBG("ep_pair_info consumer_pipe_num %d",
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num);
			IPADBG(" producer_pipe_num %d ep_id %d\n",
			pair_info[ep_info->num_ep_pairs].producer_pipe_num,
				pair_info[ep_info->num_ep_pairs].ep_id);
			ep_info->num_ep_pairs++;
		} else {
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num = -1;
			IPADBG("ep_pair_info consumer_pipe_num %d",
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num);
			IPADBG(" producer_pipe_num %d ep_id %d\n",
			pair_info[ep_info->num_ep_pairs].producer_pipe_num,
				pair_info[ep_info->num_ep_pairs].ep_id);
		}
	}

	ep_index = ipa3_get_ep_mapping(IPA_CLIENT_MHI2_PROD);

	if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) {
		pair_info[ep_info->num_ep_pairs].consumer_pipe_num = ep_index;
		ep_index = ipa3_get_ep_mapping(IPA_CLIENT_MHI2_CONS);
		if ((ep_index != -1) && (ipa3_ctx->ep[ep_index].valid)) {
			pair_info[ep_info->num_ep_pairs].producer_pipe_num =
				ep_index;
			pair_info[ep_info->num_ep_pairs].ep_id =
				IPA_PCIE1_EP_ID;

			IPADBG("ep_pair_info consumer_pipe_num %d",
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num);
			IPADBG(" producer_pipe_num %d ep_id %d\n",
			pair_info[ep_info->num_ep_pairs].producer_pipe_num,
				pair_info[ep_info->num_ep_pairs].ep_id);
			ep_info->num_ep_pairs++;
		} else {
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num = -1;
			IPADBG("ep_pair_info consumer_pipe_num %d",
			pair_info[ep_info->num_ep_pairs].consumer_pipe_num);
			IPADBG(" producer_pipe_num %d ep_id %d\n",
			pair_info[ep_info->num_ep_pairs].producer_pipe_num,
				pair_info[ep_info->num_ep_pairs].ep_id);
		}
	}
}


static int ipa3_get_ep_info(struct ipa_ioc_get_ep_info *ep_info,
							u8 *param)
{
	int ret = 0;
	struct ipa_ep_pair_info *pair_info = (struct ipa_ep_pair_info *)param;

	switch (ep_info->ep_type) {
	case IPA_DATA_EP_TYP_HSUSB:
		ipa3_get_usb_ep_info(ep_info, pair_info);
		break;

	case IPA_DATA_EP_TYP_PCIE:
		ipa3_get_pcie_ep_info(ep_info, pair_info);
		break;

	default:
		IPAERR_RL("Undefined ep_type %d\n", ep_info->ep_type);
		ret = -EFAULT;
		break;
	}

	return ret;
}

static int ipa3_send_gsb_msg(unsigned long usr_param, uint8_t msg_type)
{
	int retval;
@@ -719,6 +882,7 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
	size_t sz;
	int pre_entry;
	int hdl;
	struct ipa_ioc_get_ep_info ep_info;

	IPADBG("cmd=%x nr=%d\n", cmd, _IOC_NR(cmd));

@@ -2677,6 +2841,62 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
		}
		break;

	case IPA_IOC_GET_PHERIPHERAL_EP_INFO:
		IPADBG("Got IPA_IOC_GET_EP_INFO\n");
		if (ipa3_ctx->ipa_config_is_auto == false)
			return -ENOTTY;
		if (copy_from_user(&ep_info, (const void __user *)arg,
			sizeof(struct ipa_ioc_get_ep_info))) {
			IPAERR_RL("copy_from_user fails\n");
			retval = -EFAULT;
			break;
		}

		if (ep_info.max_ep_pairs != QUERY_MAX_EP_PAIRS)
			IPAERR_RL("unexpected max_ep_pairs %d\n",
			ep_info.max_ep_pairs);

		if (ep_info.ep_pair_size !=
			(QUERY_MAX_EP_PAIRS * sizeof(struct ipa_ep_pair_info)))
			IPAERR_RL("unexpected ep_pair_size %d\n",
			ep_info.max_ep_pairs);

		uptr = ep_info.info;
		if (unlikely(!uptr)) {
			IPAERR_RL("unexpected NULL info\n");
			retval = -EFAULT;
			break;
		}

		param = kzalloc(ep_info.ep_pair_size, GFP_KERNEL);
		if (!param) {
			IPAERR_RL("kzalloc fails\n");
			retval = -ENOMEM;
			break;
		}

		retval = ipa3_get_ep_info(&ep_info, param);
		if (retval < 0) {
			IPAERR("ipa3_get_ep_info failed\n");
			retval = -EFAULT;
			break;
		}

		if (copy_to_user((void __user *)uptr, param,
			ep_info.ep_pair_size)) {
			IPAERR_RL("copy_to_user fails\n");
			retval = -EFAULT;
			break;
		}

		if (copy_to_user((void __user *)arg, &ep_info,
			sizeof(struct ipa_ioc_get_ep_info))) {
			IPAERR_RL("copy_to_user fails\n");
			retval = -EFAULT;
			break;
		}
		break;

	default:
		IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
		return -ENOTTY;
+45 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@
#define IPA_IOCTL_FNR_COUNTER_DEALLOC           75
#define IPA_IOCTL_FNR_COUNTER_QUERY             76
#define IPA_IOCTL_GET_NAT_IN_SRAM_INFO          77
#define IPA_IOCTL_GET_PHERIPHERAL_EP_INFO       78

/**
 * max size of the header to be inserted
@@ -2247,6 +2248,46 @@ struct ipa_ioc_gsb_info {
	char name[IPA_RESOURCE_NAME_MAX];
};

#define QUERY_MAX_EP_PAIRS	2

#define IPA_USB0_EP_ID		11
#define IPA_USB1_EP_ID		12

#define IPA_PCIE0_EP_ID		21
#define IPA_PCIE1_EP_ID		22

enum ipa_peripheral_ep_type {
	IPA_DATA_EP_TYP_RESERVED = 0,
	IPA_DATA_EP_TYP_HSIC = 1,
	IPA_DATA_EP_TYP_HSUSB = 2,
	IPA_DATA_EP_TYP_PCIE = 3,
	IPA_DATA_EP_TYP_EMBEDDED = 4,
	IPA_DATA_EP_TYP_BAM_DMUX,
};

struct ipa_ep_pair_info {
	uint32_t consumer_pipe_num;
	uint32_t producer_pipe_num;
	uint32_t ep_id;
};

/**
 * struct ipa_ioc_get_ep_info - query usb/pcie ep info
 * @ep_type: type USB/PCIE - i/p param
 * @max_ep_pairs: max number of ep_pairs (constant),
					(QUERY_MAX_EP_PAIRS)
 * @num_ep_pairs: number of ep_pairs - o/p param
 * @ep_pair_size: sizeof(ipa_ep_pair_info) * max_ep_pairs
 * @info: structure contains ep pair info
 */
struct ipa_ioc_get_ep_info {
	enum ipa_peripheral_ep_type ep_type;
	uint8_t max_ep_pairs;
	uint8_t num_ep_pairs;
	uint32_t ep_pair_size;
	uintptr_t info;
};

/**
 * struct ipa_ioc_wigig_fst_switch - switch between wigig and wlan
 * @netdev_name: wigig interface name
@@ -2838,6 +2879,10 @@ struct ipa_odl_modem_config {
				IPA_IOCTL_GET_NAT_IN_SRAM_INFO, \
				struct ipa_nat_in_sram_info)

#define IPA_IOC_GET_PHERIPHERAL_EP_INFO _IOWR(IPA_IOC_MAGIC, \
				IPA_IOCTL_GET_PHERIPHERAL_EP_INFO, \
				struct ipa_ioc_get_ep_info)

/*
 * unique magic number of the Tethering bridge ioctls
 */