Loading drivers/platform/msm/ipa/ipa_api.c +83 −17 Original line number Original line Diff line number Diff line Loading @@ -703,6 +703,26 @@ int ipa_add_hdr(struct ipa_ioc_add_hdr *hdrs) } } EXPORT_SYMBOL(ipa_add_hdr); EXPORT_SYMBOL(ipa_add_hdr); /** * ipa_add_hdr_usr() - add the specified headers to SW and optionally * commit them to IPA HW * @hdrs: [inout] set of headers to add * @user_only: [in] indicate rules installed by userspace * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa_add_hdr_usr(struct ipa_ioc_add_hdr *hdrs, bool user_only) { int ret; IPA_API_DISPATCH_RETURN(ipa_add_hdr_usr, hdrs, user_only); return ret; } EXPORT_SYMBOL(ipa_add_hdr_usr); /** /** * ipa_del_hdr() - Remove the specified headers from SW and optionally * ipa_del_hdr() - Remove the specified headers from SW and optionally * commit them to IPA HW * commit them to IPA HW Loading Loading @@ -743,15 +763,16 @@ EXPORT_SYMBOL(ipa_commit_hdr); * ipa_reset_hdr() - reset the current header table in SW (does not commit to * ipa_reset_hdr() - reset the current header table in SW (does not commit to * HW) * HW) * * * @user_only: [in] indicate delete rules installed by userspace * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa_reset_hdr(void) int ipa_reset_hdr(bool user_only) { { int ret; int ret; IPA_API_DISPATCH_RETURN(ipa_reset_hdr); IPA_API_DISPATCH_RETURN(ipa_reset_hdr, user_only); return ret; return ret; } } Loading Loading @@ -821,16 +842,18 @@ EXPORT_SYMBOL(ipa_copy_hdr); * ipa_add_hdr_proc_ctx() - add the specified headers to SW * ipa_add_hdr_proc_ctx() - add the specified headers to SW * and optionally commit them to IPA HW * and optionally commit them to IPA HW * @proc_ctxs: [inout] set of processing context headers to add * @proc_ctxs: [inout] set of processing context headers to add * @user_only: [in] indicate rules installed by userspace * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs) int ipa_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs, bool user_only) { { int ret; int ret; IPA_API_DISPATCH_RETURN(ipa_add_hdr_proc_ctx, proc_ctxs); IPA_API_DISPATCH_RETURN(ipa_add_hdr_proc_ctx, proc_ctxs, user_only); return ret; return ret; } } Loading Loading @@ -875,6 +898,26 @@ int ipa_add_rt_rule(struct ipa_ioc_add_rt_rule *rules) } } EXPORT_SYMBOL(ipa_add_rt_rule); EXPORT_SYMBOL(ipa_add_rt_rule); /** * ipa_add_rt_rule_usr() - Add the specified routing rules to SW and optionally * commit to IPA HW * @rules: [inout] set of routing rules to add * @user_only: [in] indicate rules installed by userspace * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa_add_rt_rule_usr(struct ipa_ioc_add_rt_rule *rules, bool user_only) { int ret; IPA_API_DISPATCH_RETURN(ipa_add_rt_rule_usr, rules, user_only); return ret; } EXPORT_SYMBOL(ipa_add_rt_rule_usr); /** /** * ipa_del_rt_rule() - Remove the specified routing rules to SW and optionally * ipa_del_rt_rule() - Remove the specified routing rules to SW and optionally * commit to IPA HW * commit to IPA HW Loading Loading @@ -917,16 +960,17 @@ EXPORT_SYMBOL(ipa_commit_rt); * ipa_reset_rt() - reset the current SW routing table of specified type * ipa_reset_rt() - reset the current SW routing table of specified type * (does not commit to HW) * (does not commit to HW) * @ip: The family of routing tables * @ip: The family of routing tables * @user_only: [in] indicate delete rules installed by userspace * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa_reset_rt(enum ipa_ip_type ip) int ipa_reset_rt(enum ipa_ip_type ip, bool user_only) { { int ret; int ret; IPA_API_DISPATCH_RETURN(ipa_reset_rt, ip); IPA_API_DISPATCH_RETURN(ipa_reset_rt, ip, user_only); return ret; return ret; } } Loading Loading @@ -1009,6 +1053,7 @@ EXPORT_SYMBOL(ipa_mdfy_rt_rule); /** /** * ipa_add_flt_rule() - Add the specified filtering rules to SW and optionally * ipa_add_flt_rule() - Add the specified filtering rules to SW and optionally * commit to IPA HW * commit to IPA HW * @rules: [inout] set of filtering rules to add * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * Loading @@ -1024,6 +1069,26 @@ int ipa_add_flt_rule(struct ipa_ioc_add_flt_rule *rules) } } EXPORT_SYMBOL(ipa_add_flt_rule); EXPORT_SYMBOL(ipa_add_flt_rule); /** * ipa_add_flt_rule_usr() - Add the specified filtering rules to * SW and optionally commit to IPA HW * @rules: [inout] set of filtering rules to add * @user_only: [in] indicate rules installed by userspace * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa_add_flt_rule_usr(struct ipa_ioc_add_flt_rule *rules, bool user_only) { int ret; IPA_API_DISPATCH_RETURN(ipa_add_flt_rule_usr, rules, user_only); return ret; } EXPORT_SYMBOL(ipa_add_flt_rule_usr); /** /** * ipa_del_flt_rule() - Remove the specified filtering rules from SW and * ipa_del_flt_rule() - Remove the specified filtering rules from SW and * optionally commit to IPA HW * optionally commit to IPA HW Loading Loading @@ -1083,16 +1148,17 @@ EXPORT_SYMBOL(ipa_commit_flt); * ipa_reset_flt() - Reset the current SW filtering table of specified type * ipa_reset_flt() - Reset the current SW filtering table of specified type * (does not commit to HW) * (does not commit to HW) * @ip: [in] the family of routing tables * @ip: [in] the family of routing tables * @user_only: [in] indicate delete rules installed by userspace * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa_reset_flt(enum ipa_ip_type ip) int ipa_reset_flt(enum ipa_ip_type ip, bool user_only) { { int ret; int ret; IPA_API_DISPATCH_RETURN(ipa_reset_flt, ip); IPA_API_DISPATCH_RETURN(ipa_reset_flt, ip, user_only); return ret; return ret; } } Loading drivers/platform/msm/ipa/ipa_api.h +13 −4 Original line number Original line Diff line number Diff line Loading @@ -68,11 +68,13 @@ struct ipa_api_controller { int (*ipa_add_hdr)(struct ipa_ioc_add_hdr *hdrs); int (*ipa_add_hdr)(struct ipa_ioc_add_hdr *hdrs); int (*ipa_add_hdr_usr)(struct ipa_ioc_add_hdr *hdrs, bool user_only); int (*ipa_del_hdr)(struct ipa_ioc_del_hdr *hdls); int (*ipa_del_hdr)(struct ipa_ioc_del_hdr *hdls); int (*ipa_commit_hdr)(void); int (*ipa_commit_hdr)(void); int (*ipa_reset_hdr)(void); int (*ipa_reset_hdr)(bool user_only); int (*ipa_get_hdr)(struct ipa_ioc_get_hdr *lookup); int (*ipa_get_hdr)(struct ipa_ioc_get_hdr *lookup); Loading @@ -80,17 +82,21 @@ struct ipa_api_controller { int (*ipa_copy_hdr)(struct ipa_ioc_copy_hdr *copy); int (*ipa_copy_hdr)(struct ipa_ioc_copy_hdr *copy); int (*ipa_add_hdr_proc_ctx)(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs); int (*ipa_add_hdr_proc_ctx)(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs, bool user_only); int (*ipa_del_hdr_proc_ctx)(struct ipa_ioc_del_hdr_proc_ctx *hdls); int (*ipa_del_hdr_proc_ctx)(struct ipa_ioc_del_hdr_proc_ctx *hdls); int (*ipa_add_rt_rule)(struct ipa_ioc_add_rt_rule *rules); int (*ipa_add_rt_rule)(struct ipa_ioc_add_rt_rule *rules); int (*ipa_add_rt_rule_usr)(struct ipa_ioc_add_rt_rule *rules, bool user_only); int (*ipa_del_rt_rule)(struct ipa_ioc_del_rt_rule *hdls); int (*ipa_del_rt_rule)(struct ipa_ioc_del_rt_rule *hdls); int (*ipa_commit_rt)(enum ipa_ip_type ip); int (*ipa_commit_rt)(enum ipa_ip_type ip); int (*ipa_reset_rt)(enum ipa_ip_type ip); int (*ipa_reset_rt)(enum ipa_ip_type ip, bool user_only); int (*ipa_get_rt_tbl)(struct ipa_ioc_get_rt_tbl *lookup); int (*ipa_get_rt_tbl)(struct ipa_ioc_get_rt_tbl *lookup); Loading @@ -102,13 +108,16 @@ struct ipa_api_controller { int (*ipa_add_flt_rule)(struct ipa_ioc_add_flt_rule *rules); int (*ipa_add_flt_rule)(struct ipa_ioc_add_flt_rule *rules); int (*ipa_add_flt_rule_usr)(struct ipa_ioc_add_flt_rule *rules, bool user_only); int (*ipa_del_flt_rule)(struct ipa_ioc_del_flt_rule *hdls); 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_mdfy_flt_rule)(struct ipa_ioc_mdfy_flt_rule *rules); int (*ipa_commit_flt)(enum ipa_ip_type ip); int (*ipa_commit_flt)(enum ipa_ip_type ip); int (*ipa_reset_flt)(enum ipa_ip_type ip); int (*ipa_reset_flt)(enum ipa_ip_type ip, bool user_only); int (*ipa_allocate_nat_device)(struct ipa_ioc_nat_alloc_mem *mem); int (*ipa_allocate_nat_device)(struct ipa_ioc_nat_alloc_mem *mem); Loading drivers/platform/msm/ipa/ipa_common_i.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -333,11 +333,13 @@ struct ipa_mhi_connect_params_internal { * @link: entry's link in global header offset entries list * @link: entry's link in global header offset entries list * @offset: the offset * @offset: the offset * @bin: bin * @bin: bin * @ipacm_installed: indicate if installed by ipacm */ */ struct ipa_hdr_offset_entry { struct ipa_hdr_offset_entry { struct list_head link; struct list_head link; u32 offset; u32 offset; u32 bin; u32 bin; bool ipacm_installed; }; }; extern const char *ipa_clients_strings[]; extern const char *ipa_clients_strings[]; Loading drivers/platform/msm/ipa/ipa_v3/ipa.c +66 −7 Original line number Original line Diff line number Diff line Loading @@ -369,6 +369,43 @@ int ipa3_active_clients_log_print_table(char *buf, int size) return cnt; return cnt; } } static int ipa3_clean_modem_rule(void) { struct ipa_install_fltr_rule_req_msg_v01 *req; struct ipa_install_fltr_rule_req_ex_msg_v01 *req_ex; int val = 0; if (ipa3_ctx->ipa_hw_type < IPA_HW_v3_0) { req = kzalloc( sizeof(struct ipa_install_fltr_rule_req_msg_v01), GFP_KERNEL); if (!req) { IPAERR("mem allocated failed!\n"); return -ENOMEM; } req->filter_spec_list_valid = false; req->filter_spec_list_len = 0; req->source_pipe_index_valid = 0; val = ipa3_qmi_filter_request_send(req); kfree(req); } else { req_ex = kzalloc( sizeof(struct ipa_install_fltr_rule_req_ex_msg_v01), GFP_KERNEL); if (!req_ex) { IPAERR("mem allocated failed!\n"); return -ENOMEM; } req_ex->filter_spec_ex_list_valid = false; req_ex->filter_spec_ex_list_len = 0; req_ex->source_pipe_index_valid = 0; val = ipa3_qmi_filter_request_ex_send(req_ex); kfree(req_ex); } return val; } static int ipa3_active_clients_panic_notifier(struct notifier_block *this, static int ipa3_active_clients_panic_notifier(struct notifier_block *this, unsigned long event, void *ptr) unsigned long event, void *ptr) { { Loading Loading @@ -941,7 +978,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; retval = -EFAULT; break; break; } } if (ipa3_add_hdr((struct ipa_ioc_add_hdr *)param)) { if (ipa3_add_hdr_usr((struct ipa_ioc_add_hdr *)param, true)) { retval = -EFAULT; retval = -EFAULT; break; break; } } Loading Loading @@ -1021,7 +1059,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; retval = -EFAULT; break; break; } } if (ipa3_add_rt_rule((struct ipa_ioc_add_rt_rule *)param)) { if (ipa3_add_rt_rule_usr((struct ipa_ioc_add_rt_rule *)param, true)) { retval = -EFAULT; retval = -EFAULT; break; break; } } Loading Loading @@ -1225,7 +1264,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; retval = -EFAULT; break; break; } } if (ipa3_add_flt_rule((struct ipa_ioc_add_flt_rule *)param)) { if (ipa3_add_flt_rule_usr((struct ipa_ioc_add_flt_rule *)param, true)) { retval = -EFAULT; retval = -EFAULT; break; break; } } Loading Loading @@ -1362,19 +1402,19 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = ipa3_commit_hdr(); retval = ipa3_commit_hdr(); break; break; case IPA_IOC_RESET_HDR: case IPA_IOC_RESET_HDR: retval = ipa3_reset_hdr(); retval = ipa3_reset_hdr(false); break; break; case IPA_IOC_COMMIT_RT: case IPA_IOC_COMMIT_RT: retval = ipa3_commit_rt(arg); retval = ipa3_commit_rt(arg); break; break; case IPA_IOC_RESET_RT: case IPA_IOC_RESET_RT: retval = ipa3_reset_rt(arg); retval = ipa3_reset_rt(arg, false); break; break; case IPA_IOC_COMMIT_FLT: case IPA_IOC_COMMIT_FLT: retval = ipa3_commit_flt(arg); retval = ipa3_commit_flt(arg); break; break; case IPA_IOC_RESET_FLT: case IPA_IOC_RESET_FLT: retval = ipa3_reset_flt(arg); retval = ipa3_reset_flt(arg, false); break; break; case IPA_IOC_GET_RT_TBL: case IPA_IOC_GET_RT_TBL: if (copy_from_user(header, (const void __user *)arg, if (copy_from_user(header, (const void __user *)arg, Loading Loading @@ -1762,7 +1802,7 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; break; } } if (ipa3_add_hdr_proc_ctx( if (ipa3_add_hdr_proc_ctx( (struct ipa_ioc_add_hdr_proc_ctx *)param)) { (struct ipa_ioc_add_hdr_proc_ctx *)param, true)) { retval = -EFAULT; retval = -EFAULT; break; break; } } Loading Loading @@ -1887,6 +1927,21 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } } break; break; case IPA_IOC_CLEANUP: /*Route and filter rules will also be clean*/ IPADBG("Got IPA_IOC_CLEANUP\n"); retval = ipa3_reset_hdr(true); memset(&nat_del, 0, sizeof(nat_del)); nat_del.table_index = 0; retval = ipa3_nat_del_cmd(&nat_del); retval = ipa3_clean_modem_rule(); break; case IPA_IOC_QUERY_WLAN_CLIENT: IPADBG("Got IPA_IOC_QUERY_WLAN_CLIENT\n"); retval = ipa3_resend_wlan_msg(); break; default: default: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return -ENOTTY; return -ENOTTY; Loading Loading @@ -5402,6 +5457,10 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, init_waitqueue_head(&ipa3_ctx->msg_waitq); init_waitqueue_head(&ipa3_ctx->msg_waitq); mutex_init(&ipa3_ctx->msg_lock); mutex_init(&ipa3_ctx->msg_lock); /* store wlan client-connect-msg-list */ INIT_LIST_HEAD(&ipa3_ctx->msg_wlan_client_list); mutex_init(&ipa3_ctx->msg_wlan_client_lock); mutex_init(&ipa3_ctx->lock); mutex_init(&ipa3_ctx->lock); mutex_init(&ipa3_ctx->q6_proxy_clk_vote_mutex); mutex_init(&ipa3_ctx->q6_proxy_clk_vote_mutex); mutex_init(&ipa3_ctx->ipa_cne_evt_lock); mutex_init(&ipa3_ctx->ipa_cne_evt_lock); Loading drivers/platform/msm/ipa/ipa_v3/ipa_flt.c +55 −28 Original line number Original line Diff line number Diff line Loading @@ -833,7 +833,7 @@ static int __ipa_validate_flt_rule(const struct ipa_flt_rule *rule, static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry, static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry, const struct ipa_flt_rule *rule, struct ipa3_rt_tbl *rt_tbl, const struct ipa_flt_rule *rule, struct ipa3_rt_tbl *rt_tbl, struct ipa3_flt_tbl *tbl) struct ipa3_flt_tbl *tbl, bool user) { { int id; int id; Loading @@ -856,6 +856,7 @@ static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry, } } } } (*entry)->rule_id = id; (*entry)->rule_id = id; (*entry)->ipacm_installed = user; return 0; return 0; Loading Loading @@ -893,7 +894,7 @@ static int __ipa_finish_flt_rule_add(struct ipa3_flt_tbl *tbl, static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip, static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip, const struct ipa_flt_rule *rule, u8 add_rear, const struct ipa_flt_rule *rule, u8 add_rear, u32 *rule_hdl) u32 *rule_hdl, bool user) { { struct ipa3_flt_entry *entry; struct ipa3_flt_entry *entry; struct ipa3_rt_tbl *rt_tbl = NULL; struct ipa3_rt_tbl *rt_tbl = NULL; Loading @@ -901,7 +902,7 @@ static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip, if (__ipa_validate_flt_rule(rule, &rt_tbl, ip)) if (__ipa_validate_flt_rule(rule, &rt_tbl, ip)) goto error; goto error; if (__ipa_create_flt_entry(&entry, rule, rt_tbl, tbl)) if (__ipa_create_flt_entry(&entry, rule, rt_tbl, tbl, user)) goto error; goto error; if (add_rear) { if (add_rear) { Loading Loading @@ -951,7 +952,7 @@ static int __ipa_add_flt_rule_after(struct ipa3_flt_tbl *tbl, if (__ipa_validate_flt_rule(rule, &rt_tbl, ip)) if (__ipa_validate_flt_rule(rule, &rt_tbl, ip)) goto error; goto error; if (__ipa_create_flt_entry(&entry, rule, rt_tbl, tbl)) if (__ipa_create_flt_entry(&entry, rule, rt_tbl, tbl, true)) goto error; goto error; list_add(&entry->link, &((*add_after_entry)->link)); list_add(&entry->link, &((*add_after_entry)->link)); Loading Loading @@ -1072,7 +1073,7 @@ static int __ipa_add_flt_get_ep_idx(enum ipa_client_type ep, int *ipa_ep_idx) static int __ipa_add_ep_flt_rule(enum ipa_ip_type ip, enum ipa_client_type ep, static int __ipa_add_ep_flt_rule(enum ipa_ip_type ip, enum ipa_client_type ep, const struct ipa_flt_rule *rule, u8 add_rear, const struct ipa_flt_rule *rule, u8 add_rear, u32 *rule_hdl) u32 *rule_hdl, bool user) { { struct ipa3_flt_tbl *tbl; struct ipa3_flt_tbl *tbl; int ipa_ep_idx; int ipa_ep_idx; Loading @@ -1090,18 +1091,34 @@ static int __ipa_add_ep_flt_rule(enum ipa_ip_type ip, enum ipa_client_type ep, tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][ip]; tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][ip]; IPADBG_LOW("add ep flt rule ip=%d ep=%d\n", ip, ep); IPADBG_LOW("add ep flt rule ip=%d ep=%d\n", ip, ep); return __ipa_add_flt_rule(tbl, ip, rule, add_rear, rule_hdl); return __ipa_add_flt_rule(tbl, ip, rule, add_rear, rule_hdl, user); } } /** /** * ipa3_add_flt_rule() - Add the specified filtering rules to SW and optionally * ipa3_add_flt_rule() - Add the specified filtering rules to SW and optionally * commit to IPA HW * commit to IPA HW * @rules: [inout] set of filtering rules to add * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa3_add_flt_rule(struct ipa_ioc_add_flt_rule *rules) int ipa3_add_flt_rule(struct ipa_ioc_add_flt_rule *rules) { return ipa3_add_flt_rule_usr(rules, false); } /** * ipa3_add_flt_rule_usr() - Add the specified filtering rules to * SW and optionally commit to IPA HW * @rules: [inout] set of filtering rules to add * @user_only: [in] indicate rules installed by userspace * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa3_add_flt_rule_usr(struct ipa_ioc_add_flt_rule *rules, bool user_only) { { int i; int i; int result; int result; Loading @@ -1120,10 +1137,12 @@ int ipa3_add_flt_rule(struct ipa_ioc_add_flt_rule *rules) */ */ if (ipa3_ctx->ipa_fltrt_not_hashable) if (ipa3_ctx->ipa_fltrt_not_hashable) rules->rules[i].rule.hashable = false; rules->rules[i].rule.hashable = false; result = __ipa_add_ep_flt_rule(rules->ip, rules->ep, result = __ipa_add_ep_flt_rule(rules->ip, rules->ep, &rules->rules[i].rule, &rules->rules[i].rule, rules->rules[i].at_rear, rules->rules[i].at_rear, &rules->rules[i].flt_rule_hdl); &rules->rules[i].flt_rule_hdl, user_only); } else } else result = -1; result = -1; Loading Loading @@ -1376,18 +1395,20 @@ int ipa3_commit_flt(enum ipa_ip_type ip) * ipa3_reset_flt() - Reset the current SW filtering table of specified type * ipa3_reset_flt() - Reset the current SW filtering table of specified type * (does not commit to HW) * (does not commit to HW) * @ip: [in] the family of routing tables * @ip: [in] the family of routing tables * @user_only: [in] indicate rules deleted by userspace * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa3_reset_flt(enum ipa_ip_type ip) int ipa3_reset_flt(enum ipa_ip_type ip, bool user_only) { { struct ipa3_flt_tbl *tbl; struct ipa3_flt_tbl *tbl; struct ipa3_flt_entry *entry; struct ipa3_flt_entry *entry; struct ipa3_flt_entry *next; struct ipa3_flt_entry *next; int i; int i; int id; int id; int rule_id; if (ip >= IPA_IP_MAX) { if (ip >= IPA_IP_MAX) { IPAERR_RL("bad parm\n"); IPAERR_RL("bad parm\n"); Loading @@ -1407,23 +1428,29 @@ int ipa3_reset_flt(enum ipa_ip_type ip) mutex_unlock(&ipa3_ctx->lock); mutex_unlock(&ipa3_ctx->lock); return -EFAULT; return -EFAULT; } } if (!user_only || entry->ipacm_installed) { list_del(&entry->link); list_del(&entry->link); entry->tbl->rule_cnt--; entry->tbl->rule_cnt--; if (entry->rt_tbl) if (entry->rt_tbl) entry->rt_tbl->ref_cnt--; entry->rt_tbl->ref_cnt--; /* if rule id was allocated from idr, remove it */ /* if rule id was allocated from idr, remove */ if ((entry->rule_id < ipahal_get_rule_id_hi_bit()) && rule_id = entry->rule_id; (entry->rule_id >= ipahal_get_low_rule_id())) id = entry->id; if ((rule_id < ipahal_get_rule_id_hi_bit()) && (rule_id >= ipahal_get_low_rule_id())) idr_remove(entry->tbl->rule_ids, idr_remove(entry->tbl->rule_ids, entry->rule_id); rule_id); entry->cookie = 0; entry->cookie = 0; id = entry->id; kmem_cache_free(ipa3_ctx->flt_rule_cache, kmem_cache_free(ipa3_ctx->flt_rule_cache, entry); entry); /* remove the handle from the database */ /* remove the handle from the database */ ipa3_id_remove(id); ipa3_id_remove(id); } } } } } mutex_unlock(&ipa3_ctx->lock); mutex_unlock(&ipa3_ctx->lock); return 0; return 0; Loading @@ -1447,14 +1474,14 @@ void ipa3_install_dflt_flt_rules(u32 ipa_ep_idx) tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v4]; tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v4]; rule.action = IPA_PASS_TO_EXCEPTION; rule.action = IPA_PASS_TO_EXCEPTION; __ipa_add_flt_rule(tbl, IPA_IP_v4, &rule, true, __ipa_add_flt_rule(tbl, IPA_IP_v4, &rule, true, &ep->dflt_flt4_rule_hdl); &ep->dflt_flt4_rule_hdl, false); ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v4); ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v4); tbl->sticky_rear = true; tbl->sticky_rear = true; tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v6]; tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v6]; rule.action = IPA_PASS_TO_EXCEPTION; rule.action = IPA_PASS_TO_EXCEPTION; __ipa_add_flt_rule(tbl, IPA_IP_v6, &rule, true, __ipa_add_flt_rule(tbl, IPA_IP_v6, &rule, true, &ep->dflt_flt6_rule_hdl); &ep->dflt_flt6_rule_hdl, false); ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v6); ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v6); tbl->sticky_rear = true; tbl->sticky_rear = true; mutex_unlock(&ipa3_ctx->lock); mutex_unlock(&ipa3_ctx->lock); Loading Loading
drivers/platform/msm/ipa/ipa_api.c +83 −17 Original line number Original line Diff line number Diff line Loading @@ -703,6 +703,26 @@ int ipa_add_hdr(struct ipa_ioc_add_hdr *hdrs) } } EXPORT_SYMBOL(ipa_add_hdr); EXPORT_SYMBOL(ipa_add_hdr); /** * ipa_add_hdr_usr() - add the specified headers to SW and optionally * commit them to IPA HW * @hdrs: [inout] set of headers to add * @user_only: [in] indicate rules installed by userspace * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa_add_hdr_usr(struct ipa_ioc_add_hdr *hdrs, bool user_only) { int ret; IPA_API_DISPATCH_RETURN(ipa_add_hdr_usr, hdrs, user_only); return ret; } EXPORT_SYMBOL(ipa_add_hdr_usr); /** /** * ipa_del_hdr() - Remove the specified headers from SW and optionally * ipa_del_hdr() - Remove the specified headers from SW and optionally * commit them to IPA HW * commit them to IPA HW Loading Loading @@ -743,15 +763,16 @@ EXPORT_SYMBOL(ipa_commit_hdr); * ipa_reset_hdr() - reset the current header table in SW (does not commit to * ipa_reset_hdr() - reset the current header table in SW (does not commit to * HW) * HW) * * * @user_only: [in] indicate delete rules installed by userspace * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa_reset_hdr(void) int ipa_reset_hdr(bool user_only) { { int ret; int ret; IPA_API_DISPATCH_RETURN(ipa_reset_hdr); IPA_API_DISPATCH_RETURN(ipa_reset_hdr, user_only); return ret; return ret; } } Loading Loading @@ -821,16 +842,18 @@ EXPORT_SYMBOL(ipa_copy_hdr); * ipa_add_hdr_proc_ctx() - add the specified headers to SW * ipa_add_hdr_proc_ctx() - add the specified headers to SW * and optionally commit them to IPA HW * and optionally commit them to IPA HW * @proc_ctxs: [inout] set of processing context headers to add * @proc_ctxs: [inout] set of processing context headers to add * @user_only: [in] indicate rules installed by userspace * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs) int ipa_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs, bool user_only) { { int ret; int ret; IPA_API_DISPATCH_RETURN(ipa_add_hdr_proc_ctx, proc_ctxs); IPA_API_DISPATCH_RETURN(ipa_add_hdr_proc_ctx, proc_ctxs, user_only); return ret; return ret; } } Loading Loading @@ -875,6 +898,26 @@ int ipa_add_rt_rule(struct ipa_ioc_add_rt_rule *rules) } } EXPORT_SYMBOL(ipa_add_rt_rule); EXPORT_SYMBOL(ipa_add_rt_rule); /** * ipa_add_rt_rule_usr() - Add the specified routing rules to SW and optionally * commit to IPA HW * @rules: [inout] set of routing rules to add * @user_only: [in] indicate rules installed by userspace * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa_add_rt_rule_usr(struct ipa_ioc_add_rt_rule *rules, bool user_only) { int ret; IPA_API_DISPATCH_RETURN(ipa_add_rt_rule_usr, rules, user_only); return ret; } EXPORT_SYMBOL(ipa_add_rt_rule_usr); /** /** * ipa_del_rt_rule() - Remove the specified routing rules to SW and optionally * ipa_del_rt_rule() - Remove the specified routing rules to SW and optionally * commit to IPA HW * commit to IPA HW Loading Loading @@ -917,16 +960,17 @@ EXPORT_SYMBOL(ipa_commit_rt); * ipa_reset_rt() - reset the current SW routing table of specified type * ipa_reset_rt() - reset the current SW routing table of specified type * (does not commit to HW) * (does not commit to HW) * @ip: The family of routing tables * @ip: The family of routing tables * @user_only: [in] indicate delete rules installed by userspace * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa_reset_rt(enum ipa_ip_type ip) int ipa_reset_rt(enum ipa_ip_type ip, bool user_only) { { int ret; int ret; IPA_API_DISPATCH_RETURN(ipa_reset_rt, ip); IPA_API_DISPATCH_RETURN(ipa_reset_rt, ip, user_only); return ret; return ret; } } Loading Loading @@ -1009,6 +1053,7 @@ EXPORT_SYMBOL(ipa_mdfy_rt_rule); /** /** * ipa_add_flt_rule() - Add the specified filtering rules to SW and optionally * ipa_add_flt_rule() - Add the specified filtering rules to SW and optionally * commit to IPA HW * commit to IPA HW * @rules: [inout] set of filtering rules to add * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * Loading @@ -1024,6 +1069,26 @@ int ipa_add_flt_rule(struct ipa_ioc_add_flt_rule *rules) } } EXPORT_SYMBOL(ipa_add_flt_rule); EXPORT_SYMBOL(ipa_add_flt_rule); /** * ipa_add_flt_rule_usr() - Add the specified filtering rules to * SW and optionally commit to IPA HW * @rules: [inout] set of filtering rules to add * @user_only: [in] indicate rules installed by userspace * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa_add_flt_rule_usr(struct ipa_ioc_add_flt_rule *rules, bool user_only) { int ret; IPA_API_DISPATCH_RETURN(ipa_add_flt_rule_usr, rules, user_only); return ret; } EXPORT_SYMBOL(ipa_add_flt_rule_usr); /** /** * ipa_del_flt_rule() - Remove the specified filtering rules from SW and * ipa_del_flt_rule() - Remove the specified filtering rules from SW and * optionally commit to IPA HW * optionally commit to IPA HW Loading Loading @@ -1083,16 +1148,17 @@ EXPORT_SYMBOL(ipa_commit_flt); * ipa_reset_flt() - Reset the current SW filtering table of specified type * ipa_reset_flt() - Reset the current SW filtering table of specified type * (does not commit to HW) * (does not commit to HW) * @ip: [in] the family of routing tables * @ip: [in] the family of routing tables * @user_only: [in] indicate delete rules installed by userspace * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa_reset_flt(enum ipa_ip_type ip) int ipa_reset_flt(enum ipa_ip_type ip, bool user_only) { { int ret; int ret; IPA_API_DISPATCH_RETURN(ipa_reset_flt, ip); IPA_API_DISPATCH_RETURN(ipa_reset_flt, ip, user_only); return ret; return ret; } } Loading
drivers/platform/msm/ipa/ipa_api.h +13 −4 Original line number Original line Diff line number Diff line Loading @@ -68,11 +68,13 @@ struct ipa_api_controller { int (*ipa_add_hdr)(struct ipa_ioc_add_hdr *hdrs); int (*ipa_add_hdr)(struct ipa_ioc_add_hdr *hdrs); int (*ipa_add_hdr_usr)(struct ipa_ioc_add_hdr *hdrs, bool user_only); int (*ipa_del_hdr)(struct ipa_ioc_del_hdr *hdls); int (*ipa_del_hdr)(struct ipa_ioc_del_hdr *hdls); int (*ipa_commit_hdr)(void); int (*ipa_commit_hdr)(void); int (*ipa_reset_hdr)(void); int (*ipa_reset_hdr)(bool user_only); int (*ipa_get_hdr)(struct ipa_ioc_get_hdr *lookup); int (*ipa_get_hdr)(struct ipa_ioc_get_hdr *lookup); Loading @@ -80,17 +82,21 @@ struct ipa_api_controller { int (*ipa_copy_hdr)(struct ipa_ioc_copy_hdr *copy); int (*ipa_copy_hdr)(struct ipa_ioc_copy_hdr *copy); int (*ipa_add_hdr_proc_ctx)(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs); int (*ipa_add_hdr_proc_ctx)(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs, bool user_only); int (*ipa_del_hdr_proc_ctx)(struct ipa_ioc_del_hdr_proc_ctx *hdls); int (*ipa_del_hdr_proc_ctx)(struct ipa_ioc_del_hdr_proc_ctx *hdls); int (*ipa_add_rt_rule)(struct ipa_ioc_add_rt_rule *rules); int (*ipa_add_rt_rule)(struct ipa_ioc_add_rt_rule *rules); int (*ipa_add_rt_rule_usr)(struct ipa_ioc_add_rt_rule *rules, bool user_only); int (*ipa_del_rt_rule)(struct ipa_ioc_del_rt_rule *hdls); int (*ipa_del_rt_rule)(struct ipa_ioc_del_rt_rule *hdls); int (*ipa_commit_rt)(enum ipa_ip_type ip); int (*ipa_commit_rt)(enum ipa_ip_type ip); int (*ipa_reset_rt)(enum ipa_ip_type ip); int (*ipa_reset_rt)(enum ipa_ip_type ip, bool user_only); int (*ipa_get_rt_tbl)(struct ipa_ioc_get_rt_tbl *lookup); int (*ipa_get_rt_tbl)(struct ipa_ioc_get_rt_tbl *lookup); Loading @@ -102,13 +108,16 @@ struct ipa_api_controller { int (*ipa_add_flt_rule)(struct ipa_ioc_add_flt_rule *rules); int (*ipa_add_flt_rule)(struct ipa_ioc_add_flt_rule *rules); int (*ipa_add_flt_rule_usr)(struct ipa_ioc_add_flt_rule *rules, bool user_only); int (*ipa_del_flt_rule)(struct ipa_ioc_del_flt_rule *hdls); 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_mdfy_flt_rule)(struct ipa_ioc_mdfy_flt_rule *rules); int (*ipa_commit_flt)(enum ipa_ip_type ip); int (*ipa_commit_flt)(enum ipa_ip_type ip); int (*ipa_reset_flt)(enum ipa_ip_type ip); int (*ipa_reset_flt)(enum ipa_ip_type ip, bool user_only); int (*ipa_allocate_nat_device)(struct ipa_ioc_nat_alloc_mem *mem); int (*ipa_allocate_nat_device)(struct ipa_ioc_nat_alloc_mem *mem); Loading
drivers/platform/msm/ipa/ipa_common_i.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -333,11 +333,13 @@ struct ipa_mhi_connect_params_internal { * @link: entry's link in global header offset entries list * @link: entry's link in global header offset entries list * @offset: the offset * @offset: the offset * @bin: bin * @bin: bin * @ipacm_installed: indicate if installed by ipacm */ */ struct ipa_hdr_offset_entry { struct ipa_hdr_offset_entry { struct list_head link; struct list_head link; u32 offset; u32 offset; u32 bin; u32 bin; bool ipacm_installed; }; }; extern const char *ipa_clients_strings[]; extern const char *ipa_clients_strings[]; Loading
drivers/platform/msm/ipa/ipa_v3/ipa.c +66 −7 Original line number Original line Diff line number Diff line Loading @@ -369,6 +369,43 @@ int ipa3_active_clients_log_print_table(char *buf, int size) return cnt; return cnt; } } static int ipa3_clean_modem_rule(void) { struct ipa_install_fltr_rule_req_msg_v01 *req; struct ipa_install_fltr_rule_req_ex_msg_v01 *req_ex; int val = 0; if (ipa3_ctx->ipa_hw_type < IPA_HW_v3_0) { req = kzalloc( sizeof(struct ipa_install_fltr_rule_req_msg_v01), GFP_KERNEL); if (!req) { IPAERR("mem allocated failed!\n"); return -ENOMEM; } req->filter_spec_list_valid = false; req->filter_spec_list_len = 0; req->source_pipe_index_valid = 0; val = ipa3_qmi_filter_request_send(req); kfree(req); } else { req_ex = kzalloc( sizeof(struct ipa_install_fltr_rule_req_ex_msg_v01), GFP_KERNEL); if (!req_ex) { IPAERR("mem allocated failed!\n"); return -ENOMEM; } req_ex->filter_spec_ex_list_valid = false; req_ex->filter_spec_ex_list_len = 0; req_ex->source_pipe_index_valid = 0; val = ipa3_qmi_filter_request_ex_send(req_ex); kfree(req_ex); } return val; } static int ipa3_active_clients_panic_notifier(struct notifier_block *this, static int ipa3_active_clients_panic_notifier(struct notifier_block *this, unsigned long event, void *ptr) unsigned long event, void *ptr) { { Loading Loading @@ -941,7 +978,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; retval = -EFAULT; break; break; } } if (ipa3_add_hdr((struct ipa_ioc_add_hdr *)param)) { if (ipa3_add_hdr_usr((struct ipa_ioc_add_hdr *)param, true)) { retval = -EFAULT; retval = -EFAULT; break; break; } } Loading Loading @@ -1021,7 +1059,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; retval = -EFAULT; break; break; } } if (ipa3_add_rt_rule((struct ipa_ioc_add_rt_rule *)param)) { if (ipa3_add_rt_rule_usr((struct ipa_ioc_add_rt_rule *)param, true)) { retval = -EFAULT; retval = -EFAULT; break; break; } } Loading Loading @@ -1225,7 +1264,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; retval = -EFAULT; break; break; } } if (ipa3_add_flt_rule((struct ipa_ioc_add_flt_rule *)param)) { if (ipa3_add_flt_rule_usr((struct ipa_ioc_add_flt_rule *)param, true)) { retval = -EFAULT; retval = -EFAULT; break; break; } } Loading Loading @@ -1362,19 +1402,19 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = ipa3_commit_hdr(); retval = ipa3_commit_hdr(); break; break; case IPA_IOC_RESET_HDR: case IPA_IOC_RESET_HDR: retval = ipa3_reset_hdr(); retval = ipa3_reset_hdr(false); break; break; case IPA_IOC_COMMIT_RT: case IPA_IOC_COMMIT_RT: retval = ipa3_commit_rt(arg); retval = ipa3_commit_rt(arg); break; break; case IPA_IOC_RESET_RT: case IPA_IOC_RESET_RT: retval = ipa3_reset_rt(arg); retval = ipa3_reset_rt(arg, false); break; break; case IPA_IOC_COMMIT_FLT: case IPA_IOC_COMMIT_FLT: retval = ipa3_commit_flt(arg); retval = ipa3_commit_flt(arg); break; break; case IPA_IOC_RESET_FLT: case IPA_IOC_RESET_FLT: retval = ipa3_reset_flt(arg); retval = ipa3_reset_flt(arg, false); break; break; case IPA_IOC_GET_RT_TBL: case IPA_IOC_GET_RT_TBL: if (copy_from_user(header, (const void __user *)arg, if (copy_from_user(header, (const void __user *)arg, Loading Loading @@ -1762,7 +1802,7 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; break; } } if (ipa3_add_hdr_proc_ctx( if (ipa3_add_hdr_proc_ctx( (struct ipa_ioc_add_hdr_proc_ctx *)param)) { (struct ipa_ioc_add_hdr_proc_ctx *)param, true)) { retval = -EFAULT; retval = -EFAULT; break; break; } } Loading Loading @@ -1887,6 +1927,21 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } } break; break; case IPA_IOC_CLEANUP: /*Route and filter rules will also be clean*/ IPADBG("Got IPA_IOC_CLEANUP\n"); retval = ipa3_reset_hdr(true); memset(&nat_del, 0, sizeof(nat_del)); nat_del.table_index = 0; retval = ipa3_nat_del_cmd(&nat_del); retval = ipa3_clean_modem_rule(); break; case IPA_IOC_QUERY_WLAN_CLIENT: IPADBG("Got IPA_IOC_QUERY_WLAN_CLIENT\n"); retval = ipa3_resend_wlan_msg(); break; default: default: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return -ENOTTY; return -ENOTTY; Loading Loading @@ -5402,6 +5457,10 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, init_waitqueue_head(&ipa3_ctx->msg_waitq); init_waitqueue_head(&ipa3_ctx->msg_waitq); mutex_init(&ipa3_ctx->msg_lock); mutex_init(&ipa3_ctx->msg_lock); /* store wlan client-connect-msg-list */ INIT_LIST_HEAD(&ipa3_ctx->msg_wlan_client_list); mutex_init(&ipa3_ctx->msg_wlan_client_lock); mutex_init(&ipa3_ctx->lock); mutex_init(&ipa3_ctx->lock); mutex_init(&ipa3_ctx->q6_proxy_clk_vote_mutex); mutex_init(&ipa3_ctx->q6_proxy_clk_vote_mutex); mutex_init(&ipa3_ctx->ipa_cne_evt_lock); mutex_init(&ipa3_ctx->ipa_cne_evt_lock); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_flt.c +55 −28 Original line number Original line Diff line number Diff line Loading @@ -833,7 +833,7 @@ static int __ipa_validate_flt_rule(const struct ipa_flt_rule *rule, static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry, static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry, const struct ipa_flt_rule *rule, struct ipa3_rt_tbl *rt_tbl, const struct ipa_flt_rule *rule, struct ipa3_rt_tbl *rt_tbl, struct ipa3_flt_tbl *tbl) struct ipa3_flt_tbl *tbl, bool user) { { int id; int id; Loading @@ -856,6 +856,7 @@ static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry, } } } } (*entry)->rule_id = id; (*entry)->rule_id = id; (*entry)->ipacm_installed = user; return 0; return 0; Loading Loading @@ -893,7 +894,7 @@ static int __ipa_finish_flt_rule_add(struct ipa3_flt_tbl *tbl, static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip, static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip, const struct ipa_flt_rule *rule, u8 add_rear, const struct ipa_flt_rule *rule, u8 add_rear, u32 *rule_hdl) u32 *rule_hdl, bool user) { { struct ipa3_flt_entry *entry; struct ipa3_flt_entry *entry; struct ipa3_rt_tbl *rt_tbl = NULL; struct ipa3_rt_tbl *rt_tbl = NULL; Loading @@ -901,7 +902,7 @@ static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip, if (__ipa_validate_flt_rule(rule, &rt_tbl, ip)) if (__ipa_validate_flt_rule(rule, &rt_tbl, ip)) goto error; goto error; if (__ipa_create_flt_entry(&entry, rule, rt_tbl, tbl)) if (__ipa_create_flt_entry(&entry, rule, rt_tbl, tbl, user)) goto error; goto error; if (add_rear) { if (add_rear) { Loading Loading @@ -951,7 +952,7 @@ static int __ipa_add_flt_rule_after(struct ipa3_flt_tbl *tbl, if (__ipa_validate_flt_rule(rule, &rt_tbl, ip)) if (__ipa_validate_flt_rule(rule, &rt_tbl, ip)) goto error; goto error; if (__ipa_create_flt_entry(&entry, rule, rt_tbl, tbl)) if (__ipa_create_flt_entry(&entry, rule, rt_tbl, tbl, true)) goto error; goto error; list_add(&entry->link, &((*add_after_entry)->link)); list_add(&entry->link, &((*add_after_entry)->link)); Loading Loading @@ -1072,7 +1073,7 @@ static int __ipa_add_flt_get_ep_idx(enum ipa_client_type ep, int *ipa_ep_idx) static int __ipa_add_ep_flt_rule(enum ipa_ip_type ip, enum ipa_client_type ep, static int __ipa_add_ep_flt_rule(enum ipa_ip_type ip, enum ipa_client_type ep, const struct ipa_flt_rule *rule, u8 add_rear, const struct ipa_flt_rule *rule, u8 add_rear, u32 *rule_hdl) u32 *rule_hdl, bool user) { { struct ipa3_flt_tbl *tbl; struct ipa3_flt_tbl *tbl; int ipa_ep_idx; int ipa_ep_idx; Loading @@ -1090,18 +1091,34 @@ static int __ipa_add_ep_flt_rule(enum ipa_ip_type ip, enum ipa_client_type ep, tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][ip]; tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][ip]; IPADBG_LOW("add ep flt rule ip=%d ep=%d\n", ip, ep); IPADBG_LOW("add ep flt rule ip=%d ep=%d\n", ip, ep); return __ipa_add_flt_rule(tbl, ip, rule, add_rear, rule_hdl); return __ipa_add_flt_rule(tbl, ip, rule, add_rear, rule_hdl, user); } } /** /** * ipa3_add_flt_rule() - Add the specified filtering rules to SW and optionally * ipa3_add_flt_rule() - Add the specified filtering rules to SW and optionally * commit to IPA HW * commit to IPA HW * @rules: [inout] set of filtering rules to add * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa3_add_flt_rule(struct ipa_ioc_add_flt_rule *rules) int ipa3_add_flt_rule(struct ipa_ioc_add_flt_rule *rules) { return ipa3_add_flt_rule_usr(rules, false); } /** * ipa3_add_flt_rule_usr() - Add the specified filtering rules to * SW and optionally commit to IPA HW * @rules: [inout] set of filtering rules to add * @user_only: [in] indicate rules installed by userspace * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ int ipa3_add_flt_rule_usr(struct ipa_ioc_add_flt_rule *rules, bool user_only) { { int i; int i; int result; int result; Loading @@ -1120,10 +1137,12 @@ int ipa3_add_flt_rule(struct ipa_ioc_add_flt_rule *rules) */ */ if (ipa3_ctx->ipa_fltrt_not_hashable) if (ipa3_ctx->ipa_fltrt_not_hashable) rules->rules[i].rule.hashable = false; rules->rules[i].rule.hashable = false; result = __ipa_add_ep_flt_rule(rules->ip, rules->ep, result = __ipa_add_ep_flt_rule(rules->ip, rules->ep, &rules->rules[i].rule, &rules->rules[i].rule, rules->rules[i].at_rear, rules->rules[i].at_rear, &rules->rules[i].flt_rule_hdl); &rules->rules[i].flt_rule_hdl, user_only); } else } else result = -1; result = -1; Loading Loading @@ -1376,18 +1395,20 @@ int ipa3_commit_flt(enum ipa_ip_type ip) * ipa3_reset_flt() - Reset the current SW filtering table of specified type * ipa3_reset_flt() - Reset the current SW filtering table of specified type * (does not commit to HW) * (does not commit to HW) * @ip: [in] the family of routing tables * @ip: [in] the family of routing tables * @user_only: [in] indicate rules deleted by userspace * * * Returns: 0 on success, negative on failure * Returns: 0 on success, negative on failure * * * Note: Should not be called from atomic context * Note: Should not be called from atomic context */ */ int ipa3_reset_flt(enum ipa_ip_type ip) int ipa3_reset_flt(enum ipa_ip_type ip, bool user_only) { { struct ipa3_flt_tbl *tbl; struct ipa3_flt_tbl *tbl; struct ipa3_flt_entry *entry; struct ipa3_flt_entry *entry; struct ipa3_flt_entry *next; struct ipa3_flt_entry *next; int i; int i; int id; int id; int rule_id; if (ip >= IPA_IP_MAX) { if (ip >= IPA_IP_MAX) { IPAERR_RL("bad parm\n"); IPAERR_RL("bad parm\n"); Loading @@ -1407,23 +1428,29 @@ int ipa3_reset_flt(enum ipa_ip_type ip) mutex_unlock(&ipa3_ctx->lock); mutex_unlock(&ipa3_ctx->lock); return -EFAULT; return -EFAULT; } } if (!user_only || entry->ipacm_installed) { list_del(&entry->link); list_del(&entry->link); entry->tbl->rule_cnt--; entry->tbl->rule_cnt--; if (entry->rt_tbl) if (entry->rt_tbl) entry->rt_tbl->ref_cnt--; entry->rt_tbl->ref_cnt--; /* if rule id was allocated from idr, remove it */ /* if rule id was allocated from idr, remove */ if ((entry->rule_id < ipahal_get_rule_id_hi_bit()) && rule_id = entry->rule_id; (entry->rule_id >= ipahal_get_low_rule_id())) id = entry->id; if ((rule_id < ipahal_get_rule_id_hi_bit()) && (rule_id >= ipahal_get_low_rule_id())) idr_remove(entry->tbl->rule_ids, idr_remove(entry->tbl->rule_ids, entry->rule_id); rule_id); entry->cookie = 0; entry->cookie = 0; id = entry->id; kmem_cache_free(ipa3_ctx->flt_rule_cache, kmem_cache_free(ipa3_ctx->flt_rule_cache, entry); entry); /* remove the handle from the database */ /* remove the handle from the database */ ipa3_id_remove(id); ipa3_id_remove(id); } } } } } mutex_unlock(&ipa3_ctx->lock); mutex_unlock(&ipa3_ctx->lock); return 0; return 0; Loading @@ -1447,14 +1474,14 @@ void ipa3_install_dflt_flt_rules(u32 ipa_ep_idx) tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v4]; tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v4]; rule.action = IPA_PASS_TO_EXCEPTION; rule.action = IPA_PASS_TO_EXCEPTION; __ipa_add_flt_rule(tbl, IPA_IP_v4, &rule, true, __ipa_add_flt_rule(tbl, IPA_IP_v4, &rule, true, &ep->dflt_flt4_rule_hdl); &ep->dflt_flt4_rule_hdl, false); ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v4); ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v4); tbl->sticky_rear = true; tbl->sticky_rear = true; tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v6]; tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v6]; rule.action = IPA_PASS_TO_EXCEPTION; rule.action = IPA_PASS_TO_EXCEPTION; __ipa_add_flt_rule(tbl, IPA_IP_v6, &rule, true, __ipa_add_flt_rule(tbl, IPA_IP_v6, &rule, true, &ep->dflt_flt6_rule_hdl); &ep->dflt_flt6_rule_hdl, false); ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v6); ipa3_ctx->ctrl->ipa3_commit_flt(IPA_IP_v6); tbl->sticky_rear = true; tbl->sticky_rear = true; mutex_unlock(&ipa3_ctx->lock); mutex_unlock(&ipa3_ctx->lock); Loading