diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c index cb95f6e98956..4275e3d26157 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c @@ -83,6 +83,10 @@ const char *ipa_event_name[] = { __stringify(IPA_QUOTA_REACH), __stringify(IPA_SSR_BEFORE_SHUTDOWN), __stringify(IPA_SSR_AFTER_POWERUP), + __stringify(ADD_VLAN_IFACE), + __stringify(DEL_VLAN_IFACE), + __stringify(ADD_L2TP_VLAN_MAPPING), + __stringify(DEL_L2TP_VLAN_MAPPING) }; const char *ipa_hdr_l2_type_name[] = { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index a50cd0b807a2..0c52ab44874a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -611,6 +611,90 @@ static int ipa3_send_wan_msg(unsigned long usr_param, uint8_t msg_type) return 0; } +static void ipa3_vlan_l2tp_msg_free_cb(void *buff, u32 len, u32 type) +{ + if (!buff) { + IPAERR("Null buffer\n"); + return; + } + + if (type != ADD_VLAN_IFACE && + type != DEL_VLAN_IFACE && + type != ADD_L2TP_VLAN_MAPPING && + type != DEL_L2TP_VLAN_MAPPING) { + IPAERR("Wrong type given. buff %pK type %d\n", buff, type); + return; + } + + kfree(buff); +} + +static int ipa3_send_vlan_l2tp_msg(unsigned long usr_param, uint8_t msg_type) +{ + int retval; + struct ipa_ioc_vlan_iface_info *vlan_info; + struct ipa_ioc_l2tp_vlan_mapping_info *mapping_info; + struct ipa_msg_meta msg_meta; + + if (msg_type == ADD_VLAN_IFACE || + msg_type == DEL_VLAN_IFACE) { + vlan_info = kzalloc(sizeof(struct ipa_ioc_vlan_iface_info), + GFP_KERNEL); + if (!vlan_info) { + IPAERR("no memory\n"); + return -ENOMEM; + } + + if (copy_from_user((u8 *)vlan_info, (void __user *)usr_param, + sizeof(struct ipa_ioc_vlan_iface_info))) { + kfree(vlan_info); + return -EFAULT; + } + + memset(&msg_meta, 0, sizeof(msg_meta)); + msg_meta.msg_type = msg_type; + msg_meta.msg_len = sizeof(struct ipa_ioc_vlan_iface_info); + retval = ipa3_send_msg(&msg_meta, vlan_info, + ipa3_vlan_l2tp_msg_free_cb); + if (retval) { + IPAERR("ipa3_send_msg failed: %d\n", retval); + kfree(vlan_info); + return retval; + } + } else if (msg_type == ADD_L2TP_VLAN_MAPPING || + msg_type == DEL_L2TP_VLAN_MAPPING) { + mapping_info = kzalloc(sizeof(struct + ipa_ioc_l2tp_vlan_mapping_info), GFP_KERNEL); + if (!mapping_info) { + IPAERR("no memory\n"); + return -ENOMEM; + } + + if (copy_from_user((u8 *)mapping_info, + (void __user *)usr_param, + sizeof(struct ipa_ioc_l2tp_vlan_mapping_info))) { + kfree(mapping_info); + return -EFAULT; + } + + memset(&msg_meta, 0, sizeof(msg_meta)); + msg_meta.msg_type = msg_type; + msg_meta.msg_len = sizeof(struct + ipa_ioc_l2tp_vlan_mapping_info); + retval = ipa3_send_msg(&msg_meta, mapping_info, + ipa3_vlan_l2tp_msg_free_cb); + if (retval) { + IPAERR("ipa3_send_msg failed: %d\n", retval); + kfree(mapping_info); + return retval; + } + } else { + IPAERR("Unexpected event\n"); + return -EFAULT; + } + + return 0; +} static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -1582,6 +1666,34 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; + case IPA_IOC_ADD_VLAN_IFACE: + if (ipa3_send_vlan_l2tp_msg(arg, ADD_VLAN_IFACE)) { + retval = -EFAULT; + break; + } + break; + + case IPA_IOC_DEL_VLAN_IFACE: + if (ipa3_send_vlan_l2tp_msg(arg, DEL_VLAN_IFACE)) { + retval = -EFAULT; + break; + } + break; + + case IPA_IOC_ADD_L2TP_VLAN_MAPPING: + if (ipa3_send_vlan_l2tp_msg(arg, ADD_L2TP_VLAN_MAPPING)) { + retval = -EFAULT; + break; + } + break; + + case IPA_IOC_DEL_L2TP_VLAN_MAPPING: + if (ipa3_send_vlan_l2tp_msg(arg, DEL_L2TP_VLAN_MAPPING)) { + retval = -EFAULT; + break; + } + break; + default: /* redundant, as cmd was checked against MAXNR */ IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return -ENOTTY; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index fbf84ab7d2d4..c7ab616cb5b8 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -64,6 +64,10 @@ const char *ipa3_event_name[] = { __stringify(IPA_QUOTA_REACH), __stringify(IPA_SSR_BEFORE_SHUTDOWN), __stringify(IPA_SSR_AFTER_POWERUP), + __stringify(ADD_VLAN_IFACE), + __stringify(DEL_VLAN_IFACE), + __stringify(ADD_L2TP_VLAN_MAPPING), + __stringify(DEL_L2TP_VLAN_MAPPING) }; const char *ipa3_hdr_l2_type_name[] = { diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h index 51569b7e7aa0..6674538618e2 100644 --- a/include/uapi/linux/msm_ipa.h +++ b/include/uapi/linux/msm_ipa.h @@ -68,7 +68,13 @@ #define IPA_IOCTL_ADD_RT_RULE_AFTER 43 #define IPA_IOCTL_ADD_FLT_RULE_AFTER 44 #define IPA_IOCTL_GET_HW_VERSION 45 -#define IPA_IOCTL_MAX 46 +#define IPA_IOCTL_ADD_RT_RULE_EXT 46 +#define IPA_IOCTL_ADD_VLAN_IFACE 47 +#define IPA_IOCTL_DEL_VLAN_IFACE 48 +#define IPA_IOCTL_ADD_L2TP_VLAN_MAPPING 49 +#define IPA_IOCTL_DEL_L2TP_VLAN_MAPPING 50 +#define IPA_IOCTL_NAT_MODIFY_PDN 51 +#define IPA_IOCTL_MAX 52 /** * max size of the header to be inserted @@ -407,7 +413,16 @@ enum ipa_ssr_event { IPA_SSR_EVENT_MAX }; -#define IPA_EVENT_MAX_NUM ((int)IPA_SSR_EVENT_MAX) +enum ipa_vlan_l2tp_event { + ADD_VLAN_IFACE = IPA_SSR_EVENT_MAX, + DEL_VLAN_IFACE, + ADD_L2TP_VLAN_MAPPING, + DEL_L2TP_VLAN_MAPPING, + IPA_VLAN_L2TP_EVENT_MAX, +}; + +#define IPA_EVENT_MAX_NUM (IPA_VLAN_L2TP_EVENT_MAX) +#define IPA_EVENT_MAX ((int)IPA_EVENT_MAX_NUM) /** * enum ipa_rm_resource_name - IPA RM clients identification names @@ -1358,6 +1373,44 @@ struct ipa_ioc_nat_dma_cmd { }; +/** +* struct ipa_ioc_nat_pdn_entry - PDN entry modification data +* @pdn_index: index of the entry in the PDN config table to be changed +* @public_ip: PDN's public ip +* @src_metadata: PDN's source NAT metadata for metadata replacement +* @dst_metadata: PDN's destination NAT metadata for metadata replacement +*/ +struct ipa_ioc_nat_pdn_entry { + uint8_t pdn_index; + uint32_t public_ip; + uint32_t src_metadata; + uint32_t dst_metadata; +}; + +/** + * struct ipa_ioc_vlan_iface_info - add vlan interface + * @name: interface name + * @vlan_id: VLAN ID + */ +struct ipa_ioc_vlan_iface_info { + char name[IPA_RESOURCE_NAME_MAX]; + uint8_t vlan_id; +}; + +/** + * struct ipa_ioc_l2tp_vlan_mapping_info - l2tp->vlan mapping info + * @iptype: l2tp tunnel IP type + * @l2tp_iface_name: l2tp interface name + * @l2tp_session_id: l2tp session id + * @vlan_iface_name: vlan interface name + */ +struct ipa_ioc_l2tp_vlan_mapping_info { + enum ipa_ip_type iptype; + char l2tp_iface_name[IPA_RESOURCE_NAME_MAX]; + uint8_t l2tp_session_id; + char vlan_iface_name[IPA_RESOURCE_NAME_MAX]; +}; + /** * struct ipa_msg_meta - Format of the message meta-data. * @msg_type: the type of the message @@ -1632,6 +1685,21 @@ enum ipacm_client_enum { IPA_IOCTL_GET_HW_VERSION, \ enum ipa_hw_type *) +#define IPA_IOC_ADD_VLAN_IFACE _IOWR(IPA_IOC_MAGIC, \ + IPA_IOCTL_ADD_VLAN_IFACE, \ + struct ipa_ioc_vlan_iface_info *) + +#define IPA_IOC_DEL_VLAN_IFACE _IOWR(IPA_IOC_MAGIC, \ + IPA_IOCTL_DEL_VLAN_IFACE, \ + struct ipa_ioc_vlan_iface_info *) + +#define IPA_IOC_ADD_L2TP_VLAN_MAPPING _IOWR(IPA_IOC_MAGIC, \ + IPA_IOCTL_ADD_L2TP_VLAN_MAPPING, \ + struct ipa_ioc_l2tp_vlan_mapping_info *) + +#define IPA_IOC_DEL_L2TP_VLAN_MAPPING _IOWR(IPA_IOC_MAGIC, \ + IPA_IOCTL_DEL_L2TP_VLAN_MAPPING, \ + struct ipa_ioc_l2tp_vlan_mapping_info *) /* * unique magic number of the Tethering bridge ioctls */