Loading drivers/platform/msm/ipa/ipa_v3/ipa.c +220 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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; Loading include/uapi/linux/msm_ipa.h +45 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 */ Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa.c +220 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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; Loading
include/uapi/linux/msm_ipa.h +45 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 */ Loading