Merge "msm: ipa: Add IOCTL support to get ep_pair info"

This commit is contained in:
Linux Build Service Account 2019-08-09 03:00:04 -07:00 committed by Gerrit - the friendly Code Review server
commit 6b2d48887b
2 changed files with 280 additions and 1 deletions

View File

@ -624,6 +624,185 @@ 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;
@ -689,8 +868,10 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
struct ipa_ioc_rm_dependency rm_depend;
struct ipa_ioc_nat_dma_cmd *table_dma_cmd;
struct ipa_ioc_get_vlan_mode vlan_mode;
struct ipa_ioc_get_ep_info ep_info;
size_t sz;
int pre_entry;
unsigned long uptr = 0;
IPADBG("cmd=%x nr=%d\n", cmd, _IOC_NR(cmd));
@ -1878,6 +2059,60 @@ 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 (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;

View File

@ -107,7 +107,7 @@
#define IPA_IOCTL_DEL_BRIDGE_VLAN_MAPPING 60
#define IPA_IOCTL_GSB_CONNECT 61
#define IPA_IOCTL_GSB_DISCONNECT 62
#define IPA_IOCTL_GET_PHERIPHERAL_EP_INFO 63
/**
@ -1750,6 +1750,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 - flt/rt counter id query
* @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_msg_meta - Format of the message meta-data.
* @msg_type: the type of the message
@ -2191,6 +2231,10 @@ struct ipa_ioc_bridge_vlan_mapping_info {
IPA_IOCTL_GSB_DISCONNECT, \
struct ipa_ioc_gsb_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
*/