Loading drivers/platform/msm/ipa/ipa.c +35 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,9 @@ #define IPA_IOC_WRITE_QMAPID32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_WRITE_QMAPID, \ compat_uptr_t) #define IPA_IOC_MDFY_FLT_RULE32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_MDFY_FLT_RULE, \ compat_uptr_t) /** * struct ipa_ioc_nat_alloc_mem32 - nat table memory allocation Loading Loading @@ -441,6 +444,35 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; case IPA_IOC_MDFY_FLT_RULE: if (copy_from_user(header, (u8 *)arg, sizeof(struct ipa_ioc_mdfy_flt_rule))) { retval = -EFAULT; break; } pyld_sz = sizeof(struct ipa_ioc_mdfy_flt_rule) + ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules * sizeof(struct ipa_flt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; break; } if (copy_from_user(param, (u8 *)arg, pyld_sz)) { retval = -EFAULT; break; } if (ipa_mdfy_flt_rule((struct ipa_ioc_mdfy_flt_rule *)param)) { retval = -EFAULT; break; } if (copy_to_user((u8 *)arg, param, pyld_sz)) { retval = -EFAULT; break; } break; case IPA_IOC_COMMIT_HDR: retval = ipa_commit_hdr(); break; Loading Loading @@ -1378,6 +1410,9 @@ ret: case IPA_IOC_WRITE_QMAPID32: cmd = IPA_IOC_WRITE_QMAPID; break; case IPA_IOC_MDFY_FLT_RULE32: cmd = IPA_IOC_MDFY_FLT_RULE; break; case IPA_IOC_COMMIT_HDR: case IPA_IOC_RESET_HDR: case IPA_IOC_COMMIT_RT: Loading drivers/platform/msm/ipa/ipa_flt.c +103 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define IPA_FLT_TABLE_INDEX_NOT_FOUND (-1) #define IPA_FLT_STATUS_OF_ADD_FAILED (-1) #define IPA_FLT_STATUS_OF_DEL_FAILED (-1) #define IPA_FLT_STATUS_OF_MDFY_FAILED (-1) static int ipa_generate_hw_rule_from_eq( const struct ipa_ipfltri_rule_eq *attrib, u8 **buf) Loading Loading @@ -1068,6 +1069,65 @@ static int __ipa_del_flt_rule(u32 rule_hdl) return 0; } static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule, enum ipa_ip_type ip) { struct ipa_flt_entry *entry; struct ipa_rt_tbl *rt_tbl = NULL; entry = ipa_id_find(frule->rule_hdl); if (entry == NULL) { IPAERR("lookup failed\n"); goto error; } if (entry->cookie != IPA_COOKIE) { IPAERR("bad params\n"); goto error; } if (entry->rt_tbl) entry->rt_tbl->ref_cnt--; if (frule->rule.action != IPA_PASS_TO_EXCEPTION) { if (!frule->rule.eq_attrib_type) { if (!frule->rule.rt_tbl_hdl) { IPAERR("invalid RT tbl\n"); goto error; } rt_tbl = ipa_id_find(frule->rule.rt_tbl_hdl); if (rt_tbl == NULL) { IPAERR("RT tbl not found\n"); goto error; } if (rt_tbl->cookie != IPA_COOKIE) { IPAERR("RT table cookie is invalid\n"); goto error; } } else { if (frule->rule.rt_tbl_idx > ((ip == IPA_IP_v4) ? IPA_v2_V4_MODEM_RT_INDEX_HI : IPA_v2_V6_MODEM_RT_INDEX_HI)) { IPAERR("invalid RT tbl\n"); goto error; } } } entry->rule = frule->rule; entry->rt_tbl = rt_tbl; if (entry->rt_tbl) entry->rt_tbl->ref_cnt++; entry->hw_len = 0; return 0; error: return -EPERM; } static int __ipa_add_global_flt_rule(enum ipa_ip_type ip, const struct ipa_flt_rule *rule, u8 add_rear, u32 *rule_hdl) { Loading Loading @@ -1207,6 +1267,49 @@ bail: } EXPORT_SYMBOL(ipa_del_flt_rule); /** * ipa_mdfy_flt_rule() - Modify the specified filtering rules in SW and optionally * commit to IPA HW * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa_mdfy_flt_rule(struct ipa_ioc_mdfy_flt_rule *hdls) { int i; int result; if (hdls == NULL || hdls->num_rules == 0 || hdls->ip >= IPA_IP_MAX) { IPAERR("bad parm\n"); return -EINVAL; } mutex_lock(&ipa_ctx->lock); for (i = 0; i < hdls->num_rules; i++) { if (__ipa_mdfy_flt_rule(&hdls->rules[i], hdls->ip)) { IPAERR("failed to mdfy rt rule %i\n", i); hdls->rules[i].status = IPA_FLT_STATUS_OF_MDFY_FAILED; } else { hdls->rules[i].status = 0; } } if (hdls->commit) if (ipa_ctx->ctrl->ipa_commit_flt(hdls->ip)) { mutex_unlock(&ipa_ctx->lock); result = -EPERM; goto bail; } result = 0; bail: mutex_unlock(&ipa_ctx->lock); return result; } EXPORT_SYMBOL(ipa_mdfy_flt_rule); /** * ipa_commit_flt() - Commit the current SW filtering table of specified type to * IPA HW Loading include/linux/ipa.h +7 −0 Original line number Diff line number Diff line Loading @@ -821,6 +821,8 @@ int ipa_add_flt_rule(struct ipa_ioc_add_flt_rule *rules); int ipa_del_flt_rule(struct ipa_ioc_del_flt_rule *hdls); int ipa_mdfy_flt_rule(struct ipa_ioc_mdfy_flt_rule *rules); int ipa_commit_flt(enum ipa_ip_type ip); int ipa_reset_flt(enum ipa_ip_type ip); Loading Loading @@ -1143,6 +1145,11 @@ static inline int ipa_del_flt_rule(struct ipa_ioc_del_flt_rule *hdls) return -EPERM; } static inline int ipa_mdfy_flt_rule(struct ipa_ioc_mdfy_flt_rule *rules) { return -EPERM; } static inline int ipa_commit_flt(enum ipa_ip_type ip) { return -EPERM; Loading include/uapi/linux/msm_ipa.h +36 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,8 @@ #define IPA_IOCTL_QUERY_EP_MAPPING 33 #define IPA_IOCTL_QUERY_RT_TBL_INDEX 34 #define IPA_IOCTL_WRITE_QMAPID 35 #define IPA_IOCTL_MAX 36 #define IPA_IOCTL_MDFY_FLT_RULE 36 #define IPA_IOCTL_MAX 37 /** * max size of the header to be inserted Loading Loading @@ -671,6 +672,37 @@ struct ipa_ioc_add_flt_rule { struct ipa_flt_rule_add rules[0]; }; /** * struct ipa_flt_rule_mdfy - filtering rule descriptor includes * in and out parameters * @rule: actual rule to be added * @flt_rule_hdl: handle to rule * @status: output parameter, status of filtering rule modify operation, * 0 for success, * -1 for failure * */ struct ipa_flt_rule_mdfy { struct ipa_flt_rule rule; uint32_t rule_hdl; int status; }; /** * struct ipa_ioc_mdfy_flt_rule - filtering rule modify parameters (supports * multiple rules and commit) * @commit: should rules be written to IPA HW also? * @ip: IP family of rule * @num_rules: number of filtering rules that follow * @rules: all rules need to go back to back here, no pointers */ struct ipa_ioc_mdfy_flt_rule { uint8_t commit; enum ipa_ip_type ip; uint8_t num_rules; struct ipa_flt_rule_mdfy rules[0]; }; /** * struct ipa_flt_rule_del - filtering rule descriptor includes * in and out parameters Loading Loading @@ -1112,6 +1144,9 @@ struct ipa_ioc_write_qmapid { #define IPA_IOC_WRITE_QMAPID _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_WRITE_QMAPID, \ struct ipa_ioc_write_qmapid *) #define IPA_IOC_MDFY_FLT_RULE _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_MDFY_FLT_RULE, \ struct ipa_ioc_mdfy_flt_rule *) /* * unique magic number of the Tethering bridge ioctls Loading Loading
drivers/platform/msm/ipa/ipa.c +35 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,9 @@ #define IPA_IOC_WRITE_QMAPID32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_WRITE_QMAPID, \ compat_uptr_t) #define IPA_IOC_MDFY_FLT_RULE32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_MDFY_FLT_RULE, \ compat_uptr_t) /** * struct ipa_ioc_nat_alloc_mem32 - nat table memory allocation Loading Loading @@ -441,6 +444,35 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; case IPA_IOC_MDFY_FLT_RULE: if (copy_from_user(header, (u8 *)arg, sizeof(struct ipa_ioc_mdfy_flt_rule))) { retval = -EFAULT; break; } pyld_sz = sizeof(struct ipa_ioc_mdfy_flt_rule) + ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules * sizeof(struct ipa_flt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; break; } if (copy_from_user(param, (u8 *)arg, pyld_sz)) { retval = -EFAULT; break; } if (ipa_mdfy_flt_rule((struct ipa_ioc_mdfy_flt_rule *)param)) { retval = -EFAULT; break; } if (copy_to_user((u8 *)arg, param, pyld_sz)) { retval = -EFAULT; break; } break; case IPA_IOC_COMMIT_HDR: retval = ipa_commit_hdr(); break; Loading Loading @@ -1378,6 +1410,9 @@ ret: case IPA_IOC_WRITE_QMAPID32: cmd = IPA_IOC_WRITE_QMAPID; break; case IPA_IOC_MDFY_FLT_RULE32: cmd = IPA_IOC_MDFY_FLT_RULE; break; case IPA_IOC_COMMIT_HDR: case IPA_IOC_RESET_HDR: case IPA_IOC_COMMIT_RT: Loading
drivers/platform/msm/ipa/ipa_flt.c +103 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define IPA_FLT_TABLE_INDEX_NOT_FOUND (-1) #define IPA_FLT_STATUS_OF_ADD_FAILED (-1) #define IPA_FLT_STATUS_OF_DEL_FAILED (-1) #define IPA_FLT_STATUS_OF_MDFY_FAILED (-1) static int ipa_generate_hw_rule_from_eq( const struct ipa_ipfltri_rule_eq *attrib, u8 **buf) Loading Loading @@ -1068,6 +1069,65 @@ static int __ipa_del_flt_rule(u32 rule_hdl) return 0; } static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule, enum ipa_ip_type ip) { struct ipa_flt_entry *entry; struct ipa_rt_tbl *rt_tbl = NULL; entry = ipa_id_find(frule->rule_hdl); if (entry == NULL) { IPAERR("lookup failed\n"); goto error; } if (entry->cookie != IPA_COOKIE) { IPAERR("bad params\n"); goto error; } if (entry->rt_tbl) entry->rt_tbl->ref_cnt--; if (frule->rule.action != IPA_PASS_TO_EXCEPTION) { if (!frule->rule.eq_attrib_type) { if (!frule->rule.rt_tbl_hdl) { IPAERR("invalid RT tbl\n"); goto error; } rt_tbl = ipa_id_find(frule->rule.rt_tbl_hdl); if (rt_tbl == NULL) { IPAERR("RT tbl not found\n"); goto error; } if (rt_tbl->cookie != IPA_COOKIE) { IPAERR("RT table cookie is invalid\n"); goto error; } } else { if (frule->rule.rt_tbl_idx > ((ip == IPA_IP_v4) ? IPA_v2_V4_MODEM_RT_INDEX_HI : IPA_v2_V6_MODEM_RT_INDEX_HI)) { IPAERR("invalid RT tbl\n"); goto error; } } } entry->rule = frule->rule; entry->rt_tbl = rt_tbl; if (entry->rt_tbl) entry->rt_tbl->ref_cnt++; entry->hw_len = 0; return 0; error: return -EPERM; } static int __ipa_add_global_flt_rule(enum ipa_ip_type ip, const struct ipa_flt_rule *rule, u8 add_rear, u32 *rule_hdl) { Loading Loading @@ -1207,6 +1267,49 @@ bail: } EXPORT_SYMBOL(ipa_del_flt_rule); /** * ipa_mdfy_flt_rule() - Modify the specified filtering rules in SW and optionally * commit to IPA HW * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa_mdfy_flt_rule(struct ipa_ioc_mdfy_flt_rule *hdls) { int i; int result; if (hdls == NULL || hdls->num_rules == 0 || hdls->ip >= IPA_IP_MAX) { IPAERR("bad parm\n"); return -EINVAL; } mutex_lock(&ipa_ctx->lock); for (i = 0; i < hdls->num_rules; i++) { if (__ipa_mdfy_flt_rule(&hdls->rules[i], hdls->ip)) { IPAERR("failed to mdfy rt rule %i\n", i); hdls->rules[i].status = IPA_FLT_STATUS_OF_MDFY_FAILED; } else { hdls->rules[i].status = 0; } } if (hdls->commit) if (ipa_ctx->ctrl->ipa_commit_flt(hdls->ip)) { mutex_unlock(&ipa_ctx->lock); result = -EPERM; goto bail; } result = 0; bail: mutex_unlock(&ipa_ctx->lock); return result; } EXPORT_SYMBOL(ipa_mdfy_flt_rule); /** * ipa_commit_flt() - Commit the current SW filtering table of specified type to * IPA HW Loading
include/linux/ipa.h +7 −0 Original line number Diff line number Diff line Loading @@ -821,6 +821,8 @@ int ipa_add_flt_rule(struct ipa_ioc_add_flt_rule *rules); int ipa_del_flt_rule(struct ipa_ioc_del_flt_rule *hdls); int ipa_mdfy_flt_rule(struct ipa_ioc_mdfy_flt_rule *rules); int ipa_commit_flt(enum ipa_ip_type ip); int ipa_reset_flt(enum ipa_ip_type ip); Loading Loading @@ -1143,6 +1145,11 @@ static inline int ipa_del_flt_rule(struct ipa_ioc_del_flt_rule *hdls) return -EPERM; } static inline int ipa_mdfy_flt_rule(struct ipa_ioc_mdfy_flt_rule *rules) { return -EPERM; } static inline int ipa_commit_flt(enum ipa_ip_type ip) { return -EPERM; Loading
include/uapi/linux/msm_ipa.h +36 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,8 @@ #define IPA_IOCTL_QUERY_EP_MAPPING 33 #define IPA_IOCTL_QUERY_RT_TBL_INDEX 34 #define IPA_IOCTL_WRITE_QMAPID 35 #define IPA_IOCTL_MAX 36 #define IPA_IOCTL_MDFY_FLT_RULE 36 #define IPA_IOCTL_MAX 37 /** * max size of the header to be inserted Loading Loading @@ -671,6 +672,37 @@ struct ipa_ioc_add_flt_rule { struct ipa_flt_rule_add rules[0]; }; /** * struct ipa_flt_rule_mdfy - filtering rule descriptor includes * in and out parameters * @rule: actual rule to be added * @flt_rule_hdl: handle to rule * @status: output parameter, status of filtering rule modify operation, * 0 for success, * -1 for failure * */ struct ipa_flt_rule_mdfy { struct ipa_flt_rule rule; uint32_t rule_hdl; int status; }; /** * struct ipa_ioc_mdfy_flt_rule - filtering rule modify parameters (supports * multiple rules and commit) * @commit: should rules be written to IPA HW also? * @ip: IP family of rule * @num_rules: number of filtering rules that follow * @rules: all rules need to go back to back here, no pointers */ struct ipa_ioc_mdfy_flt_rule { uint8_t commit; enum ipa_ip_type ip; uint8_t num_rules; struct ipa_flt_rule_mdfy rules[0]; }; /** * struct ipa_flt_rule_del - filtering rule descriptor includes * in and out parameters Loading Loading @@ -1112,6 +1144,9 @@ struct ipa_ioc_write_qmapid { #define IPA_IOC_WRITE_QMAPID _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_WRITE_QMAPID, \ struct ipa_ioc_write_qmapid *) #define IPA_IOC_MDFY_FLT_RULE _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_MDFY_FLT_RULE, \ struct ipa_ioc_mdfy_flt_rule *) /* * unique magic number of the Tethering bridge ioctls Loading