Loading drivers/platform/msm/ipa/ipa_client.c +7 −0 Original line number Diff line number Diff line Loading @@ -325,6 +325,11 @@ int ipa_connect(const struct ipa_connect_params *in, struct ipa_sps_params *sps, ipa_program_holb(ep, ipa_ep_idx); if (in->client == IPA_CLIENT_USB_PROD && ((enum ipa_config_this_ep)ep->priv != IPA_DO_NOT_CONFIGURE_THIS_EP)) ipa_install_dflt_flt_rules(ipa_ep_idx); IPADBG("client %d (ep: %d) connected\n", in->client, ipa_ep_idx); return 0; Loading Loading @@ -431,6 +436,8 @@ int ipa_disconnect(u32 clnt_hdl) return -EPERM; } ipa_delete_dflt_flt_rules(clnt_hdl); memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context)); ipa_dec_client_disable_clks(); Loading drivers/platform/msm/ipa/ipa_dp.c +4 −0 Original line number Diff line number Diff line Loading @@ -1052,6 +1052,9 @@ int ipa_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) ipa_allocate_wlan_rx_common_cache(IPA_WLAN_COMM_RX_POOL_LOW); } if (sys_in->client == IPA_CLIENT_WLAN1_PROD) ipa_install_dflt_flt_rules(ipa_ep_idx); IPADBG("client %d (ep: %d) connected sys=%p\n", sys_in->client, ipa_ep_idx, ep->sys); Loading Loading @@ -1103,6 +1106,7 @@ int ipa_teardown_sys_pipe(u32 clnt_hdl) sps_free_endpoint(ep->ep_hdl); destroy_workqueue(ep->sys->wq); kfree(ep->sys); ipa_delete_dflt_flt_rules(clnt_hdl); memset(ep, 0, sizeof(struct ipa_ep_context)); IPADBG("client (ep: %d) disconnected\n", clnt_hdl); Loading drivers/platform/msm/ipa/ipa_flt.c +52 −4 Original line number Diff line number Diff line /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -948,10 +948,15 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip, if (!rule->eq_attrib_type) entry->rt_tbl = (struct ipa_rt_tbl *)rule->rt_tbl_hdl; entry->tbl = tbl; if (add_rear) list_add_tail(&entry->link, &tbl->head_flt_rule_list); if (add_rear) { if (tbl->sticky_rear) list_add_tail(&entry->link, tbl->head_flt_rule_list.prev); else list_add_tail(&entry->link, &tbl->head_flt_rule_list); } else { list_add(&entry->link, &tbl->head_flt_rule_list); } tbl->rule_cnt++; if (entry->rt_tbl) entry->rt_tbl->ref_cnt++; Loading Loading @@ -1261,3 +1266,46 @@ int ipa_reset_flt(enum ipa_ip_type ip) return 0; } EXPORT_SYMBOL(ipa_reset_flt); void ipa_install_dflt_flt_rules(u32 ipa_ep_idx) { struct ipa_flt_tbl *tbl; struct ipa_ep_context *ep = &ipa_ctx->ep[ipa_ep_idx]; struct ipa_flt_rule rule; memset(&rule, 0, sizeof(rule)); mutex_lock(&ipa_ctx->lock); tbl = &ipa_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v4]; tbl->sticky_rear = true; rule.action = IPA_PASS_TO_EXCEPTION; __ipa_add_flt_rule(tbl, IPA_IP_v4, &rule, false, &ep->dflt_flt4_rule_hdl); ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v4); tbl = &ipa_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v6]; tbl->sticky_rear = true; rule.action = IPA_PASS_TO_EXCEPTION; __ipa_add_flt_rule(tbl, IPA_IP_v6, &rule, false, &ep->dflt_flt6_rule_hdl); ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v6); mutex_unlock(&ipa_ctx->lock); } void ipa_delete_dflt_flt_rules(u32 ipa_ep_idx) { struct ipa_ep_context *ep = &ipa_ctx->ep[ipa_ep_idx]; mutex_lock(&ipa_ctx->lock); if (ep->dflt_flt4_rule_hdl) { __ipa_del_flt_rule(ep->dflt_flt4_rule_hdl); ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v4); ep->dflt_flt4_rule_hdl = 0; } if (ep->dflt_flt6_rule_hdl) { __ipa_del_flt_rule(ep->dflt_flt6_rule_hdl); ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v6); ep->dflt_flt6_rule_hdl = 0; } mutex_unlock(&ipa_ctx->lock); } drivers/platform/msm/ipa/ipa_i.h +5 −1 Original line number Diff line number Diff line Loading @@ -268,6 +268,7 @@ struct ipa_flt_tbl { u32 sz; struct ipa_mem_buffer curr_mem; struct ipa_mem_buffer prev_mem; bool sticky_rear; }; /** Loading Loading @@ -350,6 +351,8 @@ struct ipa_ep_context { bool suspended; struct ipa_sys_context *sys; u32 avail_fifo_desc; u32 dflt_flt4_rule_hdl; u32 dflt_flt6_rule_hdl; }; enum ipa_sys_pipe_policy { Loading Loading @@ -964,8 +967,9 @@ int __ipa_commit_hdr_v2(void); int ipa_generate_flt_eq(enum ipa_ip_type ip, const struct ipa_rule_attrib *attrib, struct ipa_ipfltri_rule_eq *eq_attrib); void ipa_skb_recycle(struct sk_buff *skb); void ipa_install_dflt_flt_rules(u32 ipa_ep_idx); void ipa_delete_dflt_flt_rules(u32 ipa_ep_idx); int ipa_enable_data_path(u32 clnt_hdl); int ipa_disable_data_path(u32 clnt_hdl); Loading Loading
drivers/platform/msm/ipa/ipa_client.c +7 −0 Original line number Diff line number Diff line Loading @@ -325,6 +325,11 @@ int ipa_connect(const struct ipa_connect_params *in, struct ipa_sps_params *sps, ipa_program_holb(ep, ipa_ep_idx); if (in->client == IPA_CLIENT_USB_PROD && ((enum ipa_config_this_ep)ep->priv != IPA_DO_NOT_CONFIGURE_THIS_EP)) ipa_install_dflt_flt_rules(ipa_ep_idx); IPADBG("client %d (ep: %d) connected\n", in->client, ipa_ep_idx); return 0; Loading Loading @@ -431,6 +436,8 @@ int ipa_disconnect(u32 clnt_hdl) return -EPERM; } ipa_delete_dflt_flt_rules(clnt_hdl); memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context)); ipa_dec_client_disable_clks(); Loading
drivers/platform/msm/ipa/ipa_dp.c +4 −0 Original line number Diff line number Diff line Loading @@ -1052,6 +1052,9 @@ int ipa_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) ipa_allocate_wlan_rx_common_cache(IPA_WLAN_COMM_RX_POOL_LOW); } if (sys_in->client == IPA_CLIENT_WLAN1_PROD) ipa_install_dflt_flt_rules(ipa_ep_idx); IPADBG("client %d (ep: %d) connected sys=%p\n", sys_in->client, ipa_ep_idx, ep->sys); Loading Loading @@ -1103,6 +1106,7 @@ int ipa_teardown_sys_pipe(u32 clnt_hdl) sps_free_endpoint(ep->ep_hdl); destroy_workqueue(ep->sys->wq); kfree(ep->sys); ipa_delete_dflt_flt_rules(clnt_hdl); memset(ep, 0, sizeof(struct ipa_ep_context)); IPADBG("client (ep: %d) disconnected\n", clnt_hdl); Loading
drivers/platform/msm/ipa/ipa_flt.c +52 −4 Original line number Diff line number Diff line /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -948,10 +948,15 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip, if (!rule->eq_attrib_type) entry->rt_tbl = (struct ipa_rt_tbl *)rule->rt_tbl_hdl; entry->tbl = tbl; if (add_rear) list_add_tail(&entry->link, &tbl->head_flt_rule_list); if (add_rear) { if (tbl->sticky_rear) list_add_tail(&entry->link, tbl->head_flt_rule_list.prev); else list_add_tail(&entry->link, &tbl->head_flt_rule_list); } else { list_add(&entry->link, &tbl->head_flt_rule_list); } tbl->rule_cnt++; if (entry->rt_tbl) entry->rt_tbl->ref_cnt++; Loading Loading @@ -1261,3 +1266,46 @@ int ipa_reset_flt(enum ipa_ip_type ip) return 0; } EXPORT_SYMBOL(ipa_reset_flt); void ipa_install_dflt_flt_rules(u32 ipa_ep_idx) { struct ipa_flt_tbl *tbl; struct ipa_ep_context *ep = &ipa_ctx->ep[ipa_ep_idx]; struct ipa_flt_rule rule; memset(&rule, 0, sizeof(rule)); mutex_lock(&ipa_ctx->lock); tbl = &ipa_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v4]; tbl->sticky_rear = true; rule.action = IPA_PASS_TO_EXCEPTION; __ipa_add_flt_rule(tbl, IPA_IP_v4, &rule, false, &ep->dflt_flt4_rule_hdl); ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v4); tbl = &ipa_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v6]; tbl->sticky_rear = true; rule.action = IPA_PASS_TO_EXCEPTION; __ipa_add_flt_rule(tbl, IPA_IP_v6, &rule, false, &ep->dflt_flt6_rule_hdl); ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v6); mutex_unlock(&ipa_ctx->lock); } void ipa_delete_dflt_flt_rules(u32 ipa_ep_idx) { struct ipa_ep_context *ep = &ipa_ctx->ep[ipa_ep_idx]; mutex_lock(&ipa_ctx->lock); if (ep->dflt_flt4_rule_hdl) { __ipa_del_flt_rule(ep->dflt_flt4_rule_hdl); ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v4); ep->dflt_flt4_rule_hdl = 0; } if (ep->dflt_flt6_rule_hdl) { __ipa_del_flt_rule(ep->dflt_flt6_rule_hdl); ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v6); ep->dflt_flt6_rule_hdl = 0; } mutex_unlock(&ipa_ctx->lock); }
drivers/platform/msm/ipa/ipa_i.h +5 −1 Original line number Diff line number Diff line Loading @@ -268,6 +268,7 @@ struct ipa_flt_tbl { u32 sz; struct ipa_mem_buffer curr_mem; struct ipa_mem_buffer prev_mem; bool sticky_rear; }; /** Loading Loading @@ -350,6 +351,8 @@ struct ipa_ep_context { bool suspended; struct ipa_sys_context *sys; u32 avail_fifo_desc; u32 dflt_flt4_rule_hdl; u32 dflt_flt6_rule_hdl; }; enum ipa_sys_pipe_policy { Loading Loading @@ -964,8 +967,9 @@ int __ipa_commit_hdr_v2(void); int ipa_generate_flt_eq(enum ipa_ip_type ip, const struct ipa_rule_attrib *attrib, struct ipa_ipfltri_rule_eq *eq_attrib); void ipa_skb_recycle(struct sk_buff *skb); void ipa_install_dflt_flt_rules(u32 ipa_ep_idx); void ipa_delete_dflt_flt_rules(u32 ipa_ep_idx); int ipa_enable_data_path(u32 clnt_hdl); int ipa_disable_data_path(u32 clnt_hdl); Loading