Loading drivers/platform/msm/ipa/ipa.c +35 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,9 @@ #define IPA_IOC_DEL_HDR_PROC_CTX32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_DEL_HDR_PROC_CTX, \ compat_uptr_t) #define IPA_IOC_MDFY_RT_RULE32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_MDFY_RT_RULE, \ compat_uptr_t) /** * struct ipa_ioc_nat_alloc_mem32 - nat table memory allocation Loading Loading @@ -443,6 +446,35 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; case IPA_IOC_MDFY_RT_RULE: if (copy_from_user(header, (u8 *)arg, sizeof(struct ipa_ioc_mdfy_rt_rule))) { retval = -EFAULT; break; } pyld_sz = sizeof(struct ipa_ioc_mdfy_rt_rule) + ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules * sizeof(struct ipa_rt_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_rt_rule((struct ipa_ioc_mdfy_rt_rule *)param)) { retval = -EFAULT; break; } if (copy_to_user((u8 *)arg, param, pyld_sz)) { retval = -EFAULT; break; } break; case IPA_IOC_DEL_RT_RULE: if (copy_from_user(header, (u8 *)arg, sizeof(struct ipa_ioc_del_rt_rule))) { Loading Loading @@ -2192,6 +2224,9 @@ ret: case IPA_IOC_NOTIFY_WAN_EMBMS_CONNECTED32: cmd = IPA_IOC_NOTIFY_WAN_EMBMS_CONNECTED; break; case IPA_IOC_MDFY_RT_RULE32: cmd = IPA_IOC_MDFY_RT_RULE; break; case IPA_IOC_COMMIT_HDR: case IPA_IOC_RESET_HDR: case IPA_IOC_COMMIT_RT: Loading drivers/platform/msm/ipa/ipa_debugfs.c +2 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ const char *ipa_event_name[] = { __stringify(WLAN_STA_CONNECT), __stringify(WLAN_STA_DISCONNECT), __stringify(WLAN_CLIENT_CONNECT_EX), __stringify(WLAN_SWITCH_TO_SCC), __stringify(WLAN_SWITCH_TO_MCC), __stringify(WAN_UPSTREAM_ROUTE_ADD), __stringify(WAN_UPSTREAM_ROUTE_DEL), __stringify(WAN_EMBMS_CONNECT), Loading drivers/platform/msm/ipa/ipa_rt.c +82 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #define IPA_RT_BIT_MASK (0x1) #define IPA_RT_STATUS_OF_ADD_FAILED (-1) #define IPA_RT_STATUS_OF_DEL_FAILED (-1) #define IPA_RT_STATUS_OF_MDFY_FAILED (-1) /** * __ipa_generate_rt_hw_rule_v2() - generates the routing hardware rule Loading Loading @@ -1337,3 +1338,84 @@ ret: return result; } EXPORT_SYMBOL(ipa_put_rt_tbl); static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule) { struct ipa_rt_entry *entry; struct ipa_hdr_entry *hdr = NULL; if (rtrule->rule.hdr_hdl) { hdr = ipa_id_find(rtrule->rule.hdr_hdl); if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) { IPAERR("rt rule does not point to valid hdr\n"); goto error; } } entry = ipa_id_find(rtrule->rt_rule_hdl); if (entry == NULL) { IPAERR("lookup failed\n"); goto error; } if (entry->cookie != IPA_COOKIE) { IPAERR("bad params\n"); goto error; } if (entry->hdr) entry->hdr->ref_cnt--; entry->rule = rtrule->rule; entry->hdr = hdr; if (entry->hdr) entry->hdr->ref_cnt++; return 0; error: return -EPERM; } /** * ipa_mdfy_rt_rule() - Modify the specified routing 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_rt_rule(struct ipa_ioc_mdfy_rt_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_rt_rule(&hdls->rules[i])) { IPAERR("failed to mdfy rt rule %i\n", i); hdls->rules[i].status = IPA_RT_STATUS_OF_MDFY_FAILED; } else { hdls->rules[i].status = 0; } } if (hdls->commit) if (ipa_ctx->ctrl->ipa_commit_rt(hdls->ip)) { result = -EPERM; goto bail; } result = 0; bail: mutex_unlock(&ipa_ctx->lock); return result; } EXPORT_SYMBOL(ipa_mdfy_rt_rule); include/linux/ipa.h +7 −0 Original line number Diff line number Diff line Loading @@ -1010,6 +1010,8 @@ int ipa_put_rt_tbl(u32 rt_tbl_hdl); int ipa_query_rt_index(struct ipa_ioc_get_rt_tbl_indx *in); int ipa_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *rules); /* * Filtering */ Loading Loading @@ -1381,6 +1383,11 @@ static inline int ipa_query_rt_index(struct ipa_ioc_get_rt_tbl_indx *in) return -EPERM; } static inline int ipa_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *rules) { return -EPERM; } /* * Filtering */ Loading include/uapi/linux/msm_ipa.h +43 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,8 @@ #define IPA_IOCTL_NOTIFY_WAN_EMBMS_CONNECTED 39 #define IPA_IOCTL_ADD_HDR_PROC_CTX 40 #define IPA_IOCTL_DEL_HDR_PROC_CTX 41 #define IPA_IOCTL_MAX 42 #define IPA_IOCTL_MDFY_RT_RULE 42 #define IPA_IOCTL_MAX 43 /** * max size of the header to be inserted Loading Loading @@ -250,6 +251,9 @@ enum ipa_flt_action { * wlan ap disconnect: wlan AP(access point) is down * wlan sta connect: wlan STA(station) is up * wlan sta disconnect: wlan STA(station) is down * wlan client connect ex: new wlan client connected * wlan scc switch: wlan interfaces in scc mode * wlan mcc switch: wlan interfaces in mcc mode */ enum ipa_wlan_event { WLAN_CLIENT_CONNECT, Loading @@ -263,6 +267,8 @@ enum ipa_wlan_event { WLAN_STA_CONNECT, WLAN_STA_DISCONNECT, WLAN_CLIENT_CONNECT_EX, WLAN_SWITCH_TO_SCC, WLAN_SWITCH_TO_MCC, IPA_WLAN_EVENT_MAX }; Loading Loading @@ -782,6 +788,37 @@ struct ipa_ioc_add_rt_rule { struct ipa_rt_rule_add rules[0]; }; /** * struct ipa_rt_rule_mdfy - routing rule descriptor includes * in and out parameters * @rule: actual rule to be added * @rt_rule_hdl: handle to rule which supposed to modify * @status: output parameter, status of routing rule modify operation, * 0 for success, * -1 for failure * */ struct ipa_rt_rule_mdfy { struct ipa_rt_rule rule; uint32_t rt_rule_hdl; int status; }; /** * struct ipa_ioc_mdfy_rt_rule - routing 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 routing rules that follow * @rules: all rules need to go back to back here, no pointers */ struct ipa_ioc_mdfy_rt_rule { uint8_t commit; enum ipa_ip_type ip; uint8_t num_rules; struct ipa_rt_rule_mdfy rules[0]; }; /** * struct ipa_rt_rule_del - routing rule descriptor includes in * and out parameters Loading Loading @@ -963,6 +1000,7 @@ struct ipa_ioc_query_intf { * @ip: IP family of routing rule * @attrib: routing rule * @dst_pipe: routing output pipe * @alt_dst_pipe: alternate routing output pipe * @hdr_name: name of associated header if any, empty string when no header * @hdr_l2_type: type of associated header if any, use NONE when no header */ Loading @@ -970,6 +1008,7 @@ struct ipa_ioc_tx_intf_prop { enum ipa_ip_type ip; struct ipa_rule_attrib attrib; enum ipa_client_type dst_pipe; enum ipa_client_type alt_dst_pipe; char hdr_name[IPA_RESOURCE_NAME_MAX]; enum ipa_hdr_l2_type hdr_l2_type; }; Loading Loading @@ -1354,6 +1393,9 @@ 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 *) #define IPA_IOC_MDFY_RT_RULE _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_MDFY_RT_RULE, \ struct ipa_ioc_mdfy_rt_rule *) #define IPA_IOC_NOTIFY_WAN_UPSTREAM_ROUTE_ADD _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_NOTIFY_WAN_UPSTREAM_ROUTE_ADD, \ Loading Loading
drivers/platform/msm/ipa/ipa.c +35 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,9 @@ #define IPA_IOC_DEL_HDR_PROC_CTX32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_DEL_HDR_PROC_CTX, \ compat_uptr_t) #define IPA_IOC_MDFY_RT_RULE32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_MDFY_RT_RULE, \ compat_uptr_t) /** * struct ipa_ioc_nat_alloc_mem32 - nat table memory allocation Loading Loading @@ -443,6 +446,35 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; case IPA_IOC_MDFY_RT_RULE: if (copy_from_user(header, (u8 *)arg, sizeof(struct ipa_ioc_mdfy_rt_rule))) { retval = -EFAULT; break; } pyld_sz = sizeof(struct ipa_ioc_mdfy_rt_rule) + ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules * sizeof(struct ipa_rt_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_rt_rule((struct ipa_ioc_mdfy_rt_rule *)param)) { retval = -EFAULT; break; } if (copy_to_user((u8 *)arg, param, pyld_sz)) { retval = -EFAULT; break; } break; case IPA_IOC_DEL_RT_RULE: if (copy_from_user(header, (u8 *)arg, sizeof(struct ipa_ioc_del_rt_rule))) { Loading Loading @@ -2192,6 +2224,9 @@ ret: case IPA_IOC_NOTIFY_WAN_EMBMS_CONNECTED32: cmd = IPA_IOC_NOTIFY_WAN_EMBMS_CONNECTED; break; case IPA_IOC_MDFY_RT_RULE32: cmd = IPA_IOC_MDFY_RT_RULE; break; case IPA_IOC_COMMIT_HDR: case IPA_IOC_RESET_HDR: case IPA_IOC_COMMIT_RT: Loading
drivers/platform/msm/ipa/ipa_debugfs.c +2 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ const char *ipa_event_name[] = { __stringify(WLAN_STA_CONNECT), __stringify(WLAN_STA_DISCONNECT), __stringify(WLAN_CLIENT_CONNECT_EX), __stringify(WLAN_SWITCH_TO_SCC), __stringify(WLAN_SWITCH_TO_MCC), __stringify(WAN_UPSTREAM_ROUTE_ADD), __stringify(WAN_UPSTREAM_ROUTE_DEL), __stringify(WAN_EMBMS_CONNECT), Loading
drivers/platform/msm/ipa/ipa_rt.c +82 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #define IPA_RT_BIT_MASK (0x1) #define IPA_RT_STATUS_OF_ADD_FAILED (-1) #define IPA_RT_STATUS_OF_DEL_FAILED (-1) #define IPA_RT_STATUS_OF_MDFY_FAILED (-1) /** * __ipa_generate_rt_hw_rule_v2() - generates the routing hardware rule Loading Loading @@ -1337,3 +1338,84 @@ ret: return result; } EXPORT_SYMBOL(ipa_put_rt_tbl); static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule) { struct ipa_rt_entry *entry; struct ipa_hdr_entry *hdr = NULL; if (rtrule->rule.hdr_hdl) { hdr = ipa_id_find(rtrule->rule.hdr_hdl); if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) { IPAERR("rt rule does not point to valid hdr\n"); goto error; } } entry = ipa_id_find(rtrule->rt_rule_hdl); if (entry == NULL) { IPAERR("lookup failed\n"); goto error; } if (entry->cookie != IPA_COOKIE) { IPAERR("bad params\n"); goto error; } if (entry->hdr) entry->hdr->ref_cnt--; entry->rule = rtrule->rule; entry->hdr = hdr; if (entry->hdr) entry->hdr->ref_cnt++; return 0; error: return -EPERM; } /** * ipa_mdfy_rt_rule() - Modify the specified routing 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_rt_rule(struct ipa_ioc_mdfy_rt_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_rt_rule(&hdls->rules[i])) { IPAERR("failed to mdfy rt rule %i\n", i); hdls->rules[i].status = IPA_RT_STATUS_OF_MDFY_FAILED; } else { hdls->rules[i].status = 0; } } if (hdls->commit) if (ipa_ctx->ctrl->ipa_commit_rt(hdls->ip)) { result = -EPERM; goto bail; } result = 0; bail: mutex_unlock(&ipa_ctx->lock); return result; } EXPORT_SYMBOL(ipa_mdfy_rt_rule);
include/linux/ipa.h +7 −0 Original line number Diff line number Diff line Loading @@ -1010,6 +1010,8 @@ int ipa_put_rt_tbl(u32 rt_tbl_hdl); int ipa_query_rt_index(struct ipa_ioc_get_rt_tbl_indx *in); int ipa_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *rules); /* * Filtering */ Loading Loading @@ -1381,6 +1383,11 @@ static inline int ipa_query_rt_index(struct ipa_ioc_get_rt_tbl_indx *in) return -EPERM; } static inline int ipa_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *rules) { return -EPERM; } /* * Filtering */ Loading
include/uapi/linux/msm_ipa.h +43 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,8 @@ #define IPA_IOCTL_NOTIFY_WAN_EMBMS_CONNECTED 39 #define IPA_IOCTL_ADD_HDR_PROC_CTX 40 #define IPA_IOCTL_DEL_HDR_PROC_CTX 41 #define IPA_IOCTL_MAX 42 #define IPA_IOCTL_MDFY_RT_RULE 42 #define IPA_IOCTL_MAX 43 /** * max size of the header to be inserted Loading Loading @@ -250,6 +251,9 @@ enum ipa_flt_action { * wlan ap disconnect: wlan AP(access point) is down * wlan sta connect: wlan STA(station) is up * wlan sta disconnect: wlan STA(station) is down * wlan client connect ex: new wlan client connected * wlan scc switch: wlan interfaces in scc mode * wlan mcc switch: wlan interfaces in mcc mode */ enum ipa_wlan_event { WLAN_CLIENT_CONNECT, Loading @@ -263,6 +267,8 @@ enum ipa_wlan_event { WLAN_STA_CONNECT, WLAN_STA_DISCONNECT, WLAN_CLIENT_CONNECT_EX, WLAN_SWITCH_TO_SCC, WLAN_SWITCH_TO_MCC, IPA_WLAN_EVENT_MAX }; Loading Loading @@ -782,6 +788,37 @@ struct ipa_ioc_add_rt_rule { struct ipa_rt_rule_add rules[0]; }; /** * struct ipa_rt_rule_mdfy - routing rule descriptor includes * in and out parameters * @rule: actual rule to be added * @rt_rule_hdl: handle to rule which supposed to modify * @status: output parameter, status of routing rule modify operation, * 0 for success, * -1 for failure * */ struct ipa_rt_rule_mdfy { struct ipa_rt_rule rule; uint32_t rt_rule_hdl; int status; }; /** * struct ipa_ioc_mdfy_rt_rule - routing 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 routing rules that follow * @rules: all rules need to go back to back here, no pointers */ struct ipa_ioc_mdfy_rt_rule { uint8_t commit; enum ipa_ip_type ip; uint8_t num_rules; struct ipa_rt_rule_mdfy rules[0]; }; /** * struct ipa_rt_rule_del - routing rule descriptor includes in * and out parameters Loading Loading @@ -963,6 +1000,7 @@ struct ipa_ioc_query_intf { * @ip: IP family of routing rule * @attrib: routing rule * @dst_pipe: routing output pipe * @alt_dst_pipe: alternate routing output pipe * @hdr_name: name of associated header if any, empty string when no header * @hdr_l2_type: type of associated header if any, use NONE when no header */ Loading @@ -970,6 +1008,7 @@ struct ipa_ioc_tx_intf_prop { enum ipa_ip_type ip; struct ipa_rule_attrib attrib; enum ipa_client_type dst_pipe; enum ipa_client_type alt_dst_pipe; char hdr_name[IPA_RESOURCE_NAME_MAX]; enum ipa_hdr_l2_type hdr_l2_type; }; Loading Loading @@ -1354,6 +1393,9 @@ 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 *) #define IPA_IOC_MDFY_RT_RULE _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_MDFY_RT_RULE, \ struct ipa_ioc_mdfy_rt_rule *) #define IPA_IOC_NOTIFY_WAN_UPSTREAM_ROUTE_ADD _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_NOTIFY_WAN_UPSTREAM_ROUTE_ADD, \ Loading