msm: ipa: support ipacm cleanup
Support header/filter, routing rules cleanup when user-space module crashed like ipacm and also cached the wlan client connect messages for ipacm to query. Change-Id: Ib09cbe0e9114aa5a5673898ff796de7e7944af35 Acked-by: Pooja Kumari <kumarip@qti.qualcomm.com> Signed-off-by: Mohammed Javid <mjavid@codeaurora.org> Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
This commit is contained in:
parent
eea1a62727
commit
aef2c9f15c
22 changed files with 1329 additions and 477 deletions
|
@ -340,13 +340,13 @@ int ipa_disconnect(u32 clnt_hdl)
|
|||
EXPORT_SYMBOL(ipa_disconnect);
|
||||
|
||||
/**
|
||||
* ipa_clear_endpoint_delay() - Clear ep_delay.
|
||||
* @clnt_hdl: [in] IPA client handle
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
* ipa_clear_endpoint_delay() - Clear ep_delay.
|
||||
* @clnt_hdl: [in] IPA client handle
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa_clear_endpoint_delay(u32 clnt_hdl)
|
||||
{
|
||||
int ret;
|
||||
|
@ -358,13 +358,13 @@ int ipa_clear_endpoint_delay(u32 clnt_hdl)
|
|||
EXPORT_SYMBOL(ipa_clear_endpoint_delay);
|
||||
|
||||
/**
|
||||
* ipa_reset_endpoint() - reset an endpoint from BAM perspective
|
||||
* @clnt_hdl: [in] IPA client handle
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
* ipa_reset_endpoint() - reset an endpoint from BAM perspective
|
||||
* @clnt_hdl: [in] IPA client handle
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa_reset_endpoint(u32 clnt_hdl)
|
||||
{
|
||||
int ret;
|
||||
|
@ -376,13 +376,13 @@ int ipa_reset_endpoint(u32 clnt_hdl)
|
|||
EXPORT_SYMBOL(ipa_reset_endpoint);
|
||||
|
||||
/**
|
||||
* ipa_disable_endpoint() - Disable an endpoint from IPA perspective
|
||||
* @clnt_hdl: [in] IPA client handle
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
* ipa_disable_endpoint() - Disable an endpoint from IPA perspective
|
||||
* @clnt_hdl: [in] IPA client handle
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa_disable_endpoint(u32 clnt_hdl)
|
||||
{
|
||||
int ret;
|
||||
|
@ -676,8 +676,28 @@ int ipa_add_hdr(struct ipa_ioc_add_hdr *hdrs)
|
|||
EXPORT_SYMBOL(ipa_add_hdr);
|
||||
|
||||
/**
|
||||
* ipa_del_hdr() - Remove the specified headers from SW and optionally commit them
|
||||
* to IPA HW
|
||||
* 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
|
||||
* commit them to IPA HW
|
||||
* @hdls: [inout] set of headers to delete
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
|
@ -715,15 +735,16 @@ EXPORT_SYMBOL(ipa_commit_hdr);
|
|||
* ipa_reset_hdr() - reset the current header table in SW (does not commit to
|
||||
* HW)
|
||||
*
|
||||
* @user_only: [in] indicate delete rules installed by userspace
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa_reset_hdr(void)
|
||||
int ipa_reset_hdr(bool user_only)
|
||||
{
|
||||
int ret;
|
||||
|
||||
IPA_API_DISPATCH_RETURN(ipa_reset_hdr);
|
||||
IPA_API_DISPATCH_RETURN(ipa_reset_hdr, user_only);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -793,16 +814,18 @@ EXPORT_SYMBOL(ipa_copy_hdr);
|
|||
* ipa_add_hdr_proc_ctx() - add the specified headers to SW
|
||||
* and optionally commit them to IPA HW
|
||||
* @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
|
||||
*
|
||||
* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -847,6 +870,26 @@ int ipa_add_rt_rule(struct ipa_ioc_add_rt_rule *rules)
|
|||
}
|
||||
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
|
||||
* commit to IPA HW
|
||||
|
@ -889,16 +932,17 @@ EXPORT_SYMBOL(ipa_commit_rt);
|
|||
* ipa_reset_rt() - reset the current SW routing table of specified type
|
||||
* (does not commit to HW)
|
||||
* @ip: The family of routing tables
|
||||
* @user_only: [in] indicate delete rules installed by userspace
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* 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;
|
||||
|
||||
IPA_API_DISPATCH_RETURN(ipa_reset_rt, ip);
|
||||
IPA_API_DISPATCH_RETURN(ipa_reset_rt, ip, user_only);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -981,6 +1025,7 @@ EXPORT_SYMBOL(ipa_mdfy_rt_rule);
|
|||
/**
|
||||
* ipa_add_flt_rule() - Add the specified filtering rules to SW and optionally
|
||||
* commit to IPA HW
|
||||
* @rules: [inout] set of filtering rules to add
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
|
@ -996,6 +1041,26 @@ int ipa_add_flt_rule(struct ipa_ioc_add_flt_rule *rules)
|
|||
}
|
||||
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
|
||||
* optionally commit to IPA HW
|
||||
|
@ -1054,17 +1119,18 @@ EXPORT_SYMBOL(ipa_commit_flt);
|
|||
/**
|
||||
* ipa_reset_flt() - Reset the current SW filtering table of specified type
|
||||
* (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
|
||||
*
|
||||
* 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;
|
||||
|
||||
IPA_API_DISPATCH_RETURN(ipa_reset_flt, ip);
|
||||
IPA_API_DISPATCH_RETURN(ipa_reset_flt, ip, user_only);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1710,20 +1776,20 @@ int ipa_uc_dereg_rdyCB(void)
|
|||
EXPORT_SYMBOL(ipa_uc_dereg_rdyCB);
|
||||
|
||||
/**
|
||||
* teth_bridge_init() - Initialize the Tethering bridge driver
|
||||
* @params - in/out params for USB initialization API (please look at struct
|
||||
* definition for more info)
|
||||
*
|
||||
* USB driver gets a pointer to a callback function (usb_notify_cb) and an
|
||||
* associated data. USB driver installs this callback function in the call to
|
||||
* ipa_connect().
|
||||
*
|
||||
* Builds IPA resource manager dependency graph.
|
||||
*
|
||||
* Return codes: 0: success,
|
||||
* -EINVAL - Bad parameter
|
||||
* Other negative value - Failure
|
||||
*/
|
||||
* teth_bridge_init() - Initialize the Tethering bridge driver
|
||||
* @params - in/out params for USB initialization API (please look at struct
|
||||
* definition for more info)
|
||||
*
|
||||
* USB driver gets a pointer to a callback function (usb_notify_cb) and an
|
||||
* associated data. USB driver installs this callback function in the call to
|
||||
* ipa_connect().
|
||||
*
|
||||
* Builds IPA resource manager dependency graph.
|
||||
*
|
||||
* Return codes: 0: success,
|
||||
* -EINVAL - Bad parameter
|
||||
* Other negative value - Failure
|
||||
*/
|
||||
int teth_bridge_init(struct teth_bridge_init_params *params)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1735,8 +1801,8 @@ int teth_bridge_init(struct teth_bridge_init_params *params)
|
|||
EXPORT_SYMBOL(teth_bridge_init);
|
||||
|
||||
/**
|
||||
* teth_bridge_disconnect() - Disconnect tethering bridge module
|
||||
*/
|
||||
* teth_bridge_disconnect() - Disconnect tethering bridge module
|
||||
*/
|
||||
int teth_bridge_disconnect(enum ipa_client_type client)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1748,14 +1814,14 @@ int teth_bridge_disconnect(enum ipa_client_type client)
|
|||
EXPORT_SYMBOL(teth_bridge_disconnect);
|
||||
|
||||
/**
|
||||
* teth_bridge_connect() - Connect bridge for a tethered Rmnet / MBIM call
|
||||
* @connect_params: Connection info
|
||||
*
|
||||
* Return codes: 0: success
|
||||
* -EINVAL: invalid parameters
|
||||
* -EPERM: Operation not permitted as the bridge is already
|
||||
* connected
|
||||
*/
|
||||
* teth_bridge_connect() - Connect bridge for a tethered Rmnet / MBIM call
|
||||
* @connect_params: Connection info
|
||||
*
|
||||
* Return codes: 0: success
|
||||
* -EINVAL: invalid parameters
|
||||
* -EPERM: Operation not permitted as the bridge is already
|
||||
* connected
|
||||
*/
|
||||
int teth_bridge_connect(struct teth_bridge_connect_params *connect_params)
|
||||
{
|
||||
int ret;
|
||||
|
@ -2232,16 +2298,16 @@ int ipa_write_qmap_id(struct ipa_ioc_write_qmapid *param_in)
|
|||
EXPORT_SYMBOL(ipa_write_qmap_id);
|
||||
|
||||
/**
|
||||
* ipa_add_interrupt_handler() - Adds handler to an interrupt type
|
||||
* @interrupt: Interrupt type
|
||||
* @handler: The handler to be added
|
||||
* @deferred_flag: whether the handler processing should be deferred in
|
||||
* a workqueue
|
||||
* @private_data: the client's private data
|
||||
*
|
||||
* Adds handler to an interrupt type and enable the specific bit
|
||||
* in IRQ_EN register, associated interrupt in IRQ_STTS register will be enabled
|
||||
*/
|
||||
* ipa_add_interrupt_handler() - Adds handler to an interrupt type
|
||||
* @interrupt: Interrupt type
|
||||
* @handler: The handler to be added
|
||||
* @deferred_flag: whether the handler processing should be deferred in
|
||||
* a workqueue
|
||||
* @private_data: the client's private data
|
||||
*
|
||||
* Adds handler to an interrupt type and enable the specific bit
|
||||
* in IRQ_EN register, associated interrupt in IRQ_STTS register will be enabled
|
||||
*/
|
||||
int ipa_add_interrupt_handler(enum ipa_irq_type interrupt,
|
||||
ipa_irq_handler_t handler,
|
||||
bool deferred_flag,
|
||||
|
@ -2257,11 +2323,11 @@ int ipa_add_interrupt_handler(enum ipa_irq_type interrupt,
|
|||
EXPORT_SYMBOL(ipa_add_interrupt_handler);
|
||||
|
||||
/**
|
||||
* ipa_remove_interrupt_handler() - Removes handler to an interrupt type
|
||||
* @interrupt: Interrupt type
|
||||
*
|
||||
* Removes the handler and disable the specific bit in IRQ_EN register
|
||||
*/
|
||||
* ipa_remove_interrupt_handler() - Removes handler to an interrupt type
|
||||
* @interrupt: Interrupt type
|
||||
*
|
||||
* Removes the handler and disable the specific bit in IRQ_EN register
|
||||
*/
|
||||
int ipa_remove_interrupt_handler(enum ipa_irq_type interrupt)
|
||||
{
|
||||
int ret;
|
||||
|
@ -2273,12 +2339,12 @@ int ipa_remove_interrupt_handler(enum ipa_irq_type interrupt)
|
|||
EXPORT_SYMBOL(ipa_remove_interrupt_handler);
|
||||
|
||||
/**
|
||||
* ipa_restore_suspend_handler() - restores the original suspend IRQ handler
|
||||
* as it was registered in the IPA init sequence.
|
||||
* Return codes:
|
||||
* 0: success
|
||||
* -EPERM: failed to remove current handler or failed to add original handler
|
||||
* */
|
||||
* ipa_restore_suspend_handler() - restores the original suspend IRQ handler
|
||||
* as it was registered in the IPA init sequence.
|
||||
* Return codes:
|
||||
* 0: success
|
||||
* -EPERM: failed to remove current handler or failed to add original handler
|
||||
*/
|
||||
int ipa_restore_suspend_handler(void)
|
||||
{
|
||||
int ret;
|
||||
|
@ -2621,10 +2687,10 @@ static int ipa_generic_plat_drv_probe(struct platform_device *pdev_p)
|
|||
{
|
||||
int result;
|
||||
|
||||
/*
|
||||
* IPA probe function can be called for multiple times as the same probe
|
||||
* function handles multiple compatibilities
|
||||
*/
|
||||
/**
|
||||
* IPA probe function can be called for multiple times as the same probe
|
||||
* function handles multiple compatibilities
|
||||
*/
|
||||
pr_debug("ipa: IPA driver probing started for %s\n",
|
||||
pdev_p->dev.of_node->name);
|
||||
|
||||
|
@ -2747,7 +2813,7 @@ EXPORT_SYMBOL(ipa_register_ipa_ready_cb);
|
|||
*
|
||||
* Return codes:
|
||||
* None
|
||||
*/
|
||||
*/
|
||||
void ipa_inc_client_enable_clks(struct ipa_active_client_logging_info *id)
|
||||
{
|
||||
IPA_API_DISPATCH(ipa_inc_client_enable_clks, id);
|
||||
|
@ -2763,7 +2829,7 @@ EXPORT_SYMBOL(ipa_inc_client_enable_clks);
|
|||
*
|
||||
* Return codes:
|
||||
* None
|
||||
*/
|
||||
*/
|
||||
void ipa_dec_client_disable_clks(struct ipa_active_client_logging_info *id)
|
||||
{
|
||||
IPA_API_DISPATCH(ipa_dec_client_disable_clks, id);
|
||||
|
@ -2793,14 +2859,14 @@ int ipa_inc_client_enable_clks_no_block(
|
|||
EXPORT_SYMBOL(ipa_inc_client_enable_clks_no_block);
|
||||
|
||||
/**
|
||||
* ipa_suspend_resource_no_block() - suspend client endpoints related to the
|
||||
* IPA_RM resource and decrement active clients counter. This function is
|
||||
* guaranteed to avoid sleeping.
|
||||
*
|
||||
* @resource: [IN] IPA Resource Manager resource
|
||||
*
|
||||
* Return codes: 0 on success, negative on failure.
|
||||
*/
|
||||
* ipa_suspend_resource_no_block() - suspend client endpoints related to the
|
||||
* IPA_RM resource and decrement active clients counter. This function is
|
||||
* guaranteed to avoid sleeping.
|
||||
*
|
||||
* @resource: [IN] IPA Resource Manager resource
|
||||
*
|
||||
* Return codes: 0 on success, negative on failure.
|
||||
*/
|
||||
int ipa_suspend_resource_no_block(enum ipa_rm_resource_name resource)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
@ -69,11 +69,13 @@ struct ipa_api_controller {
|
|||
|
||||
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_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);
|
||||
|
||||
|
@ -81,17 +83,21 @@ struct ipa_api_controller {
|
|||
|
||||
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_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_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);
|
||||
|
||||
|
@ -103,13 +109,16 @@ struct ipa_api_controller {
|
|||
|
||||
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_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);
|
||||
int (*ipa_reset_flt)(enum ipa_ip_type ip, bool user_only);
|
||||
|
||||
int (*allocate_nat_device)(struct ipa_ioc_nat_alloc_mem *mem);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, 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
|
||||
|
@ -296,11 +296,13 @@ struct ipa_mhi_connect_params_internal {
|
|||
* @link: entry's link in global header offset entries list
|
||||
* @offset: the offset
|
||||
* @bin: bin
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa_hdr_offset_entry {
|
||||
struct list_head link;
|
||||
u32 offset;
|
||||
u32 bin;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
extern const char *ipa_clients_strings[];
|
||||
|
|
|
@ -279,6 +279,28 @@ int ipa2_active_clients_log_print_table(char *buf, int size)
|
|||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
static int ipa2_clean_modem_rule(void)
|
||||
{
|
||||
struct ipa_install_fltr_rule_req_msg_v01 *req;
|
||||
int val = 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 = qmi_filter_request_send(req);
|
||||
kfree(req);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int ipa2_active_clients_panic_notifier(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
|
@ -531,7 +553,8 @@ static void ipa_wan_msg_free_cb(void *buff, u32 len, u32 type)
|
|||
kfree(buff);
|
||||
}
|
||||
|
||||
static int ipa_send_wan_msg(unsigned long usr_param, uint8_t msg_type, bool is_cache)
|
||||
static int ipa_send_wan_msg(unsigned long usr_param, uint8_t msg_type,
|
||||
bool is_cache)
|
||||
{
|
||||
int retval;
|
||||
struct ipa_wan_msg *wan_msg;
|
||||
|
@ -716,7 +739,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (ipa2_add_hdr((struct ipa_ioc_add_hdr *)param)) {
|
||||
if (ipa2_add_hdr_usr((struct ipa_ioc_add_hdr *)param,
|
||||
true)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
@ -796,7 +820,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (ipa2_add_rt_rule((struct ipa_ioc_add_rt_rule *)param)) {
|
||||
if (ipa2_add_rt_rule_usr((struct ipa_ioc_add_rt_rule *)param,
|
||||
true)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
@ -915,7 +940,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (ipa2_add_flt_rule((struct ipa_ioc_add_flt_rule *)param)) {
|
||||
if (ipa2_add_flt_rule_usr((struct ipa_ioc_add_flt_rule *)param,
|
||||
true)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
@ -1009,19 +1035,19 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
retval = ipa2_commit_hdr();
|
||||
break;
|
||||
case IPA_IOC_RESET_HDR:
|
||||
retval = ipa2_reset_hdr();
|
||||
retval = ipa2_reset_hdr(false);
|
||||
break;
|
||||
case IPA_IOC_COMMIT_RT:
|
||||
retval = ipa2_commit_rt(arg);
|
||||
break;
|
||||
case IPA_IOC_RESET_RT:
|
||||
retval = ipa2_reset_rt(arg);
|
||||
retval = ipa2_reset_rt(arg, false);
|
||||
break;
|
||||
case IPA_IOC_COMMIT_FLT:
|
||||
retval = ipa2_commit_flt(arg);
|
||||
break;
|
||||
case IPA_IOC_RESET_FLT:
|
||||
retval = ipa2_reset_flt(arg);
|
||||
retval = ipa2_reset_flt(arg, false);
|
||||
break;
|
||||
case IPA_IOC_GET_RT_TBL:
|
||||
if (copy_from_user(header, (u8 *)arg,
|
||||
|
@ -1401,7 +1427,7 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
break;
|
||||
}
|
||||
if (ipa2_add_hdr_proc_ctx(
|
||||
(struct ipa_ioc_add_hdr_proc_ctx *)param)) {
|
||||
(struct ipa_ioc_add_hdr_proc_ctx *)param, true)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
@ -1465,7 +1491,22 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
}
|
||||
break;
|
||||
|
||||
default: /* redundant, as cmd was checked against MAXNR */
|
||||
case IPA_IOC_CLEANUP:
|
||||
/*Route and filter rules will also be clean*/
|
||||
IPADBG("Got IPA_IOC_CLEANUP\n");
|
||||
retval = ipa2_reset_hdr(true);
|
||||
memset(&nat_del, 0, sizeof(nat_del));
|
||||
nat_del.table_index = 0;
|
||||
retval = ipa2_nat_del_cmd(&nat_del);
|
||||
retval = ipa2_clean_modem_rule();
|
||||
break;
|
||||
|
||||
case IPA_IOC_QUERY_WLAN_CLIENT:
|
||||
IPADBG("Got IPA_IOC_QUERY_WLAN_CLIENT\n");
|
||||
retval = ipa2_resend_wlan_msg();
|
||||
break;
|
||||
|
||||
default:
|
||||
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
@ -1478,7 +1519,7 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
|
||||
/**
|
||||
* ipa_setup_dflt_rt_tables() - Setup default routing tables
|
||||
*
|
||||
|
||||
* Return codes:
|
||||
* 0: success
|
||||
* -ENOMEM: failed to allocate memory
|
||||
|
@ -4301,6 +4342,10 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p,
|
|||
init_waitqueue_head(&ipa_ctx->msg_waitq);
|
||||
mutex_init(&ipa_ctx->msg_lock);
|
||||
|
||||
/* store wlan client-connect-msg-list */
|
||||
INIT_LIST_HEAD(&ipa_ctx->msg_wlan_client_list);
|
||||
mutex_init(&ipa_ctx->msg_wlan_client_lock);
|
||||
|
||||
mutex_init(&ipa_ctx->lock);
|
||||
mutex_init(&ipa_ctx->nat_mem.lock);
|
||||
mutex_init(&ipa_ctx->ipa_cne_evt_lock);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, 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
|
||||
|
@ -1008,7 +1008,7 @@ fail_desc:
|
|||
|
||||
static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
|
||||
const struct ipa_flt_rule *rule, u8 add_rear,
|
||||
u32 *rule_hdl)
|
||||
u32 *rule_hdl, bool user)
|
||||
{
|
||||
struct ipa_flt_entry *entry;
|
||||
struct ipa_rt_tbl *rt_tbl = NULL;
|
||||
|
@ -1076,6 +1076,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
|
|||
}
|
||||
*rule_hdl = id;
|
||||
entry->id = id;
|
||||
entry->ipacm_installed = user;
|
||||
IPADBG_LOW("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
|
||||
|
||||
return 0;
|
||||
|
@ -1198,12 +1199,12 @@ static int __ipa_add_global_flt_rule(enum ipa_ip_type ip,
|
|||
tbl = &ipa_ctx->glob_flt_tbl[ip];
|
||||
IPADBG_LOW("add global flt rule ip=%d\n", ip);
|
||||
|
||||
return __ipa_add_flt_rule(tbl, ip, rule, add_rear, rule_hdl);
|
||||
return __ipa_add_flt_rule(tbl, ip, rule, add_rear, rule_hdl, false);
|
||||
}
|
||||
|
||||
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,
|
||||
u32 *rule_hdl)
|
||||
u32 *rule_hdl, bool user)
|
||||
{
|
||||
struct ipa_flt_tbl *tbl;
|
||||
int ipa_ep_idx;
|
||||
|
@ -1225,18 +1226,34 @@ static int __ipa_add_ep_flt_rule(enum ipa_ip_type ip, enum ipa_client_type ep,
|
|||
tbl = &ipa_ctx->flt_tbl[ipa_ep_idx][ip];
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa2_add_flt_rule() - Add the specified filtering rules to SW and optionally
|
||||
* commit to IPA HW
|
||||
* @rules: [inout] set of filtering rules to add
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa2_add_flt_rule(struct ipa_ioc_add_flt_rule *rules)
|
||||
{
|
||||
return ipa2_add_flt_rule_usr(rules, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa2_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 ipa2_add_flt_rule_usr(struct ipa_ioc_add_flt_rule *rules, bool user_only)
|
||||
{
|
||||
int i;
|
||||
int result;
|
||||
|
@ -1259,7 +1276,8 @@ int ipa2_add_flt_rule(struct ipa_ioc_add_flt_rule *rules)
|
|||
result = __ipa_add_ep_flt_rule(rules->ip, rules->ep,
|
||||
&rules->rules[i].rule,
|
||||
rules->rules[i].at_rear,
|
||||
&rules->rules[i].flt_rule_hdl);
|
||||
&rules->rules[i].flt_rule_hdl,
|
||||
user_only);
|
||||
if (result) {
|
||||
IPAERR_RL("failed to add flt rule %d\n", i);
|
||||
rules->rules[i].status = IPA_FLT_STATUS_OF_ADD_FAILED;
|
||||
|
@ -1396,13 +1414,14 @@ bail:
|
|||
/**
|
||||
* ipa2_reset_flt() - Reset the current SW filtering table of specified type
|
||||
* (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
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa2_reset_flt(enum ipa_ip_type ip)
|
||||
int ipa2_reset_flt(enum ipa_ip_type ip, bool user_only)
|
||||
{
|
||||
struct ipa_flt_tbl *tbl;
|
||||
struct ipa_flt_entry *entry;
|
||||
|
@ -1435,16 +1454,19 @@ int ipa2_reset_flt(enum ipa_ip_type ip)
|
|||
IPA_INVALID_L4_PROTOCOL))
|
||||
continue;
|
||||
|
||||
list_del(&entry->link);
|
||||
entry->tbl->rule_cnt--;
|
||||
if (entry->rt_tbl)
|
||||
entry->rt_tbl->ref_cnt--;
|
||||
entry->cookie = 0;
|
||||
id = entry->id;
|
||||
kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
|
||||
if (!user_only ||
|
||||
entry->ipacm_installed) {
|
||||
list_del(&entry->link);
|
||||
entry->tbl->rule_cnt--;
|
||||
if (entry->rt_tbl)
|
||||
entry->rt_tbl->ref_cnt--;
|
||||
entry->cookie = 0;
|
||||
id = entry->id;
|
||||
kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(id);
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ipa_ctx->ipa_num_pipes; i++) {
|
||||
|
@ -1456,16 +1478,21 @@ int ipa2_reset_flt(enum ipa_ip_type ip)
|
|||
mutex_unlock(&ipa_ctx->lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
list_del(&entry->link);
|
||||
entry->tbl->rule_cnt--;
|
||||
if (entry->rt_tbl)
|
||||
entry->rt_tbl->ref_cnt--;
|
||||
entry->cookie = 0;
|
||||
id = entry->id;
|
||||
kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(id);
|
||||
if (!user_only ||
|
||||
entry->ipacm_installed) {
|
||||
list_del(&entry->link);
|
||||
entry->tbl->rule_cnt--;
|
||||
if (entry->rt_tbl)
|
||||
entry->rt_tbl->ref_cnt--;
|
||||
entry->cookie = 0;
|
||||
id = entry->id;
|
||||
kmem_cache_free(ipa_ctx->flt_rule_cache,
|
||||
entry);
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ipa_ctx->lock);
|
||||
|
@ -1485,14 +1512,14 @@ void ipa_install_dflt_flt_rules(u32 ipa_ep_idx)
|
|||
tbl = &ipa_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v4];
|
||||
rule.action = IPA_PASS_TO_EXCEPTION;
|
||||
__ipa_add_flt_rule(tbl, IPA_IP_v4, &rule, true,
|
||||
&ep->dflt_flt4_rule_hdl);
|
||||
&ep->dflt_flt4_rule_hdl, false);
|
||||
ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v4);
|
||||
tbl->sticky_rear = true;
|
||||
|
||||
tbl = &ipa_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v6];
|
||||
rule.action = IPA_PASS_TO_EXCEPTION;
|
||||
__ipa_add_flt_rule(tbl, IPA_IP_v6, &rule, true,
|
||||
&ep->dflt_flt6_rule_hdl);
|
||||
&ep->dflt_flt6_rule_hdl, false);
|
||||
ipa_ctx->ctrl->ipa_commit_flt(IPA_IP_v6);
|
||||
tbl->sticky_rear = true;
|
||||
mutex_unlock(&ipa_ctx->lock);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, 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
|
||||
|
@ -543,7 +543,7 @@ int __ipa_commit_hdr_v2_6L(void)
|
|||
}
|
||||
|
||||
static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
||||
bool add_ref_hdr)
|
||||
bool add_ref_hdr, bool user_only)
|
||||
{
|
||||
struct ipa_hdr_entry *hdr_entry;
|
||||
struct ipa_hdr_proc_ctx_entry *entry;
|
||||
|
@ -581,6 +581,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
if (add_ref_hdr)
|
||||
hdr_entry->ref_cnt++;
|
||||
entry->cookie = IPA_PROC_HDR_COOKIE;
|
||||
entry->ipacm_installed = user_only;
|
||||
|
||||
needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
|
||||
sizeof(struct ipa_hdr_proc_ctx_add_hdr_seq) :
|
||||
|
@ -619,6 +620,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
*/
|
||||
offset->offset = htbl->end;
|
||||
offset->bin = bin;
|
||||
offset->ipacm_installed = user_only;
|
||||
htbl->end += ipa_hdr_proc_ctx_bin_sz[bin];
|
||||
list_add(&offset->link,
|
||||
&htbl->head_offset_list[bin]);
|
||||
|
@ -627,6 +629,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
offset =
|
||||
list_first_entry(&htbl->head_free_offset_list[bin],
|
||||
struct ipa_hdr_proc_ctx_offset_entry, link);
|
||||
offset->ipacm_installed = user_only;
|
||||
list_move(&offset->link, &htbl->head_offset_list[bin]);
|
||||
}
|
||||
|
||||
|
@ -664,7 +667,7 @@ bad_len:
|
|||
}
|
||||
|
||||
|
||||
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
||||
static int __ipa_add_hdr(struct ipa_hdr_add *hdr, bool user)
|
||||
{
|
||||
struct ipa_hdr_entry *entry;
|
||||
struct ipa_hdr_offset_entry *offset = NULL;
|
||||
|
@ -700,6 +703,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
|
||||
entry->eth2_ofst = hdr->eth2_ofst;
|
||||
entry->cookie = IPA_HDR_COOKIE;
|
||||
entry->ipacm_installed = user;
|
||||
|
||||
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
|
||||
bin = IPA_HDR_BIN0;
|
||||
|
@ -760,6 +764,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
list_add(&offset->link,
|
||||
&htbl->head_offset_list[bin]);
|
||||
entry->offset_entry = offset;
|
||||
offset->ipacm_installed = user;
|
||||
}
|
||||
} else {
|
||||
entry->is_hdr_proc_ctx = false;
|
||||
|
@ -769,6 +774,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
struct ipa_hdr_offset_entry, link);
|
||||
list_move(&offset->link, &htbl->head_offset_list[bin]);
|
||||
entry->offset_entry = offset;
|
||||
offset->ipacm_installed = user;
|
||||
}
|
||||
|
||||
list_add(&entry->link, &htbl->head_hdr_entry_list);
|
||||
|
@ -800,7 +806,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
IPADBG("adding processing context for header %s\n", hdr->name);
|
||||
proc_ctx.type = IPA_HDR_PROC_NONE;
|
||||
proc_ctx.hdr_hdl = id;
|
||||
if (__ipa_add_hdr_proc_ctx(&proc_ctx, false)) {
|
||||
if (__ipa_add_hdr_proc_ctx(&proc_ctx, false, user)) {
|
||||
IPAERR("failed to add hdr proc ctx\n");
|
||||
goto fail_add_proc_ctx;
|
||||
}
|
||||
|
@ -959,6 +965,21 @@ int __ipa_del_hdr(u32 hdr_hdl, bool by_user)
|
|||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa2_add_hdr(struct ipa_ioc_add_hdr *hdrs)
|
||||
{
|
||||
return ipa2_add_hdr_usr(hdrs, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa2_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 installed from user
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa2_add_hdr_usr(struct ipa_ioc_add_hdr *hdrs, bool user_only)
|
||||
{
|
||||
int i;
|
||||
int result = -EFAULT;
|
||||
|
@ -977,7 +998,7 @@ int ipa2_add_hdr(struct ipa_ioc_add_hdr *hdrs)
|
|||
IPADBG("adding %d headers to IPA driver internal data struct\n",
|
||||
hdrs->num_hdrs);
|
||||
for (i = 0; i < hdrs->num_hdrs; i++) {
|
||||
if (__ipa_add_hdr(&hdrs->hdr[i])) {
|
||||
if (__ipa_add_hdr(&hdrs->hdr[i], user_only)) {
|
||||
IPAERR_RL("failed to add hdr %d\n", i);
|
||||
hdrs->hdr[i].status = -1;
|
||||
} else {
|
||||
|
@ -997,7 +1018,6 @@ bail:
|
|||
mutex_unlock(&ipa_ctx->lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa2_del_hdr_by_user() - Remove the specified headers
|
||||
* from SW and optionally commit them to IPA HW
|
||||
|
@ -1063,12 +1083,14 @@ int ipa2_del_hdr(struct ipa_ioc_del_hdr *hdls)
|
|||
* ipa2_add_hdr_proc_ctx() - add the specified headers to SW
|
||||
* and optionally commit them to IPA HW
|
||||
* @proc_ctxs: [inout] set of processing context headers to add
|
||||
* @user_only: [in] indicate installed by user-space module
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa2_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs)
|
||||
int ipa2_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs,
|
||||
bool user_only)
|
||||
{
|
||||
int i;
|
||||
int result = -EFAULT;
|
||||
|
@ -1089,7 +1111,8 @@ int ipa2_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs)
|
|||
IPADBG("adding %d header processing contextes to IPA driver\n",
|
||||
proc_ctxs->num_proc_ctxs);
|
||||
for (i = 0; i < proc_ctxs->num_proc_ctxs; i++) {
|
||||
if (__ipa_add_hdr_proc_ctx(&proc_ctxs->proc_ctx[i], true)) {
|
||||
if (__ipa_add_hdr_proc_ctx(&proc_ctxs->proc_ctx[i],
|
||||
true, user_only)) {
|
||||
IPAERR_RL("failed to add hdr pric ctx %d\n", i);
|
||||
proc_ctxs->proc_ctx[i].status = -1;
|
||||
} else {
|
||||
|
@ -1211,11 +1234,12 @@ bail:
|
|||
* ipa2_reset_hdr() - reset the current header table in SW (does not commit to
|
||||
* HW)
|
||||
*
|
||||
* @user_only: [in] indicate delete rules installed by userspace
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa2_reset_hdr(void)
|
||||
int ipa2_reset_hdr(bool user_only)
|
||||
{
|
||||
struct ipa_hdr_entry *entry;
|
||||
struct ipa_hdr_entry *next;
|
||||
|
@ -1231,9 +1255,9 @@ int ipa2_reset_hdr(void)
|
|||
* issue a reset on the routing module since routing rules point to
|
||||
* header table entries
|
||||
*/
|
||||
if (ipa2_reset_rt(IPA_IP_v4))
|
||||
if (ipa2_reset_rt(IPA_IP_v4, user_only))
|
||||
IPAERR("fail to reset v4 rt\n");
|
||||
if (ipa2_reset_rt(IPA_IP_v6))
|
||||
if (ipa2_reset_rt(IPA_IP_v6, user_only))
|
||||
IPAERR("fail to reset v4 rt\n");
|
||||
|
||||
mutex_lock(&ipa_ctx->lock);
|
||||
|
@ -1262,21 +1286,23 @@ int ipa2_reset_hdr(void)
|
|||
WARN_ON(1);
|
||||
return -EFAULT;
|
||||
}
|
||||
if (entry->is_hdr_proc_ctx) {
|
||||
dma_unmap_single(ipa_ctx->pdev,
|
||||
entry->phys_base,
|
||||
entry->hdr_len,
|
||||
DMA_TO_DEVICE);
|
||||
entry->proc_ctx = NULL;
|
||||
|
||||
if (!user_only || entry->ipacm_installed) {
|
||||
if (entry->is_hdr_proc_ctx) {
|
||||
dma_unmap_single(ipa_ctx->pdev,
|
||||
entry->phys_base,
|
||||
entry->hdr_len,
|
||||
DMA_TO_DEVICE);
|
||||
entry->proc_ctx = NULL;
|
||||
}
|
||||
list_del(&entry->link);
|
||||
entry->ref_cnt = 0;
|
||||
entry->cookie = 0;
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(entry->id);
|
||||
kmem_cache_free(ipa_ctx->hdr_cache, entry);
|
||||
}
|
||||
list_del(&entry->link);
|
||||
entry->ref_cnt = 0;
|
||||
entry->cookie = 0;
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(entry->id);
|
||||
kmem_cache_free(ipa_ctx->hdr_cache, entry);
|
||||
|
||||
}
|
||||
for (i = 0; i < IPA_HDR_BIN_MAX; i++) {
|
||||
list_for_each_entry_safe(off_entry, off_next,
|
||||
|
@ -1290,14 +1316,23 @@ int ipa2_reset_hdr(void)
|
|||
if (off_entry->offset == 0)
|
||||
continue;
|
||||
|
||||
list_del(&off_entry->link);
|
||||
kmem_cache_free(ipa_ctx->hdr_offset_cache, off_entry);
|
||||
if (!user_only ||
|
||||
off_entry->ipacm_installed) {
|
||||
list_del(&off_entry->link);
|
||||
kmem_cache_free(ipa_ctx->hdr_offset_cache,
|
||||
off_entry);
|
||||
}
|
||||
}
|
||||
list_for_each_entry_safe(off_entry, off_next,
|
||||
&ipa_ctx->hdr_tbl.head_free_offset_list[i],
|
||||
link) {
|
||||
list_del(&off_entry->link);
|
||||
kmem_cache_free(ipa_ctx->hdr_offset_cache, off_entry);
|
||||
|
||||
if (!user_only ||
|
||||
off_entry->ipacm_installed) {
|
||||
list_del(&off_entry->link);
|
||||
kmem_cache_free(ipa_ctx->hdr_offset_cache,
|
||||
off_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* there is one header of size 8 */
|
||||
|
@ -1316,30 +1351,43 @@ int ipa2_reset_hdr(void)
|
|||
WARN_ON(1);
|
||||
return -EFAULT;
|
||||
}
|
||||
list_del(&ctx_entry->link);
|
||||
ctx_entry->ref_cnt = 0;
|
||||
ctx_entry->cookie = 0;
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(ctx_entry->id);
|
||||
kmem_cache_free(ipa_ctx->hdr_proc_ctx_cache, ctx_entry);
|
||||
if (!user_only ||
|
||||
ctx_entry->ipacm_installed) {
|
||||
list_del(&ctx_entry->link);
|
||||
ctx_entry->ref_cnt = 0;
|
||||
ctx_entry->cookie = 0;
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(ctx_entry->id);
|
||||
kmem_cache_free(ipa_ctx->hdr_proc_ctx_cache,
|
||||
ctx_entry);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < IPA_HDR_PROC_CTX_BIN_MAX; i++) {
|
||||
list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
|
||||
&ipa_ctx->hdr_proc_ctx_tbl.head_offset_list[i],
|
||||
link) {
|
||||
|
||||
list_del(&ctx_off_entry->link);
|
||||
kmem_cache_free(ipa_ctx->hdr_proc_ctx_offset_cache,
|
||||
if (!user_only ||
|
||||
ctx_off_entry->ipacm_installed) {
|
||||
list_del(&ctx_off_entry->link);
|
||||
kmem_cache_free(
|
||||
ipa_ctx->hdr_proc_ctx_offset_cache,
|
||||
ctx_off_entry);
|
||||
}
|
||||
}
|
||||
list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
|
||||
&ipa_ctx->hdr_proc_ctx_tbl.head_free_offset_list[i],
|
||||
link) {
|
||||
list_del(&ctx_off_entry->link);
|
||||
kmem_cache_free(ipa_ctx->hdr_proc_ctx_offset_cache,
|
||||
ctx_off_entry);
|
||||
|
||||
if (!user_only ||
|
||||
ctx_off_entry->ipacm_installed) {
|
||||
list_del(&ctx_off_entry->link);
|
||||
kmem_cache_free(
|
||||
ipa_ctx->hdr_proc_ctx_offset_cache,
|
||||
ctx_off_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
ipa_ctx->hdr_proc_ctx_tbl.end = 0;
|
||||
|
|
|
@ -242,6 +242,8 @@ struct ipa_smmu_cb_ctx {
|
|||
* @tbl: filter table
|
||||
* @rt_tbl: routing table
|
||||
* @hw_len: entry's size
|
||||
* @id: rule handle - globally unique
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa_flt_entry {
|
||||
struct list_head link;
|
||||
|
@ -251,6 +253,7 @@ struct ipa_flt_entry {
|
|||
struct ipa_rt_tbl *rt_tbl;
|
||||
u32 hw_len;
|
||||
int id;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -305,6 +308,7 @@ struct ipa_rt_tbl {
|
|||
* @is_eth2_ofst_valid: is eth2_ofst field valid?
|
||||
* @eth2_ofst: offset to start of Ethernet-II/802.3 header
|
||||
* @user_deleted: is the header deleted by the user?
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa_hdr_entry {
|
||||
struct list_head link;
|
||||
|
@ -323,6 +327,7 @@ struct ipa_hdr_entry {
|
|||
u8 is_eth2_ofst_valid;
|
||||
u16 eth2_ofst;
|
||||
bool user_deleted;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -346,11 +351,13 @@ struct ipa_hdr_tbl {
|
|||
* @link: entry's link in global processing context header offset entries list
|
||||
* @offset: the offset
|
||||
* @bin: bin
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa_hdr_proc_ctx_offset_entry {
|
||||
struct list_head link;
|
||||
u32 offset;
|
||||
u32 bin;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -387,6 +394,7 @@ struct ipa_hdr_proc_ctx_add_hdr_cmd_seq {
|
|||
* @ref_cnt: reference counter of routing table
|
||||
* @id: processing context header entry id
|
||||
* @user_deleted: is the hdr processing context deleted by the user?
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa_hdr_proc_ctx_entry {
|
||||
struct list_head link;
|
||||
|
@ -397,6 +405,7 @@ struct ipa_hdr_proc_ctx_entry {
|
|||
u32 ref_cnt;
|
||||
int id;
|
||||
bool user_deleted;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -446,6 +455,8 @@ struct ipa_flt_tbl {
|
|||
* @hdr: header table
|
||||
* @proc_ctx: processing context table
|
||||
* @hw_len: the length of the table
|
||||
* @id: rule handle - globaly unique
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa_rt_entry {
|
||||
struct list_head link;
|
||||
|
@ -456,6 +467,7 @@ struct ipa_rt_entry {
|
|||
struct ipa_hdr_proc_ctx_entry *proc_ctx;
|
||||
u32 hw_len;
|
||||
int id;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1151,6 +1163,8 @@ struct ipa_context {
|
|||
struct list_head msg_list;
|
||||
struct list_head pull_msg_list;
|
||||
struct mutex msg_lock;
|
||||
struct list_head msg_wlan_client_list;
|
||||
struct mutex msg_wlan_client_lock;
|
||||
wait_queue_head_t msg_waitq;
|
||||
enum ipa_hw_type ipa_hw_type;
|
||||
enum ipa_hw_mode ipa_hw_mode;
|
||||
|
@ -1441,13 +1455,15 @@ int ipa2_cfg_ep_ctrl(u32 clnt_hdl, const struct ipa_ep_cfg_ctrl *ep_ctrl);
|
|||
*/
|
||||
int ipa2_add_hdr(struct ipa_ioc_add_hdr *hdrs);
|
||||
|
||||
int ipa2_add_hdr_usr(struct ipa_ioc_add_hdr *hdrs, bool by_user);
|
||||
|
||||
int ipa2_del_hdr(struct ipa_ioc_del_hdr *hdls);
|
||||
|
||||
int ipa2_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user);
|
||||
|
||||
int ipa2_commit_hdr(void);
|
||||
|
||||
int ipa2_reset_hdr(void);
|
||||
int ipa2_reset_hdr(bool user_only);
|
||||
|
||||
int ipa2_get_hdr(struct ipa_ioc_get_hdr *lookup);
|
||||
|
||||
|
@ -1458,7 +1474,8 @@ int ipa2_copy_hdr(struct ipa_ioc_copy_hdr *copy);
|
|||
/*
|
||||
* Header Processing Context
|
||||
*/
|
||||
int ipa2_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs);
|
||||
int ipa2_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs,
|
||||
bool user_only);
|
||||
|
||||
int ipa2_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls);
|
||||
|
||||
|
@ -1470,11 +1487,14 @@ int ipa2_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls,
|
|||
*/
|
||||
int ipa2_add_rt_rule(struct ipa_ioc_add_rt_rule *rules);
|
||||
|
||||
int ipa2_add_rt_rule_usr(struct ipa_ioc_add_rt_rule *rules,
|
||||
bool user_only);
|
||||
|
||||
int ipa2_del_rt_rule(struct ipa_ioc_del_rt_rule *hdls);
|
||||
|
||||
int ipa2_commit_rt(enum ipa_ip_type ip);
|
||||
|
||||
int ipa2_reset_rt(enum ipa_ip_type ip);
|
||||
int ipa2_reset_rt(enum ipa_ip_type ip, bool user_only);
|
||||
|
||||
int ipa2_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup);
|
||||
|
||||
|
@ -1489,13 +1509,16 @@ int ipa2_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *rules);
|
|||
*/
|
||||
int ipa2_add_flt_rule(struct ipa_ioc_add_flt_rule *rules);
|
||||
|
||||
int ipa2_add_flt_rule_usr(struct ipa_ioc_add_flt_rule *rules,
|
||||
bool user_only);
|
||||
|
||||
int ipa2_del_flt_rule(struct ipa_ioc_del_flt_rule *hdls);
|
||||
|
||||
int ipa2_mdfy_flt_rule(struct ipa_ioc_mdfy_flt_rule *rules);
|
||||
|
||||
int ipa2_commit_flt(enum ipa_ip_type ip);
|
||||
|
||||
int ipa2_reset_flt(enum ipa_ip_type ip);
|
||||
int ipa2_reset_flt(enum ipa_ip_type ip, bool user_only);
|
||||
|
||||
/*
|
||||
* NAT
|
||||
|
@ -1513,6 +1536,7 @@ int ipa2_nat_del_cmd(struct ipa_ioc_v4_nat_del *del);
|
|||
*/
|
||||
int ipa2_send_msg(struct ipa_msg_meta *meta, void *buff,
|
||||
ipa_msg_free_fn callback);
|
||||
int ipa2_resend_wlan_msg(void);
|
||||
int ipa2_register_pull_msg(struct ipa_msg_meta *meta, ipa_msg_pull_fn callback);
|
||||
int ipa2_deregister_pull_msg(struct ipa_msg_meta *meta);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, 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
|
||||
|
@ -13,6 +13,7 @@
|
|||
#include <linux/fs.h>
|
||||
#include <linux/sched.h>
|
||||
#include "ipa_i.h"
|
||||
#include <linux/msm_ipa.h>
|
||||
|
||||
struct ipa_intf {
|
||||
char name[IPA_RESOURCE_NAME_MAX];
|
||||
|
@ -377,6 +378,108 @@ static void ipa2_send_msg_free(void *buff, u32 len, u32 type)
|
|||
kfree(buff);
|
||||
}
|
||||
|
||||
static int wlan_msg_process(struct ipa_msg_meta *meta, void *buff)
|
||||
{
|
||||
struct ipa_push_msg *msg_dup;
|
||||
struct ipa_wlan_msg_ex *event_ex_cur_con = NULL;
|
||||
struct ipa_wlan_msg_ex *event_ex_list = NULL;
|
||||
struct ipa_wlan_msg *event_ex_cur_discon = NULL;
|
||||
void *data_dup = NULL;
|
||||
struct ipa_push_msg *entry;
|
||||
struct ipa_push_msg *next;
|
||||
int cnt = 0, total = 0, max = 0;
|
||||
uint8_t mac[IPA_MAC_ADDR_SIZE];
|
||||
uint8_t mac2[IPA_MAC_ADDR_SIZE];
|
||||
|
||||
if (meta->msg_type == WLAN_CLIENT_CONNECT_EX) {
|
||||
/* debug print */
|
||||
event_ex_cur_con = buff;
|
||||
for (cnt = 0; cnt < event_ex_cur_con->num_of_attribs; cnt++) {
|
||||
if (event_ex_cur_con->attribs[cnt].attrib_type ==
|
||||
WLAN_HDR_ATTRIB_MAC_ADDR) {
|
||||
IPADBG("%02x:%02x:%02x:%02x:%02x:%02x,(%d)\n",
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[0],
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[1],
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[2],
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[3],
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[4],
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[5],
|
||||
meta->msg_type);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&ipa_ctx->msg_wlan_client_lock);
|
||||
msg_dup = kzalloc(sizeof(struct ipa_push_msg), GFP_KERNEL);
|
||||
if (msg_dup == NULL) {
|
||||
IPAERR("fail to alloc ipa_msg container\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
msg_dup->meta = *meta;
|
||||
if (meta->msg_len > 0 && buff) {
|
||||
data_dup = kmalloc(meta->msg_len, GFP_KERNEL);
|
||||
if (data_dup == NULL) {
|
||||
IPAERR("fail to alloc data_dup container\n");
|
||||
kfree(msg_dup);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(data_dup, buff, meta->msg_len);
|
||||
msg_dup->buff = data_dup;
|
||||
msg_dup->callback = ipa2_send_msg_free;
|
||||
}
|
||||
list_add_tail(&msg_dup->link, &ipa_ctx->msg_wlan_client_list);
|
||||
mutex_unlock(&ipa_ctx->msg_wlan_client_lock);
|
||||
}
|
||||
|
||||
/* remove the cache */
|
||||
if (meta->msg_type == WLAN_CLIENT_DISCONNECT) {
|
||||
/* debug print */
|
||||
event_ex_cur_discon = buff;
|
||||
IPADBG("Mac %02x:%02x:%02x:%02x:%02x:%02x,msg %d\n",
|
||||
event_ex_cur_discon->mac_addr[0],
|
||||
event_ex_cur_discon->mac_addr[1],
|
||||
event_ex_cur_discon->mac_addr[2],
|
||||
event_ex_cur_discon->mac_addr[3],
|
||||
event_ex_cur_discon->mac_addr[4],
|
||||
event_ex_cur_discon->mac_addr[5],
|
||||
meta->msg_type);
|
||||
memcpy(mac2,
|
||||
event_ex_cur_discon->mac_addr,
|
||||
sizeof(mac2));
|
||||
|
||||
mutex_lock(&ipa_ctx->msg_wlan_client_lock);
|
||||
list_for_each_entry_safe(entry, next,
|
||||
&ipa_ctx->msg_wlan_client_list,
|
||||
link) {
|
||||
event_ex_list = entry->buff;
|
||||
max = event_ex_list->num_of_attribs;
|
||||
for (cnt = 0; cnt < max; cnt++) {
|
||||
memcpy(mac,
|
||||
event_ex_list->attribs[cnt].u.mac_addr,
|
||||
sizeof(mac));
|
||||
if (event_ex_list->attribs[cnt].attrib_type ==
|
||||
WLAN_HDR_ATTRIB_MAC_ADDR) {
|
||||
pr_debug("%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2],
|
||||
mac[3], mac[4], mac[5]);
|
||||
|
||||
/* compare to delete one*/
|
||||
if (memcmp(mac2,
|
||||
mac,
|
||||
sizeof(mac)) == 0) {
|
||||
IPADBG("clean %d\n", total);
|
||||
list_del(&entry->link);
|
||||
kfree(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
total++;
|
||||
}
|
||||
mutex_unlock(&ipa_ctx->msg_wlan_client_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa2_send_msg() - Send "message" from kernel client to IPA driver
|
||||
* @meta: [in] message meta-data
|
||||
|
@ -404,7 +507,7 @@ int ipa2_send_msg(struct ipa_msg_meta *meta, void *buff,
|
|||
}
|
||||
|
||||
if (meta == NULL || (buff == NULL && callback != NULL) ||
|
||||
(buff != NULL && callback == NULL)) {
|
||||
(buff != NULL && callback == NULL) || buff == NULL) {
|
||||
IPAERR_RL("invalid param meta=%p buff=%p, callback=%p\n",
|
||||
meta, buff, callback);
|
||||
return -EINVAL;
|
||||
|
@ -436,6 +539,11 @@ int ipa2_send_msg(struct ipa_msg_meta *meta, void *buff,
|
|||
|
||||
mutex_lock(&ipa_ctx->msg_lock);
|
||||
list_add_tail(&msg->link, &ipa_ctx->msg_list);
|
||||
/* support for softap client event cache */
|
||||
if (wlan_msg_process(meta, buff))
|
||||
IPAERR("wlan_msg_process failed\n");
|
||||
|
||||
/* unlock only after process */
|
||||
mutex_unlock(&ipa_ctx->msg_lock);
|
||||
IPA_STATS_INC_CNT(ipa_ctx->stats.msg_w[meta->msg_type]);
|
||||
|
||||
|
@ -446,6 +554,73 @@ int ipa2_send_msg(struct ipa_msg_meta *meta, void *buff,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa2_resend_wlan_msg() - Resend cached "message" to IPACM
|
||||
*
|
||||
* resend wlan client connect events to user-space
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa2_resend_wlan_msg(void)
|
||||
{
|
||||
struct ipa_wlan_msg_ex *event_ex_list = NULL;
|
||||
struct ipa_push_msg *entry;
|
||||
struct ipa_push_msg *next;
|
||||
int cnt = 0, total = 0;
|
||||
struct ipa_push_msg *msg;
|
||||
void *data = NULL;
|
||||
|
||||
IPADBG("\n");
|
||||
|
||||
mutex_lock(&ipa_ctx->msg_wlan_client_lock);
|
||||
list_for_each_entry_safe(entry, next, &ipa_ctx->msg_wlan_client_list,
|
||||
link) {
|
||||
|
||||
event_ex_list = entry->buff;
|
||||
for (cnt = 0; cnt < event_ex_list->num_of_attribs; cnt++) {
|
||||
if (event_ex_list->attribs[cnt].attrib_type ==
|
||||
WLAN_HDR_ATTRIB_MAC_ADDR) {
|
||||
IPADBG("%d-Mac %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
total,
|
||||
event_ex_list->attribs[cnt].u.mac_addr[0],
|
||||
event_ex_list->attribs[cnt].u.mac_addr[1],
|
||||
event_ex_list->attribs[cnt].u.mac_addr[2],
|
||||
event_ex_list->attribs[cnt].u.mac_addr[3],
|
||||
event_ex_list->attribs[cnt].u.mac_addr[4],
|
||||
event_ex_list->attribs[cnt].u.mac_addr[5]);
|
||||
}
|
||||
}
|
||||
|
||||
msg = kzalloc(sizeof(struct ipa_push_msg), GFP_KERNEL);
|
||||
if (msg == NULL) {
|
||||
IPAERR("fail to alloc ipa_msg container\n");
|
||||
mutex_unlock(&ipa_ctx->msg_wlan_client_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
msg->meta = entry->meta;
|
||||
data = kmalloc(entry->meta.msg_len, GFP_KERNEL);
|
||||
if (data == NULL) {
|
||||
IPAERR("fail to alloc data container\n");
|
||||
kfree(msg);
|
||||
mutex_unlock(&ipa_ctx->msg_wlan_client_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(data, entry->buff, entry->meta.msg_len);
|
||||
msg->buff = data;
|
||||
msg->callback = ipa2_send_msg_free;
|
||||
mutex_lock(&ipa_ctx->msg_lock);
|
||||
list_add_tail(&msg->link, &ipa_ctx->msg_list);
|
||||
mutex_unlock(&ipa_ctx->msg_lock);
|
||||
wake_up(&ipa_ctx->msg_waitq);
|
||||
|
||||
total++;
|
||||
}
|
||||
mutex_unlock(&ipa_ctx->msg_wlan_client_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa2_register_pull_msg() - register pull message type
|
||||
* @meta: [in] message meta-data
|
||||
|
|
|
@ -785,12 +785,6 @@ int ipa2_nat_del_cmd(struct ipa_ioc_v4_nat_del *del)
|
|||
base_addr = ipa_ctx->nat_mem.tmp_dma_handle;
|
||||
}
|
||||
|
||||
if (del->public_ip_addr == 0) {
|
||||
IPADBG("Bad Parameter\n");
|
||||
result = -EPERM;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
/* NO-OP IC for ensuring that IPA pipeline is empty */
|
||||
reg_write_nop = kzalloc(sizeof(*reg_write_nop), flag);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, 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
|
||||
|
@ -514,6 +514,14 @@ int qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req)
|
|||
int rc;
|
||||
int i;
|
||||
|
||||
/* check if modem up */
|
||||
if (!qmi_indication_fin ||
|
||||
!qmi_modem_init_fin ||
|
||||
!ipa_q6_clnt) {
|
||||
IPAWANDBG("modem QMI haven't up yet\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check if the filter rules from IPACM is valid */
|
||||
if (req->filter_spec_list_len == 0) {
|
||||
IPAWANDBG("IPACM pass zero rules to Q6\n");
|
||||
|
|
|
@ -1026,7 +1026,8 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
|
|||
}
|
||||
|
||||
static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
|
||||
const struct ipa_rt_rule *rule, u8 at_rear, u32 *rule_hdl)
|
||||
const struct ipa_rt_rule *rule, u8 at_rear, u32 *rule_hdl,
|
||||
bool user)
|
||||
{
|
||||
struct ipa_rt_tbl *tbl;
|
||||
struct ipa_rt_entry *entry;
|
||||
|
@ -1101,6 +1102,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
|
|||
IPADBG_LOW("rule_cnt=%d\n", tbl->rule_cnt);
|
||||
*rule_hdl = id;
|
||||
entry->id = id;
|
||||
entry->ipacm_installed = user;
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -1125,6 +1127,21 @@ error:
|
|||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa2_add_rt_rule(struct ipa_ioc_add_rt_rule *rules)
|
||||
{
|
||||
return ipa2_add_rt_rule_usr(rules, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa2_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 installed by userspace module
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa2_add_rt_rule_usr(struct ipa_ioc_add_rt_rule *rules, bool user_only)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
@ -1139,7 +1156,8 @@ int ipa2_add_rt_rule(struct ipa_ioc_add_rt_rule *rules)
|
|||
if (__ipa_add_rt_rule(rules->ip, rules->rt_tbl_name,
|
||||
&rules->rules[i].rule,
|
||||
rules->rules[i].at_rear,
|
||||
&rules->rules[i].rt_rule_hdl)) {
|
||||
&rules->rules[i].rt_rule_hdl,
|
||||
user_only)) {
|
||||
IPAERR_RL("failed to add rt rule %d\n", i);
|
||||
rules->rules[i].status = IPA_RT_STATUS_OF_ADD_FAILED;
|
||||
} else {
|
||||
|
@ -1308,13 +1326,14 @@ bail:
|
|||
/**
|
||||
* ipa2_reset_rt() - reset the current SW routing table of specified type
|
||||
* (does not commit to HW)
|
||||
* @ip: 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
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa2_reset_rt(enum ipa_ip_type ip)
|
||||
int ipa2_reset_rt(enum ipa_ip_type ip, bool user_only)
|
||||
{
|
||||
struct ipa_rt_tbl *tbl;
|
||||
struct ipa_rt_tbl *tbl_next;
|
||||
|
@ -1324,6 +1343,7 @@ int ipa2_reset_rt(enum ipa_ip_type ip)
|
|||
struct ipa_rt_tbl_set *rset;
|
||||
u32 apps_start_idx;
|
||||
int id;
|
||||
bool tbl_user = false;
|
||||
|
||||
if (ip >= IPA_IP_MAX) {
|
||||
IPAERR_RL("bad parm\n");
|
||||
|
@ -1343,7 +1363,7 @@ int ipa2_reset_rt(enum ipa_ip_type ip)
|
|||
* issue a reset on the filtering module of same IP type since
|
||||
* filtering rules point to routing tables
|
||||
*/
|
||||
if (ipa2_reset_flt(ip))
|
||||
if (ipa2_reset_flt(ip, user_only))
|
||||
IPAERR_RL("fail to reset flt ip=%d\n", ip);
|
||||
|
||||
set = &ipa_ctx->rt_tbl_set[ip];
|
||||
|
@ -1351,6 +1371,7 @@ int ipa2_reset_rt(enum ipa_ip_type ip)
|
|||
mutex_lock(&ipa_ctx->lock);
|
||||
IPADBG("reset rt ip=%d\n", ip);
|
||||
list_for_each_entry_safe(tbl, tbl_next, &set->head_rt_tbl_list, link) {
|
||||
tbl_user = false;
|
||||
list_for_each_entry_safe(rule, rule_next,
|
||||
&tbl->head_rt_rule_list, link) {
|
||||
if (ipa_id_find(rule->id) == NULL) {
|
||||
|
@ -1359,25 +1380,34 @@ int ipa2_reset_rt(enum ipa_ip_type ip)
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* indicate if tbl used for user-specified rules*/
|
||||
if (rule->ipacm_installed) {
|
||||
IPADBG("tbl_user %d, tbl-index %d\n",
|
||||
tbl_user, tbl->id);
|
||||
tbl_user = true;
|
||||
}
|
||||
/*
|
||||
* for the "default" routing tbl, remove all but the
|
||||
* last rule
|
||||
*/
|
||||
if (tbl->idx == apps_start_idx && tbl->rule_cnt == 1)
|
||||
continue;
|
||||
if (!user_only ||
|
||||
rule->ipacm_installed) {
|
||||
list_del(&rule->link);
|
||||
tbl->rule_cnt--;
|
||||
if (rule->hdr)
|
||||
__ipa_release_hdr(rule->hdr->id);
|
||||
else if (rule->proc_ctx)
|
||||
__ipa_release_hdr_proc_ctx(
|
||||
rule->proc_ctx->id);
|
||||
rule->cookie = 0;
|
||||
id = rule->id;
|
||||
kmem_cache_free(ipa_ctx->rt_rule_cache, rule);
|
||||
|
||||
list_del(&rule->link);
|
||||
tbl->rule_cnt--;
|
||||
if (rule->hdr)
|
||||
__ipa_release_hdr(rule->hdr->id);
|
||||
else if (rule->proc_ctx)
|
||||
__ipa_release_hdr_proc_ctx(rule->proc_ctx->id);
|
||||
rule->cookie = 0;
|
||||
id = rule->id;
|
||||
kmem_cache_free(ipa_ctx->rt_rule_cache, rule);
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(id);
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (ipa_id_find(tbl->id) == NULL) {
|
||||
|
@ -1389,24 +1419,28 @@ int ipa2_reset_rt(enum ipa_ip_type ip)
|
|||
|
||||
/* do not remove the "default" routing tbl which has index 0 */
|
||||
if (tbl->idx != apps_start_idx) {
|
||||
if (!tbl->in_sys) {
|
||||
list_del(&tbl->link);
|
||||
set->tbl_cnt--;
|
||||
clear_bit(tbl->idx,
|
||||
&ipa_ctx->rt_idx_bitmap[ip]);
|
||||
IPADBG("rst rt tbl_idx=%d tbl_cnt=%d\n",
|
||||
tbl->idx, set->tbl_cnt);
|
||||
kmem_cache_free(ipa_ctx->rt_tbl_cache, tbl);
|
||||
} else {
|
||||
list_move(&tbl->link, &rset->head_rt_tbl_list);
|
||||
clear_bit(tbl->idx,
|
||||
&ipa_ctx->rt_idx_bitmap[ip]);
|
||||
set->tbl_cnt--;
|
||||
IPADBG("rst sys rt tbl_idx=%d tbl_cnt=%d\n",
|
||||
tbl->idx, set->tbl_cnt);
|
||||
if (!user_only || tbl_user) {
|
||||
if (!tbl->in_sys) {
|
||||
list_del(&tbl->link);
|
||||
set->tbl_cnt--;
|
||||
clear_bit(tbl->idx,
|
||||
&ipa_ctx->rt_idx_bitmap[ip]);
|
||||
IPADBG("rst rt tbl_idx=%d tbl_cnt=%d\n",
|
||||
tbl->idx, set->tbl_cnt);
|
||||
kmem_cache_free(ipa_ctx->rt_tbl_cache,
|
||||
tbl);
|
||||
} else {
|
||||
list_move(&tbl->link,
|
||||
&rset->head_rt_tbl_list);
|
||||
clear_bit(tbl->idx,
|
||||
&ipa_ctx->rt_idx_bitmap[ip]);
|
||||
set->tbl_cnt--;
|
||||
IPADBG("rst tbl_idx=%d cnt=%d\n",
|
||||
tbl->idx, set->tbl_cnt);
|
||||
}
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(id);
|
||||
}
|
||||
/* remove the handle from the database */
|
||||
ipa_id_remove(id);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ipa_ctx->lock);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, 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
|
||||
|
@ -5078,6 +5078,7 @@ int ipa2_bind_api_controller(enum ipa_hw_type ipa_hw_type,
|
|||
api_ctrl->ipa_cfg_ep_holb_by_client = ipa2_cfg_ep_holb_by_client;
|
||||
api_ctrl->ipa_cfg_ep_ctrl = ipa2_cfg_ep_ctrl;
|
||||
api_ctrl->ipa_add_hdr = ipa2_add_hdr;
|
||||
api_ctrl->ipa_add_hdr_usr = ipa2_add_hdr_usr;
|
||||
api_ctrl->ipa_del_hdr = ipa2_del_hdr;
|
||||
api_ctrl->ipa_commit_hdr = ipa2_commit_hdr;
|
||||
api_ctrl->ipa_reset_hdr = ipa2_reset_hdr;
|
||||
|
@ -5087,6 +5088,7 @@ int ipa2_bind_api_controller(enum ipa_hw_type ipa_hw_type,
|
|||
api_ctrl->ipa_add_hdr_proc_ctx = ipa2_add_hdr_proc_ctx;
|
||||
api_ctrl->ipa_del_hdr_proc_ctx = ipa2_del_hdr_proc_ctx;
|
||||
api_ctrl->ipa_add_rt_rule = ipa2_add_rt_rule;
|
||||
api_ctrl->ipa_add_rt_rule_usr = ipa2_add_rt_rule_usr;
|
||||
api_ctrl->ipa_del_rt_rule = ipa2_del_rt_rule;
|
||||
api_ctrl->ipa_commit_rt = ipa2_commit_rt;
|
||||
api_ctrl->ipa_reset_rt = ipa2_reset_rt;
|
||||
|
@ -5095,6 +5097,7 @@ int ipa2_bind_api_controller(enum ipa_hw_type ipa_hw_type,
|
|||
api_ctrl->ipa_query_rt_index = ipa2_query_rt_index;
|
||||
api_ctrl->ipa_mdfy_rt_rule = ipa2_mdfy_rt_rule;
|
||||
api_ctrl->ipa_add_flt_rule = ipa2_add_flt_rule;
|
||||
api_ctrl->ipa_add_flt_rule_usr = ipa2_add_flt_rule_usr;
|
||||
api_ctrl->ipa_del_flt_rule = ipa2_del_flt_rule;
|
||||
api_ctrl->ipa_mdfy_flt_rule = ipa2_mdfy_flt_rule;
|
||||
api_ctrl->ipa_commit_flt = ipa2_commit_flt;
|
||||
|
|
|
@ -345,6 +345,43 @@ int ipa3_active_clients_log_print_table(char *buf, int size)
|
|||
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,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
|
@ -598,7 +635,8 @@ static void ipa3_wan_msg_free_cb(void *buff, u32 len, u32 type)
|
|||
kfree(buff);
|
||||
}
|
||||
|
||||
static int ipa3_send_wan_msg(unsigned long usr_param, uint8_t msg_type, bool is_cache)
|
||||
static int ipa3_send_wan_msg(unsigned long usr_param, uint8_t msg_type,
|
||||
bool is_cache)
|
||||
{
|
||||
int retval;
|
||||
struct ipa_wan_msg *wan_msg;
|
||||
|
@ -906,7 +944,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
retval = -EFAULT;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -986,7 +1025,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
retval = -EFAULT;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -1191,7 +1231,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
retval = -EFAULT;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -1328,19 +1369,19 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
retval = ipa3_commit_hdr();
|
||||
break;
|
||||
case IPA_IOC_RESET_HDR:
|
||||
retval = ipa3_reset_hdr();
|
||||
retval = ipa3_reset_hdr(false);
|
||||
break;
|
||||
case IPA_IOC_COMMIT_RT:
|
||||
retval = ipa3_commit_rt(arg);
|
||||
break;
|
||||
case IPA_IOC_RESET_RT:
|
||||
retval = ipa3_reset_rt(arg);
|
||||
retval = ipa3_reset_rt(arg, false);
|
||||
break;
|
||||
case IPA_IOC_COMMIT_FLT:
|
||||
retval = ipa3_commit_flt(arg);
|
||||
break;
|
||||
case IPA_IOC_RESET_FLT:
|
||||
retval = ipa3_reset_flt(arg);
|
||||
retval = ipa3_reset_flt(arg, false);
|
||||
break;
|
||||
case IPA_IOC_GET_RT_TBL:
|
||||
if (copy_from_user(header, (u8 *)arg,
|
||||
|
@ -1720,7 +1761,7 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
break;
|
||||
}
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -1812,7 +1853,22 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
}
|
||||
break;
|
||||
|
||||
default: /* redundant, as cmd was checked against MAXNR */
|
||||
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:
|
||||
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
@ -1823,13 +1879,13 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_setup_dflt_rt_tables() - Setup default routing tables
|
||||
*
|
||||
* Return codes:
|
||||
* 0: success
|
||||
* -ENOMEM: failed to allocate memory
|
||||
* -EPERM: failed to add the tables
|
||||
*/
|
||||
* ipa3_setup_dflt_rt_tables() - Setup default routing tables
|
||||
*
|
||||
* Return codes:
|
||||
* 0: success
|
||||
* -ENOMEM: failed to allocate memory
|
||||
* -EPERM: failed to add the tables
|
||||
*/
|
||||
int ipa3_setup_dflt_rt_tables(void)
|
||||
{
|
||||
struct ipa_ioc_add_rt_rule *rt_rule;
|
||||
|
@ -2010,14 +2066,14 @@ static int ipa3_init_smem_region(int memory_region_size,
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_init_q6_smem() - Initialize Q6 general memory and
|
||||
* header memory regions in IPA.
|
||||
*
|
||||
* Return codes:
|
||||
* 0: success
|
||||
* -ENOMEM: failed to allocate dma memory
|
||||
* -EFAULT: failed to send IPA command to initialize the memory
|
||||
*/
|
||||
* ipa3_init_q6_smem() - Initialize Q6 general memory and
|
||||
* header memory regions in IPA.
|
||||
*
|
||||
* Return codes:
|
||||
* 0: success
|
||||
* -ENOMEM: failed to allocate dma memory
|
||||
* -EFAULT: failed to send IPA command to initialize the memory
|
||||
*/
|
||||
int ipa3_init_q6_smem(void)
|
||||
{
|
||||
int rc;
|
||||
|
@ -2546,12 +2602,12 @@ static int ipa3_q6_set_ex_path_to_apps(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_q6_pre_shutdown_cleanup() - A cleanup for all Q6 related configuration
|
||||
* in IPA HW. This is performed in case of SSR.
|
||||
*
|
||||
* This is a mandatory procedure, in case one of the steps fails, the
|
||||
* AP needs to restart.
|
||||
*/
|
||||
* ipa3_q6_pre_shutdown_cleanup() - A cleanup for all Q6 related configuration
|
||||
* in IPA HW. This is performed in case of SSR.
|
||||
*
|
||||
* This is a mandatory procedure, in case one of the steps fails, the
|
||||
* AP needs to restart.
|
||||
*/
|
||||
void ipa3_q6_pre_shutdown_cleanup(void)
|
||||
{
|
||||
IPADBG_LOW("ENTER\n");
|
||||
|
@ -2569,8 +2625,8 @@ void ipa3_q6_pre_shutdown_cleanup(void)
|
|||
BUG();
|
||||
}
|
||||
/* Remove delay from Q6 PRODs to avoid pending descriptors
|
||||
* on pipe reset procedure
|
||||
*/
|
||||
* on pipe reset procedure
|
||||
*/
|
||||
ipa3_q6_pipe_delay(false);
|
||||
|
||||
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
|
||||
|
@ -3465,11 +3521,11 @@ static unsigned int ipa3_get_bus_vote(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_enable_clks() - Turn on IPA clocks
|
||||
*
|
||||
* Return codes:
|
||||
* None
|
||||
*/
|
||||
* ipa3_enable_clks() - Turn on IPA clocks
|
||||
*
|
||||
* Return codes:
|
||||
* None
|
||||
*/
|
||||
void ipa3_enable_clks(void)
|
||||
{
|
||||
IPADBG("enabling IPA clocks and bus voting\n");
|
||||
|
@ -3498,11 +3554,11 @@ void _ipa_disable_clks_v3_0(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_disable_clks() - Turn off IPA clocks
|
||||
*
|
||||
* Return codes:
|
||||
* None
|
||||
*/
|
||||
* ipa3_disable_clks() - Turn off IPA clocks
|
||||
*
|
||||
* Return codes:
|
||||
* None
|
||||
*/
|
||||
void ipa3_disable_clks(void)
|
||||
{
|
||||
IPADBG("disabling IPA clocks and bus voting\n");
|
||||
|
@ -3541,28 +3597,28 @@ static void ipa3_start_tag_process(struct work_struct *work)
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_active_clients_log_mod() - Log a modification in the active clients
|
||||
* reference count
|
||||
*
|
||||
* This method logs any modification in the active clients reference count:
|
||||
* It logs the modification in the circular history buffer
|
||||
* It logs the modification in the hash table - looking for an entry,
|
||||
* creating one if needed and deleting one if needed.
|
||||
*
|
||||
* @id: ipa3_active client logging info struct to hold the log information
|
||||
* @inc: a boolean variable to indicate whether the modification is an increase
|
||||
* or decrease
|
||||
* @int_ctx: a boolean variable to indicate whether this call is being made from
|
||||
* an interrupt context and therefore should allocate GFP_ATOMIC memory
|
||||
*
|
||||
* Method process:
|
||||
* - Hash the unique identifier string
|
||||
* - Find the hash in the table
|
||||
* 1)If found, increase or decrease the reference count
|
||||
* 2)If not found, allocate a new hash table entry struct and initialize it
|
||||
* - Remove and deallocate unneeded data structure
|
||||
* - Log the call in the circular history buffer (unless it is a simple call)
|
||||
*/
|
||||
* ipa3_active_clients_log_mod() - Log a modification in the active clients
|
||||
* reference count
|
||||
*
|
||||
* This method logs any modification in the active clients reference count:
|
||||
* It logs the modification in the circular history buffer
|
||||
* It logs the modification in the hash table - looking for an entry,
|
||||
* creating one if needed and deleting one if needed.
|
||||
*
|
||||
* @id: ipa3_active client logging info struct to hold the log information
|
||||
* @inc: a boolean variable to indicate whether the modification is an increase
|
||||
* or decrease
|
||||
* @int_ctx: a boolean variable to indicate whether this call is being made from
|
||||
* an interrupt context and therefore should allocate GFP_ATOMIC memory
|
||||
*
|
||||
* Method process:
|
||||
* - Hash the unique identifier string
|
||||
* - Find the hash in the table
|
||||
* 1)If found, increase or decrease the reference count
|
||||
* 2)If not found, allocate a new hash table entry struct and initialize it
|
||||
* - Remove and deallocate unneeded data structure
|
||||
* - Log the call in the circular history buffer (unless it is a simple call)
|
||||
*/
|
||||
void ipa3_active_clients_log_mod(struct ipa_active_client_logging_info *id,
|
||||
bool inc, bool int_ctx)
|
||||
{
|
||||
|
@ -3632,12 +3688,12 @@ void ipa3_active_clients_log_inc(struct ipa_active_client_logging_info *id,
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_inc_client_enable_clks() - Increase active clients counter, and
|
||||
* enable ipa clocks if necessary
|
||||
*
|
||||
* Return codes:
|
||||
* None
|
||||
*/
|
||||
* ipa3_inc_client_enable_clks() - Increase active clients counter, and
|
||||
* enable ipa clocks if necessary
|
||||
*
|
||||
* Return codes:
|
||||
* None
|
||||
*/
|
||||
void ipa3_inc_client_enable_clks(struct ipa_active_client_logging_info *id)
|
||||
{
|
||||
ipa3_active_clients_lock();
|
||||
|
@ -3650,13 +3706,13 @@ void ipa3_inc_client_enable_clks(struct ipa_active_client_logging_info *id)
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_inc_client_enable_clks_no_block() - Only increment the number of active
|
||||
* clients if no asynchronous actions should be done. Asynchronous actions are
|
||||
* locking a mutex and waking up IPA HW.
|
||||
*
|
||||
* Return codes: 0 for success
|
||||
* -EPERM if an asynchronous action should have been done
|
||||
*/
|
||||
* ipa3_inc_client_enable_clks_no_block() - Only increment the number of active
|
||||
* clients if no asynchronous actions should be done. Asynchronous actions are
|
||||
* locking a mutex and waking up IPA HW.
|
||||
*
|
||||
* Return codes: 0 for success
|
||||
* -EPERM if an asynchronous action should have been done
|
||||
*/
|
||||
int ipa3_inc_client_enable_clks_no_block(struct ipa_active_client_logging_info
|
||||
*id)
|
||||
{
|
||||
|
@ -3718,12 +3774,12 @@ void ipa3_dec_client_disable_clks(struct ipa_active_client_logging_info *id)
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_inc_acquire_wakelock() - Increase active clients counter, and
|
||||
* acquire wakelock if necessary
|
||||
*
|
||||
* Return codes:
|
||||
* None
|
||||
*/
|
||||
* ipa3_inc_acquire_wakelock() - Increase active clients counter, and
|
||||
* acquire wakelock if necessary
|
||||
*
|
||||
* Return codes:
|
||||
* None
|
||||
*/
|
||||
void ipa3_inc_acquire_wakelock(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -3835,12 +3891,12 @@ static void ipa3_sps_process_irq_schedule_rel(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_suspend_handler() - Handles the suspend interrupt:
|
||||
* wakes up the suspended peripheral by requesting its consumer
|
||||
* @interrupt: Interrupt type
|
||||
* @private_data: The client's private data
|
||||
* @interrupt_data: Interrupt specific information data
|
||||
*/
|
||||
* ipa3_suspend_handler() - Handles the suspend interrupt:
|
||||
* wakes up the suspended peripheral by requesting its consumer
|
||||
* @interrupt: Interrupt type
|
||||
* @private_data: The client's private data
|
||||
* @interrupt_data: Interrupt specific information data
|
||||
*/
|
||||
void ipa3_suspend_handler(enum ipa_irq_type interrupt,
|
||||
void *private_data,
|
||||
void *interrupt_data)
|
||||
|
@ -3903,12 +3959,12 @@ void ipa3_suspend_handler(enum ipa_irq_type interrupt,
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_restore_suspend_handler() - restores the original suspend IRQ handler
|
||||
* as it was registered in the IPA init sequence.
|
||||
* Return codes:
|
||||
* 0: success
|
||||
* -EPERM: failed to remove current handler or failed to add original handler
|
||||
* */
|
||||
* ipa3_restore_suspend_handler() - restores the original suspend IRQ handler
|
||||
* as it was registered in the IPA init sequence.
|
||||
* Return codes:
|
||||
* 0: success
|
||||
* -EPERM: failed to remove current handler or failed to add original handler
|
||||
*/
|
||||
int ipa3_restore_suspend_handler(void)
|
||||
{
|
||||
int result = 0;
|
||||
|
@ -4497,39 +4553,37 @@ static int ipa3_tz_unlock_reg(struct ipa3_context *ipa3_ctx)
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_pre_init() - Initialize the IPA Driver.
|
||||
* This part contains all initialization which doesn't require IPA HW, such
|
||||
* as structure allocations and initializations, register writes, etc.
|
||||
*
|
||||
* @resource_p: contain platform specific values from DST file
|
||||
* @pdev: The platform device structure representing the IPA driver
|
||||
*
|
||||
* Function initialization process:
|
||||
* - Allocate memory for the driver context data struct
|
||||
* - Initializing the ipa3_ctx with:
|
||||
* 1)parsed values from the dts file
|
||||
* 2)parameters passed to the module initialization
|
||||
* 3)read HW values(such as core memory size)
|
||||
* - Map IPA core registers to CPU memory
|
||||
* - Restart IPA core(HW reset)
|
||||
* - Set configuration for IPA BAM via BAM_CNFG_BITS
|
||||
* - Initialize the look-aside caches(kmem_cache/slab) for filter,
|
||||
* routing and IPA-tree
|
||||
* - Create memory pool with 4 objects for DMA operations(each object
|
||||
* is 512Bytes long), this object will be use for tx(A5->IPA)
|
||||
* - Initialize lists head(routing,filter,hdr,system pipes)
|
||||
* - Initialize mutexes (for ipa_ctx and NAT memory mutexes)
|
||||
* - Initialize spinlocks (for list related to A5<->IPA pipes)
|
||||
* - Initialize 2 single-threaded work-queue named "ipa rx wq" and "ipa tx wq"
|
||||
* - Initialize Red-Black-Tree(s) for handles of header,routing rule,
|
||||
* routing table ,filtering rule
|
||||
* - Initialize the filter block by committing IPV4 and IPV6 default rules
|
||||
* - Create empty routing table in system memory(no committing)
|
||||
* - Initialize pipes memory pool with ipa3_pipe_mem_init for supported platforms
|
||||
* - Create a char-device for IPA
|
||||
* - Initialize IPA RM (resource manager)
|
||||
* - Configure GSI registers (in GSI case)
|
||||
*/
|
||||
* ipa3_pre_init() - Initialize the IPA Driver.
|
||||
* This part contains all initialization which doesn't require IPA HW, such
|
||||
* as structure allocations and initializations, register writes, etc.
|
||||
*
|
||||
* @resource_p: contain platform specific values from DST file
|
||||
* @pdev: The platform device structure representing the IPA driver
|
||||
*
|
||||
* Function initialization process:
|
||||
* Allocate memory for the driver context data struct
|
||||
* Initializing the ipa3_ctx with :
|
||||
* 1)parsed values from the dts file
|
||||
* 2)parameters passed to the module initialization
|
||||
* 3)read HW values(such as core memory size)
|
||||
* Map IPA core registers to CPU memory
|
||||
* Restart IPA core(HW reset)
|
||||
* Initialize the look-aside caches(kmem_cache/slab) for filter,
|
||||
* routing and IPA-tree
|
||||
* Create memory pool with 4 objects for DMA operations(each object
|
||||
* is 512Bytes long), this object will be use for tx(A5->IPA)
|
||||
* Initialize lists head(routing, hdr, system pipes)
|
||||
* Initialize mutexes (for ipa_ctx and NAT memory mutexes)
|
||||
* Initialize spinlocks (for list related to A5<->IPA pipes)
|
||||
* Initialize 2 single-threaded work-queue named "ipa rx wq" and "ipa tx wq"
|
||||
* Initialize Red-Black-Tree(s) for handles of header,routing rule,
|
||||
* routing table ,filtering rule
|
||||
* Initialize the filter block by committing IPV4 and IPV6 default rules
|
||||
* Create empty routing table in system memory(no committing)
|
||||
* Create a char-device for IPA
|
||||
* Initialize IPA RM (resource manager)
|
||||
* Configure GSI registers (in GSI case)
|
||||
*/
|
||||
static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
|
||||
struct device *ipa_dev)
|
||||
{
|
||||
|
@ -4887,6 +4941,10 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
|
|||
init_waitqueue_head(&ipa3_ctx->msg_waitq);
|
||||
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->nat_mem.lock);
|
||||
mutex_init(&ipa3_ctx->q6_proxy_clk_vote_mutex);
|
||||
|
@ -5873,7 +5931,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p,
|
|||
*
|
||||
* Returns -EAGAIN to runtime_pm framework in case IPA is in use by AP.
|
||||
* This will postpone the suspend operation until IPA is no longer used by AP.
|
||||
*/
|
||||
*/
|
||||
int ipa3_ap_suspend(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
@ -5899,14 +5957,14 @@ int ipa3_ap_suspend(struct device *dev)
|
|||
}
|
||||
|
||||
/**
|
||||
* ipa3_ap_resume() - resume callback for runtime_pm
|
||||
* @dev: pointer to device
|
||||
*
|
||||
* This callback will be invoked by the runtime_pm framework when an AP resume
|
||||
* operation is invoked.
|
||||
*
|
||||
* Always returns 0 since resume should always succeed.
|
||||
*/
|
||||
* ipa3_ap_resume() - resume callback for runtime_pm
|
||||
* @dev: pointer to device
|
||||
*
|
||||
* This callback will be invoked by the runtime_pm framework when an AP resume
|
||||
* operation is invoked.
|
||||
*
|
||||
* Always returns 0 since resume should always succeed.
|
||||
*/
|
||||
int ipa3_ap_resume(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -784,7 +784,7 @@ error:
|
|||
|
||||
static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry,
|
||||
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;
|
||||
|
||||
|
@ -809,6 +809,7 @@ static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry,
|
|||
}
|
||||
}
|
||||
(*entry)->rule_id = id;
|
||||
(*entry)->ipacm_installed = user;
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -846,7 +847,7 @@ ipa_insert_failed:
|
|||
|
||||
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,
|
||||
u32 *rule_hdl)
|
||||
u32 *rule_hdl, bool user)
|
||||
{
|
||||
struct ipa3_flt_entry *entry;
|
||||
struct ipa3_rt_tbl *rt_tbl = NULL;
|
||||
|
@ -854,7 +855,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))
|
||||
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;
|
||||
|
||||
if (add_rear) {
|
||||
|
@ -904,7 +905,7 @@ static int __ipa_add_flt_rule_after(struct ipa3_flt_tbl *tbl,
|
|||
if (__ipa_validate_flt_rule(rule, &rt_tbl, ip))
|
||||
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;
|
||||
|
||||
list_add(&entry->link, &((*add_after_entry)->link));
|
||||
|
@ -1054,7 +1055,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,
|
||||
const struct ipa_flt_rule *rule, u8 add_rear,
|
||||
u32 *rule_hdl)
|
||||
u32 *rule_hdl, bool user)
|
||||
{
|
||||
struct ipa3_flt_tbl *tbl;
|
||||
int ipa_ep_idx;
|
||||
|
@ -1072,18 +1073,33 @@ 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];
|
||||
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
|
||||
* commit to IPA HW
|
||||
* @rules: [inout] set of filtering rules to add
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
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 result;
|
||||
|
@ -1100,7 +1116,8 @@ int ipa3_add_flt_rule(struct ipa_ioc_add_flt_rule *rules)
|
|||
result = __ipa_add_ep_flt_rule(rules->ip, rules->ep,
|
||||
&rules->rules[i].rule,
|
||||
rules->rules[i].at_rear,
|
||||
&rules->rules[i].flt_rule_hdl);
|
||||
&rules->rules[i].flt_rule_hdl,
|
||||
user_only);
|
||||
else
|
||||
result = -1;
|
||||
|
||||
|
@ -1347,18 +1364,20 @@ bail:
|
|||
* ipa3_reset_flt() - Reset the current SW filtering table of specified type
|
||||
* (does not commit to HW)
|
||||
* @ip: [in] the family of routing tables
|
||||
* @user_only: [in] indicate rules deleted by userspace
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* 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_entry *entry;
|
||||
struct ipa3_flt_entry *next;
|
||||
int i;
|
||||
int id;
|
||||
int rule_id;
|
||||
|
||||
if (ip >= IPA_IP_MAX) {
|
||||
IPAERR_RL("bad parm\n");
|
||||
|
@ -1378,21 +1397,27 @@ int ipa3_reset_flt(enum ipa_ip_type ip)
|
|||
mutex_unlock(&ipa3_ctx->lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
list_del(&entry->link);
|
||||
entry->tbl->rule_cnt--;
|
||||
if (entry->rt_tbl)
|
||||
entry->rt_tbl->ref_cnt--;
|
||||
/* if rule id was allocated from idr, remove it */
|
||||
if ((entry->rule_id < ipahal_get_rule_id_hi_bit()) &&
|
||||
(entry->rule_id >= ipahal_get_low_rule_id()))
|
||||
idr_remove(&entry->tbl->rule_ids,
|
||||
entry->rule_id);
|
||||
entry->cookie = 0;
|
||||
id = entry->id;
|
||||
kmem_cache_free(ipa3_ctx->flt_rule_cache, entry);
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa3_id_remove(id);
|
||||
if (!user_only ||
|
||||
entry->ipacm_installed) {
|
||||
list_del(&entry->link);
|
||||
entry->tbl->rule_cnt--;
|
||||
if (entry->rt_tbl)
|
||||
entry->rt_tbl->ref_cnt--;
|
||||
/* if rule id was allocated from idr, remove */
|
||||
rule_id = entry->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,
|
||||
rule_id);
|
||||
entry->cookie = 0;
|
||||
kmem_cache_free(ipa3_ctx->flt_rule_cache,
|
||||
entry);
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa3_id_remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ipa3_ctx->lock);
|
||||
|
@ -1418,14 +1443,14 @@ void ipa3_install_dflt_flt_rules(u32 ipa_ep_idx)
|
|||
tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v4];
|
||||
rule.action = IPA_PASS_TO_EXCEPTION;
|
||||
__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);
|
||||
tbl->sticky_rear = true;
|
||||
|
||||
tbl = &ipa3_ctx->flt_tbl[ipa_ep_idx][IPA_IP_v6];
|
||||
rule.action = IPA_PASS_TO_EXCEPTION;
|
||||
__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);
|
||||
tbl->sticky_rear = true;
|
||||
mutex_unlock(&ipa3_ctx->lock);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, 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
|
||||
|
@ -315,7 +315,7 @@ end:
|
|||
}
|
||||
|
||||
static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
||||
bool add_ref_hdr)
|
||||
bool add_ref_hdr, bool user_only)
|
||||
{
|
||||
struct ipa3_hdr_entry *hdr_entry;
|
||||
struct ipa3_hdr_proc_ctx_entry *entry;
|
||||
|
@ -360,6 +360,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
if (add_ref_hdr)
|
||||
hdr_entry->ref_cnt++;
|
||||
entry->cookie = IPA_PROC_HDR_COOKIE;
|
||||
entry->ipacm_installed = user_only;
|
||||
|
||||
needed_len = ipahal_get_proc_ctx_needed_len(proc_ctx->type);
|
||||
|
||||
|
@ -396,6 +397,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
*/
|
||||
offset->offset = htbl->end;
|
||||
offset->bin = bin;
|
||||
offset->ipacm_installed = user_only;
|
||||
htbl->end += ipa_hdr_proc_ctx_bin_sz[bin];
|
||||
list_add(&offset->link,
|
||||
&htbl->head_offset_list[bin]);
|
||||
|
@ -404,6 +406,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
offset =
|
||||
list_first_entry(&htbl->head_free_offset_list[bin],
|
||||
struct ipa3_hdr_proc_ctx_offset_entry, link);
|
||||
offset->ipacm_installed = user_only;
|
||||
list_move(&offset->link, &htbl->head_offset_list[bin]);
|
||||
}
|
||||
|
||||
|
@ -441,7 +444,7 @@ bad_len:
|
|||
}
|
||||
|
||||
|
||||
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
||||
static int __ipa_add_hdr(struct ipa_hdr_add *hdr, bool user)
|
||||
{
|
||||
struct ipa3_hdr_entry *entry;
|
||||
struct ipa_hdr_offset_entry *offset = NULL;
|
||||
|
@ -476,6 +479,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
|
||||
entry->eth2_ofst = hdr->eth2_ofst;
|
||||
entry->cookie = IPA_HDR_COOKIE;
|
||||
entry->ipacm_installed = user;
|
||||
|
||||
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
|
||||
bin = IPA_HDR_BIN0;
|
||||
|
@ -527,6 +531,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
list_add(&offset->link,
|
||||
&htbl->head_offset_list[bin]);
|
||||
entry->offset_entry = offset;
|
||||
offset->ipacm_installed = user;
|
||||
}
|
||||
} else {
|
||||
entry->is_hdr_proc_ctx = false;
|
||||
|
@ -535,6 +540,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
struct ipa_hdr_offset_entry, link);
|
||||
list_move(&offset->link, &htbl->head_offset_list[bin]);
|
||||
entry->offset_entry = offset;
|
||||
offset->ipacm_installed = user;
|
||||
}
|
||||
|
||||
list_add(&entry->link, &htbl->head_hdr_entry_list);
|
||||
|
@ -566,7 +572,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
IPADBG("adding processing context for header %s\n", hdr->name);
|
||||
proc_ctx.type = IPA_HDR_PROC_NONE;
|
||||
proc_ctx.hdr_hdl = id;
|
||||
if (__ipa_add_hdr_proc_ctx(&proc_ctx, false)) {
|
||||
if (__ipa_add_hdr_proc_ctx(&proc_ctx, false, user)) {
|
||||
IPAERR("failed to add hdr proc ctx\n");
|
||||
goto fail_add_proc_ctx;
|
||||
}
|
||||
|
@ -727,6 +733,21 @@ int __ipa3_del_hdr(u32 hdr_hdl, bool by_user)
|
|||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa3_add_hdr(struct ipa_ioc_add_hdr *hdrs)
|
||||
{
|
||||
return ipa3_add_hdr_usr(hdrs, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa3_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 installed from user
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa3_add_hdr_usr(struct ipa_ioc_add_hdr *hdrs, bool user_only)
|
||||
{
|
||||
int i;
|
||||
int result = -EFAULT;
|
||||
|
@ -740,7 +761,7 @@ int ipa3_add_hdr(struct ipa_ioc_add_hdr *hdrs)
|
|||
IPADBG("adding %d headers to IPA driver internal data struct\n",
|
||||
hdrs->num_hdrs);
|
||||
for (i = 0; i < hdrs->num_hdrs; i++) {
|
||||
if (__ipa_add_hdr(&hdrs->hdr[i])) {
|
||||
if (__ipa_add_hdr(&hdrs->hdr[i], user_only)) {
|
||||
IPAERR_RL("failed to add hdr %d\n", i);
|
||||
hdrs->hdr[i].status = -1;
|
||||
} else {
|
||||
|
@ -821,12 +842,14 @@ int ipa3_del_hdr(struct ipa_ioc_del_hdr *hdls)
|
|||
* ipa3_add_hdr_proc_ctx() - add the specified headers to SW
|
||||
* and optionally commit them to IPA HW
|
||||
* @proc_ctxs: [inout] set of processing context headers to add
|
||||
* @user_only: [in] indicate installed by user-space module
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa3_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs)
|
||||
int ipa3_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs,
|
||||
bool user_only)
|
||||
{
|
||||
int i;
|
||||
int result = -EFAULT;
|
||||
|
@ -840,7 +863,8 @@ int ipa3_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs)
|
|||
IPADBG("adding %d header processing contextes to IPA driver\n",
|
||||
proc_ctxs->num_proc_ctxs);
|
||||
for (i = 0; i < proc_ctxs->num_proc_ctxs; i++) {
|
||||
if (__ipa_add_hdr_proc_ctx(&proc_ctxs->proc_ctx[i], true)) {
|
||||
if (__ipa_add_hdr_proc_ctx(&proc_ctxs->proc_ctx[i],
|
||||
true, user_only)) {
|
||||
IPAERR_RL("failed to add hdr pric ctx %d\n", i);
|
||||
proc_ctxs->proc_ctx[i].status = -1;
|
||||
} else {
|
||||
|
@ -955,11 +979,12 @@ bail:
|
|||
* ipa3_reset_hdr() - reset the current header table in SW (does not commit to
|
||||
* HW)
|
||||
*
|
||||
* @user_only: [in] indicate delete rules installed by userspace
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa3_reset_hdr(void)
|
||||
int ipa3_reset_hdr(bool user_only)
|
||||
{
|
||||
struct ipa3_hdr_entry *entry;
|
||||
struct ipa3_hdr_entry *next;
|
||||
|
@ -975,9 +1000,9 @@ int ipa3_reset_hdr(void)
|
|||
* issue a reset on the routing module since routing rules point to
|
||||
* header table entries
|
||||
*/
|
||||
if (ipa3_reset_rt(IPA_IP_v4))
|
||||
if (ipa3_reset_rt(IPA_IP_v4, user_only))
|
||||
IPAERR("fail to reset v4 rt\n");
|
||||
if (ipa3_reset_rt(IPA_IP_v6))
|
||||
if (ipa3_reset_rt(IPA_IP_v6, user_only))
|
||||
IPAERR("fail to reset v4 rt\n");
|
||||
|
||||
mutex_lock(&ipa3_ctx->lock);
|
||||
|
@ -1006,21 +1031,23 @@ int ipa3_reset_hdr(void)
|
|||
WARN_ON(1);
|
||||
return -EFAULT;
|
||||
}
|
||||
if (entry->is_hdr_proc_ctx) {
|
||||
dma_unmap_single(ipa3_ctx->pdev,
|
||||
entry->phys_base,
|
||||
entry->hdr_len,
|
||||
DMA_TO_DEVICE);
|
||||
entry->proc_ctx = NULL;
|
||||
|
||||
if (!user_only || entry->ipacm_installed) {
|
||||
if (entry->is_hdr_proc_ctx) {
|
||||
dma_unmap_single(ipa3_ctx->pdev,
|
||||
entry->phys_base,
|
||||
entry->hdr_len,
|
||||
DMA_TO_DEVICE);
|
||||
entry->proc_ctx = NULL;
|
||||
}
|
||||
list_del(&entry->link);
|
||||
entry->ref_cnt = 0;
|
||||
entry->cookie = 0;
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa3_id_remove(entry->id);
|
||||
kmem_cache_free(ipa3_ctx->hdr_cache, entry);
|
||||
}
|
||||
list_del(&entry->link);
|
||||
entry->ref_cnt = 0;
|
||||
entry->cookie = 0;
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa3_id_remove(entry->id);
|
||||
kmem_cache_free(ipa3_ctx->hdr_cache, entry);
|
||||
|
||||
}
|
||||
for (i = 0; i < IPA_HDR_BIN_MAX; i++) {
|
||||
list_for_each_entry_safe(off_entry, off_next,
|
||||
|
@ -1034,14 +1061,23 @@ int ipa3_reset_hdr(void)
|
|||
if (off_entry->offset == 0)
|
||||
continue;
|
||||
|
||||
list_del(&off_entry->link);
|
||||
kmem_cache_free(ipa3_ctx->hdr_offset_cache, off_entry);
|
||||
if (!user_only ||
|
||||
off_entry->ipacm_installed) {
|
||||
list_del(&off_entry->link);
|
||||
kmem_cache_free(ipa3_ctx->hdr_offset_cache,
|
||||
off_entry);
|
||||
}
|
||||
}
|
||||
list_for_each_entry_safe(off_entry, off_next,
|
||||
&ipa3_ctx->hdr_tbl.head_free_offset_list[i],
|
||||
link) {
|
||||
list_del(&off_entry->link);
|
||||
kmem_cache_free(ipa3_ctx->hdr_offset_cache, off_entry);
|
||||
|
||||
if (!user_only ||
|
||||
off_entry->ipacm_installed) {
|
||||
list_del(&off_entry->link);
|
||||
kmem_cache_free(ipa3_ctx->hdr_offset_cache,
|
||||
off_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* there is one header of size 8 */
|
||||
|
@ -1060,30 +1096,43 @@ int ipa3_reset_hdr(void)
|
|||
WARN_ON(1);
|
||||
return -EFAULT;
|
||||
}
|
||||
list_del(&ctx_entry->link);
|
||||
ctx_entry->ref_cnt = 0;
|
||||
ctx_entry->cookie = 0;
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa3_id_remove(ctx_entry->id);
|
||||
kmem_cache_free(ipa3_ctx->hdr_proc_ctx_cache, ctx_entry);
|
||||
if (!user_only ||
|
||||
ctx_entry->ipacm_installed) {
|
||||
list_del(&ctx_entry->link);
|
||||
ctx_entry->ref_cnt = 0;
|
||||
ctx_entry->cookie = 0;
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa3_id_remove(ctx_entry->id);
|
||||
kmem_cache_free(ipa3_ctx->hdr_proc_ctx_cache,
|
||||
ctx_entry);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < IPA_HDR_PROC_CTX_BIN_MAX; i++) {
|
||||
list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
|
||||
&ipa3_ctx->hdr_proc_ctx_tbl.head_offset_list[i],
|
||||
link) {
|
||||
|
||||
list_del(&ctx_off_entry->link);
|
||||
kmem_cache_free(ipa3_ctx->hdr_proc_ctx_offset_cache,
|
||||
if (!user_only ||
|
||||
ctx_off_entry->ipacm_installed) {
|
||||
list_del(&ctx_off_entry->link);
|
||||
kmem_cache_free(
|
||||
ipa3_ctx->hdr_proc_ctx_offset_cache,
|
||||
ctx_off_entry);
|
||||
}
|
||||
}
|
||||
list_for_each_entry_safe(ctx_off_entry, ctx_off_next,
|
||||
&ipa3_ctx->hdr_proc_ctx_tbl.head_free_offset_list[i],
|
||||
link) {
|
||||
list_del(&ctx_off_entry->link);
|
||||
kmem_cache_free(ipa3_ctx->hdr_proc_ctx_offset_cache,
|
||||
ctx_off_entry);
|
||||
|
||||
if (!user_only ||
|
||||
ctx_off_entry->ipacm_installed) {
|
||||
list_del(&ctx_off_entry->link);
|
||||
kmem_cache_free(
|
||||
ipa3_ctx->hdr_proc_ctx_offset_cache,
|
||||
ctx_off_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
ipa3_ctx->hdr_proc_ctx_tbl.end = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, 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
|
||||
|
@ -233,6 +233,7 @@ struct ipa_smmu_cb_ctx {
|
|||
* @prio: rule 10bit priority which defines the order of the rule
|
||||
* among other rules at the same integrated table
|
||||
* @rule_id: rule 10bit ID to be returned in packet status
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa3_flt_entry {
|
||||
struct list_head link;
|
||||
|
@ -244,6 +245,7 @@ struct ipa3_flt_entry {
|
|||
int id;
|
||||
u16 prio;
|
||||
u16 rule_id;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -300,6 +302,7 @@ struct ipa3_rt_tbl {
|
|||
* @is_eth2_ofst_valid: is eth2_ofst field valid?
|
||||
* @eth2_ofst: offset to start of Ethernet-II/802.3 header
|
||||
* @user_deleted: is the header deleted by the user?
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa3_hdr_entry {
|
||||
struct list_head link;
|
||||
|
@ -318,6 +321,7 @@ struct ipa3_hdr_entry {
|
|||
u8 is_eth2_ofst_valid;
|
||||
u16 eth2_ofst;
|
||||
bool user_deleted;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -341,11 +345,13 @@ struct ipa3_hdr_tbl {
|
|||
* @link: entry's link in global processing context header offset entries list
|
||||
* @offset: the offset
|
||||
* @bin: bin
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa3_hdr_proc_ctx_offset_entry {
|
||||
struct list_head link;
|
||||
u32 offset;
|
||||
u32 bin;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -358,6 +364,7 @@ struct ipa3_hdr_proc_ctx_offset_entry {
|
|||
* @ref_cnt: reference counter of routing table
|
||||
* @id: processing context header entry id
|
||||
* @user_deleted: is the hdr processing context deleted by the user?
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa3_hdr_proc_ctx_entry {
|
||||
struct list_head link;
|
||||
|
@ -368,6 +375,7 @@ struct ipa3_hdr_proc_ctx_entry {
|
|||
u32 ref_cnt;
|
||||
int id;
|
||||
bool user_deleted;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -423,6 +431,8 @@ struct ipa3_flt_tbl {
|
|||
* @prio: rule 10bit priority which defines the order of the rule
|
||||
* among other rules at the integrated same table
|
||||
* @rule_id: rule 10bit ID to be returned in packet status
|
||||
* @rule_id_valid: indicate if rule_id_valid valid or not?
|
||||
* @ipacm_installed: indicate if installed by ipacm
|
||||
*/
|
||||
struct ipa3_rt_entry {
|
||||
struct list_head link;
|
||||
|
@ -436,6 +446,7 @@ struct ipa3_rt_entry {
|
|||
u16 prio;
|
||||
u16 rule_id;
|
||||
u16 rule_id_valid;
|
||||
bool ipacm_installed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1217,6 +1228,8 @@ struct ipa3_context {
|
|||
struct list_head msg_list;
|
||||
struct list_head pull_msg_list;
|
||||
struct mutex msg_lock;
|
||||
struct list_head msg_wlan_client_list;
|
||||
struct mutex msg_wlan_client_lock;
|
||||
wait_queue_head_t msg_waitq;
|
||||
enum ipa_hw_type ipa_hw_type;
|
||||
enum ipa3_hw_mode ipa3_hw_mode;
|
||||
|
@ -1591,13 +1604,15 @@ int ipa3_cfg_ep_ctrl(u32 clnt_hdl, const struct ipa_ep_cfg_ctrl *ep_ctrl);
|
|||
*/
|
||||
int ipa3_add_hdr(struct ipa_ioc_add_hdr *hdrs);
|
||||
|
||||
int ipa3_add_hdr_usr(struct ipa_ioc_add_hdr *hdrs, bool by_user);
|
||||
|
||||
int ipa3_del_hdr(struct ipa_ioc_del_hdr *hdls);
|
||||
|
||||
int ipa3_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user);
|
||||
|
||||
int ipa3_commit_hdr(void);
|
||||
|
||||
int ipa3_reset_hdr(void);
|
||||
int ipa3_reset_hdr(bool user_only);
|
||||
|
||||
int ipa3_get_hdr(struct ipa_ioc_get_hdr *lookup);
|
||||
|
||||
|
@ -1608,7 +1623,8 @@ int ipa3_copy_hdr(struct ipa_ioc_copy_hdr *copy);
|
|||
/*
|
||||
* Header Processing Context
|
||||
*/
|
||||
int ipa3_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs);
|
||||
int ipa3_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs,
|
||||
bool user_only);
|
||||
|
||||
int ipa3_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls);
|
||||
|
||||
|
@ -1620,6 +1636,9 @@ int ipa3_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls,
|
|||
*/
|
||||
int ipa3_add_rt_rule(struct ipa_ioc_add_rt_rule *rules);
|
||||
|
||||
int ipa3_add_rt_rule_usr(struct ipa_ioc_add_rt_rule *rules,
|
||||
bool user_only);
|
||||
|
||||
int ipa3_add_rt_rule_ext(struct ipa_ioc_add_rt_rule_ext *rules);
|
||||
|
||||
int ipa3_add_rt_rule_after(struct ipa_ioc_add_rt_rule_after *rules);
|
||||
|
@ -1628,7 +1647,7 @@ int ipa3_del_rt_rule(struct ipa_ioc_del_rt_rule *hdls);
|
|||
|
||||
int ipa3_commit_rt(enum ipa_ip_type ip);
|
||||
|
||||
int ipa3_reset_rt(enum ipa_ip_type ip);
|
||||
int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only);
|
||||
|
||||
int ipa3_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup);
|
||||
|
||||
|
@ -1643,6 +1662,9 @@ int ipa3_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *rules);
|
|||
*/
|
||||
int ipa3_add_flt_rule(struct ipa_ioc_add_flt_rule *rules);
|
||||
|
||||
int ipa3_add_flt_rule_usr(struct ipa_ioc_add_flt_rule *rules,
|
||||
bool user_only);
|
||||
|
||||
int ipa3_add_flt_rule_after(struct ipa_ioc_add_flt_rule_after *rules);
|
||||
|
||||
int ipa3_del_flt_rule(struct ipa_ioc_del_flt_rule *hdls);
|
||||
|
@ -1651,7 +1673,7 @@ int ipa3_mdfy_flt_rule(struct ipa_ioc_mdfy_flt_rule *rules);
|
|||
|
||||
int ipa3_commit_flt(enum ipa_ip_type ip);
|
||||
|
||||
int ipa3_reset_flt(enum ipa_ip_type ip);
|
||||
int ipa3_reset_flt(enum ipa_ip_type ip, bool user_only);
|
||||
|
||||
/*
|
||||
* NAT
|
||||
|
@ -1672,6 +1694,7 @@ int ipa3_del_nat_table(struct ipa_ioc_nat_ipv6ct_table_del *del);
|
|||
*/
|
||||
int ipa3_send_msg(struct ipa_msg_meta *meta, void *buff,
|
||||
ipa_msg_free_fn callback);
|
||||
int ipa3_resend_wlan_msg(void);
|
||||
int ipa3_register_pull_msg(struct ipa_msg_meta *meta, ipa_msg_pull_fn callback);
|
||||
int ipa3_deregister_pull_msg(struct ipa_msg_meta *meta);
|
||||
|
||||
|
@ -1704,7 +1727,7 @@ int ipa3_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
|
|||
* To transfer multiple data packets
|
||||
* While passing the data descriptor list, the anchor node
|
||||
* should be of type struct ipa_tx_data_desc not list_head
|
||||
*/
|
||||
*/
|
||||
int ipa3_tx_dp_mul(enum ipa_client_type dst,
|
||||
struct ipa_tx_data_desc *data_desc);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2018, 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
|
||||
|
@ -13,6 +13,7 @@
|
|||
#include <linux/fs.h>
|
||||
#include <linux/sched.h>
|
||||
#include "ipa_i.h"
|
||||
#include <linux/msm_ipa.h>
|
||||
|
||||
struct ipa3_intf {
|
||||
char name[IPA_RESOURCE_NAME_MAX];
|
||||
|
@ -387,6 +388,108 @@ static void ipa3_send_msg_free(void *buff, u32 len, u32 type)
|
|||
kfree(buff);
|
||||
}
|
||||
|
||||
static int wlan_msg_process(struct ipa_msg_meta *meta, void *buff)
|
||||
{
|
||||
struct ipa3_push_msg *msg_dup;
|
||||
struct ipa_wlan_msg_ex *event_ex_cur_con = NULL;
|
||||
struct ipa_wlan_msg_ex *event_ex_list = NULL;
|
||||
struct ipa_wlan_msg *event_ex_cur_discon = NULL;
|
||||
void *data_dup = NULL;
|
||||
struct ipa3_push_msg *entry;
|
||||
struct ipa3_push_msg *next;
|
||||
int cnt = 0, total = 0, max = 0;
|
||||
uint8_t mac[IPA_MAC_ADDR_SIZE];
|
||||
uint8_t mac2[IPA_MAC_ADDR_SIZE];
|
||||
|
||||
if (meta->msg_type == WLAN_CLIENT_CONNECT_EX) {
|
||||
/* debug print */
|
||||
event_ex_cur_con = buff;
|
||||
for (cnt = 0; cnt < event_ex_cur_con->num_of_attribs; cnt++) {
|
||||
if (event_ex_cur_con->attribs[cnt].attrib_type ==
|
||||
WLAN_HDR_ATTRIB_MAC_ADDR) {
|
||||
IPADBG("%02x:%02x:%02x:%02x:%02x:%02x,(%d)\n",
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[0],
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[1],
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[2],
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[3],
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[4],
|
||||
event_ex_cur_con->attribs[cnt].u.mac_addr[5],
|
||||
meta->msg_type);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&ipa3_ctx->msg_wlan_client_lock);
|
||||
msg_dup = kzalloc(sizeof(struct ipa3_push_msg), GFP_KERNEL);
|
||||
if (msg_dup == NULL) {
|
||||
IPAERR("fail to alloc ipa_msg container\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
msg_dup->meta = *meta;
|
||||
if (meta->msg_len > 0 && buff) {
|
||||
data_dup = kmalloc(meta->msg_len, GFP_KERNEL);
|
||||
if (data_dup == NULL) {
|
||||
IPAERR("fail to alloc data_dup container\n");
|
||||
kfree(msg_dup);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(data_dup, buff, meta->msg_len);
|
||||
msg_dup->buff = data_dup;
|
||||
msg_dup->callback = ipa3_send_msg_free;
|
||||
}
|
||||
list_add_tail(&msg_dup->link, &ipa3_ctx->msg_wlan_client_list);
|
||||
mutex_unlock(&ipa3_ctx->msg_wlan_client_lock);
|
||||
}
|
||||
|
||||
/* remove the cache */
|
||||
if (meta->msg_type == WLAN_CLIENT_DISCONNECT) {
|
||||
/* debug print */
|
||||
event_ex_cur_discon = buff;
|
||||
IPADBG("Mac %02x:%02x:%02x:%02x:%02x:%02x,msg %d\n",
|
||||
event_ex_cur_discon->mac_addr[0],
|
||||
event_ex_cur_discon->mac_addr[1],
|
||||
event_ex_cur_discon->mac_addr[2],
|
||||
event_ex_cur_discon->mac_addr[3],
|
||||
event_ex_cur_discon->mac_addr[4],
|
||||
event_ex_cur_discon->mac_addr[5],
|
||||
meta->msg_type);
|
||||
memcpy(mac2,
|
||||
event_ex_cur_discon->mac_addr,
|
||||
sizeof(mac2));
|
||||
|
||||
mutex_lock(&ipa3_ctx->msg_wlan_client_lock);
|
||||
list_for_each_entry_safe(entry, next,
|
||||
&ipa3_ctx->msg_wlan_client_list,
|
||||
link) {
|
||||
event_ex_list = entry->buff;
|
||||
max = event_ex_list->num_of_attribs;
|
||||
for (cnt = 0; cnt < max; cnt++) {
|
||||
memcpy(mac,
|
||||
event_ex_list->attribs[cnt].u.mac_addr,
|
||||
sizeof(mac));
|
||||
if (event_ex_list->attribs[cnt].attrib_type ==
|
||||
WLAN_HDR_ATTRIB_MAC_ADDR) {
|
||||
pr_debug("%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2],
|
||||
mac[3], mac[4], mac[5]);
|
||||
|
||||
/* compare to delete one*/
|
||||
if (memcmp(mac2,
|
||||
mac,
|
||||
sizeof(mac)) == 0) {
|
||||
IPADBG("clean %d\n", total);
|
||||
list_del(&entry->link);
|
||||
kfree(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
total++;
|
||||
}
|
||||
mutex_unlock(&ipa3_ctx->msg_wlan_client_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa3_send_msg() - Send "message" from kernel client to IPA driver
|
||||
* @meta: [in] message meta-data
|
||||
|
@ -409,7 +512,7 @@ int ipa3_send_msg(struct ipa_msg_meta *meta, void *buff,
|
|||
void *data = NULL;
|
||||
|
||||
if (meta == NULL || (buff == NULL && callback != NULL) ||
|
||||
(buff != NULL && callback == NULL)) {
|
||||
(buff != NULL && callback == NULL) || buff == NULL) {
|
||||
IPAERR_RL("invalid param meta=%p buff=%p, callback=%p\n",
|
||||
meta, buff, callback);
|
||||
return -EINVAL;
|
||||
|
@ -441,6 +544,11 @@ int ipa3_send_msg(struct ipa_msg_meta *meta, void *buff,
|
|||
|
||||
mutex_lock(&ipa3_ctx->msg_lock);
|
||||
list_add_tail(&msg->link, &ipa3_ctx->msg_list);
|
||||
/* support for softap client event cache */
|
||||
if (wlan_msg_process(meta, buff))
|
||||
IPAERR("wlan_msg_process failed\n");
|
||||
|
||||
/* unlock only after process */
|
||||
mutex_unlock(&ipa3_ctx->msg_lock);
|
||||
IPA_STATS_INC_CNT(ipa3_ctx->stats.msg_w[meta->msg_type]);
|
||||
|
||||
|
@ -451,6 +559,73 @@ int ipa3_send_msg(struct ipa_msg_meta *meta, void *buff,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa3_resend_wlan_msg() - Resend cached "message" to IPACM
|
||||
*
|
||||
* resend wlan client connect events to user-space
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa3_resend_wlan_msg(void)
|
||||
{
|
||||
struct ipa_wlan_msg_ex *event_ex_list = NULL;
|
||||
struct ipa3_push_msg *entry;
|
||||
struct ipa3_push_msg *next;
|
||||
int cnt = 0, total = 0;
|
||||
struct ipa3_push_msg *msg;
|
||||
void *data = NULL;
|
||||
|
||||
IPADBG("\n");
|
||||
|
||||
mutex_lock(&ipa3_ctx->msg_wlan_client_lock);
|
||||
list_for_each_entry_safe(entry, next, &ipa3_ctx->msg_wlan_client_list,
|
||||
link) {
|
||||
|
||||
event_ex_list = entry->buff;
|
||||
for (cnt = 0; cnt < event_ex_list->num_of_attribs; cnt++) {
|
||||
if (event_ex_list->attribs[cnt].attrib_type ==
|
||||
WLAN_HDR_ATTRIB_MAC_ADDR) {
|
||||
IPADBG("%d-Mac %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
total,
|
||||
event_ex_list->attribs[cnt].u.mac_addr[0],
|
||||
event_ex_list->attribs[cnt].u.mac_addr[1],
|
||||
event_ex_list->attribs[cnt].u.mac_addr[2],
|
||||
event_ex_list->attribs[cnt].u.mac_addr[3],
|
||||
event_ex_list->attribs[cnt].u.mac_addr[4],
|
||||
event_ex_list->attribs[cnt].u.mac_addr[5]);
|
||||
}
|
||||
}
|
||||
|
||||
msg = kzalloc(sizeof(struct ipa3_push_msg), GFP_KERNEL);
|
||||
if (msg == NULL) {
|
||||
IPAERR("fail to alloc ipa_msg container\n");
|
||||
mutex_unlock(&ipa3_ctx->msg_wlan_client_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
msg->meta = entry->meta;
|
||||
data = kmalloc(entry->meta.msg_len, GFP_KERNEL);
|
||||
if (data == NULL) {
|
||||
IPAERR("fail to alloc data container\n");
|
||||
kfree(msg);
|
||||
mutex_unlock(&ipa3_ctx->msg_wlan_client_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(data, entry->buff, entry->meta.msg_len);
|
||||
msg->buff = data;
|
||||
msg->callback = ipa3_send_msg_free;
|
||||
mutex_lock(&ipa3_ctx->msg_lock);
|
||||
list_add_tail(&msg->link, &ipa3_ctx->msg_list);
|
||||
mutex_unlock(&ipa3_ctx->msg_lock);
|
||||
wake_up(&ipa3_ctx->msg_waitq);
|
||||
|
||||
total++;
|
||||
}
|
||||
mutex_unlock(&ipa3_ctx->msg_wlan_client_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa3_register_pull_msg() - register pull message type
|
||||
* @meta: [in] message meta-data
|
||||
|
|
|
@ -605,6 +605,14 @@ int ipa3_qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req)
|
|||
int rc;
|
||||
int i;
|
||||
|
||||
/* check if modem up */
|
||||
if (!ipa3_qmi_indication_fin ||
|
||||
!ipa3_qmi_modem_init_fin ||
|
||||
!ipa_q6_clnt) {
|
||||
IPAWANDBG("modem QMI haven't up yet\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check if the filter rules from IPACM is valid */
|
||||
if (req->filter_spec_list_len == 0)
|
||||
IPAWANDBG("IPACM pass zero rules to Q6\n");
|
||||
|
@ -688,6 +696,14 @@ int ipa3_qmi_filter_request_ex_send(
|
|||
int rc;
|
||||
int i;
|
||||
|
||||
/* check if modem up */
|
||||
if (!ipa3_qmi_indication_fin ||
|
||||
!ipa3_qmi_modem_init_fin ||
|
||||
!ipa_q6_clnt) {
|
||||
IPAWANDBG("modem QMI haven't up yet\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check if the filter rules from IPACM is valid */
|
||||
if (req->filter_spec_ex_list_len == 0) {
|
||||
IPAWANDBG("IPACM pass zero rules to Q6\n");
|
||||
|
|
|
@ -940,7 +940,7 @@ static int __ipa_create_rt_entry(struct ipa3_rt_entry **entry,
|
|||
const struct ipa_rt_rule *rule,
|
||||
struct ipa3_rt_tbl *tbl, struct ipa3_hdr_entry *hdr,
|
||||
struct ipa3_hdr_proc_ctx_entry *proc_ctx,
|
||||
u16 rule_id)
|
||||
u16 rule_id, bool user)
|
||||
{
|
||||
int id;
|
||||
|
||||
|
@ -967,6 +967,7 @@ static int __ipa_create_rt_entry(struct ipa3_rt_entry **entry,
|
|||
}
|
||||
}
|
||||
(*(entry))->rule_id = id;
|
||||
(*(entry))->ipacm_installed = user;
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -1012,7 +1013,7 @@ ipa_insert_failed:
|
|||
|
||||
static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
|
||||
const struct ipa_rt_rule *rule, u8 at_rear, u32 *rule_hdl,
|
||||
u16 rule_id)
|
||||
u16 rule_id, bool user)
|
||||
{
|
||||
struct ipa3_rt_tbl *tbl;
|
||||
struct ipa3_rt_entry *entry;
|
||||
|
@ -1041,7 +1042,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
|
|||
}
|
||||
|
||||
if (__ipa_create_rt_entry(&entry, rule, tbl, hdr, proc_ctx,
|
||||
rule_id))
|
||||
rule_id, user))
|
||||
goto error;
|
||||
|
||||
if (at_rear)
|
||||
|
@ -1072,7 +1073,7 @@ static int __ipa_add_rt_rule_after(struct ipa3_rt_tbl *tbl,
|
|||
if (__ipa_rt_validate_hndls(rule, &hdr, &proc_ctx))
|
||||
goto error;
|
||||
|
||||
if (__ipa_create_rt_entry(&entry, rule, tbl, hdr, proc_ctx, 0))
|
||||
if (__ipa_create_rt_entry(&entry, rule, tbl, hdr, proc_ctx, 0, true))
|
||||
goto error;
|
||||
|
||||
list_add(&entry->link, &((*add_after_entry)->link));
|
||||
|
@ -1101,7 +1102,23 @@ error:
|
|||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
|
||||
int ipa3_add_rt_rule(struct ipa_ioc_add_rt_rule *rules)
|
||||
{
|
||||
return ipa3_add_rt_rule_usr(rules, false);
|
||||
}
|
||||
/**
|
||||
* ipa3_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 installed by userspace module
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
|
||||
int ipa3_add_rt_rule_usr(struct ipa_ioc_add_rt_rule *rules, bool user_only)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
@ -1117,7 +1134,8 @@ int ipa3_add_rt_rule(struct ipa_ioc_add_rt_rule *rules)
|
|||
&rules->rules[i].rule,
|
||||
rules->rules[i].at_rear,
|
||||
&rules->rules[i].rt_rule_hdl,
|
||||
0)) {
|
||||
0,
|
||||
user_only)) {
|
||||
IPAERR("failed to add rt rule %d\n", i);
|
||||
rules->rules[i].status = IPA_RT_STATUS_OF_ADD_FAILED;
|
||||
} else {
|
||||
|
@ -1162,7 +1180,7 @@ int ipa3_add_rt_rule_ext(struct ipa_ioc_add_rt_rule_ext *rules)
|
|||
&rules->rules[i].rule,
|
||||
rules->rules[i].at_rear,
|
||||
&rules->rules[i].rt_rule_hdl,
|
||||
rules->rules[i].rule_id)) {
|
||||
rules->rules[i].rule_id, true)) {
|
||||
IPAERR("failed to add rt rule %d\n", i);
|
||||
rules->rules[i].status = IPA_RT_STATUS_OF_ADD_FAILED;
|
||||
} else {
|
||||
|
@ -1439,13 +1457,14 @@ bail:
|
|||
/**
|
||||
* ipa3_reset_rt() - reset the current SW routing table of specified type
|
||||
* (does not commit to HW)
|
||||
* @ip: 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
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa3_reset_rt(enum ipa_ip_type ip)
|
||||
int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only)
|
||||
{
|
||||
struct ipa3_rt_tbl *tbl;
|
||||
struct ipa3_rt_tbl *tbl_next;
|
||||
|
@ -1455,6 +1474,7 @@ int ipa3_reset_rt(enum ipa_ip_type ip)
|
|||
struct ipa3_rt_tbl_set *rset;
|
||||
u32 apps_start_idx;
|
||||
int id;
|
||||
bool tbl_user = false;
|
||||
|
||||
if (ip >= IPA_IP_MAX) {
|
||||
IPAERR_RL("bad parm\n");
|
||||
|
@ -1472,7 +1492,7 @@ int ipa3_reset_rt(enum ipa_ip_type ip)
|
|||
* issue a reset on the filtering module of same IP type since
|
||||
* filtering rules point to routing tables
|
||||
*/
|
||||
if (ipa3_reset_flt(ip))
|
||||
if (ipa3_reset_flt(ip, user_only))
|
||||
IPAERR_RL("fail to reset flt ip=%d\n", ip);
|
||||
|
||||
set = &ipa3_ctx->rt_tbl_set[ip];
|
||||
|
@ -1480,6 +1500,7 @@ int ipa3_reset_rt(enum ipa_ip_type ip)
|
|||
mutex_lock(&ipa3_ctx->lock);
|
||||
IPADBG("reset rt ip=%d\n", ip);
|
||||
list_for_each_entry_safe(tbl, tbl_next, &set->head_rt_tbl_list, link) {
|
||||
tbl_user = false;
|
||||
list_for_each_entry_safe(rule, rule_next,
|
||||
&tbl->head_rt_rule_list, link) {
|
||||
if (ipa3_id_find(rule->id) == NULL) {
|
||||
|
@ -1488,6 +1509,12 @@ int ipa3_reset_rt(enum ipa_ip_type ip)
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* indicate if tbl used for user-specified rules*/
|
||||
if (rule->ipacm_installed) {
|
||||
IPADBG("tbl_user %d, tbl-index %d\n",
|
||||
tbl_user, tbl->id);
|
||||
tbl_user = true;
|
||||
}
|
||||
/*
|
||||
* for the "default" routing tbl, remove all but the
|
||||
* last rule
|
||||
|
@ -1495,19 +1522,23 @@ int ipa3_reset_rt(enum ipa_ip_type ip)
|
|||
if (tbl->idx == apps_start_idx && tbl->rule_cnt == 1)
|
||||
continue;
|
||||
|
||||
list_del(&rule->link);
|
||||
tbl->rule_cnt--;
|
||||
if (rule->hdr)
|
||||
__ipa3_release_hdr(rule->hdr->id);
|
||||
else if (rule->proc_ctx)
|
||||
__ipa3_release_hdr_proc_ctx(rule->proc_ctx->id);
|
||||
rule->cookie = 0;
|
||||
idr_remove(&tbl->rule_ids, rule->rule_id);
|
||||
id = rule->id;
|
||||
kmem_cache_free(ipa3_ctx->rt_rule_cache, rule);
|
||||
if (!user_only ||
|
||||
rule->ipacm_installed) {
|
||||
list_del(&rule->link);
|
||||
tbl->rule_cnt--;
|
||||
if (rule->hdr)
|
||||
__ipa3_release_hdr(rule->hdr->id);
|
||||
else if (rule->proc_ctx)
|
||||
__ipa3_release_hdr_proc_ctx(
|
||||
rule->proc_ctx->id);
|
||||
rule->cookie = 0;
|
||||
idr_remove(&tbl->rule_ids, rule->rule_id);
|
||||
id = rule->id;
|
||||
kmem_cache_free(ipa3_ctx->rt_rule_cache, rule);
|
||||
|
||||
/* remove the handle from the database */
|
||||
ipa3_id_remove(id);
|
||||
/* remove the handle from the database */
|
||||
ipa3_id_remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (ipa3_id_find(tbl->id) == NULL) {
|
||||
|
@ -1519,26 +1550,30 @@ int ipa3_reset_rt(enum ipa_ip_type ip)
|
|||
|
||||
/* do not remove the "default" routing tbl which has index 0 */
|
||||
if (tbl->idx != apps_start_idx) {
|
||||
idr_destroy(&tbl->rule_ids);
|
||||
if (tbl->in_sys[IPA_RULE_HASHABLE] ||
|
||||
tbl->in_sys[IPA_RULE_NON_HASHABLE]) {
|
||||
list_move(&tbl->link, &rset->head_rt_tbl_list);
|
||||
clear_bit(tbl->idx,
|
||||
if (!user_only || tbl_user) {
|
||||
idr_destroy(&tbl->rule_ids);
|
||||
if (tbl->in_sys[IPA_RULE_HASHABLE] ||
|
||||
tbl->in_sys[IPA_RULE_NON_HASHABLE]) {
|
||||
list_move(&tbl->link,
|
||||
&rset->head_rt_tbl_list);
|
||||
clear_bit(tbl->idx,
|
||||
&ipa3_ctx->rt_idx_bitmap[ip]);
|
||||
set->tbl_cnt--;
|
||||
IPADBG("rst sys rt tbl_idx=%d tbl_cnt=%d\n",
|
||||
set->tbl_cnt--;
|
||||
IPADBG("rst tbl_idx=%d cnt=%d\n",
|
||||
tbl->idx, set->tbl_cnt);
|
||||
} else {
|
||||
list_del(&tbl->link);
|
||||
set->tbl_cnt--;
|
||||
clear_bit(tbl->idx,
|
||||
} else {
|
||||
list_del(&tbl->link);
|
||||
set->tbl_cnt--;
|
||||
clear_bit(tbl->idx,
|
||||
&ipa3_ctx->rt_idx_bitmap[ip]);
|
||||
IPADBG("rst rt tbl_idx=%d tbl_cnt=%d\n",
|
||||
IPADBG("rst rt tbl_idx=%d tbl_cnt=%d\n",
|
||||
tbl->idx, set->tbl_cnt);
|
||||
kmem_cache_free(ipa3_ctx->rt_tbl_cache, tbl);
|
||||
kmem_cache_free(ipa3_ctx->rt_tbl_cache,
|
||||
tbl);
|
||||
}
|
||||
/* remove the handle from the database */
|
||||
ipa3_id_remove(id);
|
||||
}
|
||||
/* remove the handle from the database */
|
||||
ipa3_id_remove(id);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ipa3_ctx->lock);
|
||||
|
@ -1653,6 +1688,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
|
|||
struct ipa3_hdr_proc_ctx_entry *proc_ctx = NULL;
|
||||
struct ipa3_hdr_entry *hdr_entry;
|
||||
struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry;
|
||||
|
||||
if (rtrule->rule.hdr_hdl) {
|
||||
hdr = ipa3_id_find(rtrule->rule.hdr_hdl);
|
||||
if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, 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
|
||||
|
@ -3153,6 +3153,7 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type,
|
|||
api_ctrl->ipa_cfg_ep_holb_by_client = ipa3_cfg_ep_holb_by_client;
|
||||
api_ctrl->ipa_cfg_ep_ctrl = ipa3_cfg_ep_ctrl;
|
||||
api_ctrl->ipa_add_hdr = ipa3_add_hdr;
|
||||
api_ctrl->ipa_add_hdr_usr = ipa3_add_hdr_usr;
|
||||
api_ctrl->ipa_del_hdr = ipa3_del_hdr;
|
||||
api_ctrl->ipa_commit_hdr = ipa3_commit_hdr;
|
||||
api_ctrl->ipa_reset_hdr = ipa3_reset_hdr;
|
||||
|
@ -3162,6 +3163,7 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type,
|
|||
api_ctrl->ipa_add_hdr_proc_ctx = ipa3_add_hdr_proc_ctx;
|
||||
api_ctrl->ipa_del_hdr_proc_ctx = ipa3_del_hdr_proc_ctx;
|
||||
api_ctrl->ipa_add_rt_rule = ipa3_add_rt_rule;
|
||||
api_ctrl->ipa_add_rt_rule_usr = ipa3_add_rt_rule_usr;
|
||||
api_ctrl->ipa_del_rt_rule = ipa3_del_rt_rule;
|
||||
api_ctrl->ipa_commit_rt = ipa3_commit_rt;
|
||||
api_ctrl->ipa_reset_rt = ipa3_reset_rt;
|
||||
|
@ -3170,6 +3172,7 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type,
|
|||
api_ctrl->ipa_query_rt_index = ipa3_query_rt_index;
|
||||
api_ctrl->ipa_mdfy_rt_rule = ipa3_mdfy_rt_rule;
|
||||
api_ctrl->ipa_add_flt_rule = ipa3_add_flt_rule;
|
||||
api_ctrl->ipa_add_flt_rule_usr = ipa3_add_flt_rule_usr;
|
||||
api_ctrl->ipa_del_flt_rule = ipa3_del_flt_rule;
|
||||
api_ctrl->ipa_mdfy_flt_rule = ipa3_mdfy_flt_rule;
|
||||
api_ctrl->ipa_commit_flt = ipa3_commit_flt;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, 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
|
||||
|
@ -1226,11 +1226,13 @@ int ipa_cfg_ep_ctrl(u32 clnt_hdl, const struct ipa_ep_cfg_ctrl *ep_ctrl);
|
|||
*/
|
||||
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_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);
|
||||
|
||||
|
@ -1241,7 +1243,8 @@ int ipa_copy_hdr(struct ipa_ioc_copy_hdr *copy);
|
|||
/*
|
||||
* Header Processing 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 ipa_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls);
|
||||
|
||||
|
@ -1250,11 +1253,13 @@ 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_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_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);
|
||||
|
||||
|
@ -1269,13 +1274,15 @@ int ipa_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_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_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);
|
||||
int ipa_reset_flt(enum ipa_ip_type ip, bool user_only);
|
||||
|
||||
/*
|
||||
* NAT
|
||||
|
@ -1648,6 +1655,12 @@ static inline int ipa_add_hdr(struct ipa_ioc_add_hdr *hdrs)
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int ipa_add_hdr_usr(struct ipa_ioc_add_hdr *hdrs,
|
||||
bool user_only)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int ipa_del_hdr(struct ipa_ioc_del_hdr *hdls)
|
||||
{
|
||||
return -EPERM;
|
||||
|
@ -1658,7 +1671,7 @@ static inline int ipa_commit_hdr(void)
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int ipa_reset_hdr(void)
|
||||
static inline int ipa_reset_hdr(bool user_only)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
@ -1682,7 +1695,8 @@ static inline int ipa_copy_hdr(struct ipa_ioc_copy_hdr *copy)
|
|||
* Header Processing Context
|
||||
*/
|
||||
static inline int ipa_add_hdr_proc_ctx(
|
||||
struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs)
|
||||
struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs,
|
||||
bool user_only)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
@ -1699,6 +1713,12 @@ static inline int ipa_add_rt_rule(struct ipa_ioc_add_rt_rule *rules)
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int ipa_add_rt_rule_usr(struct ipa_ioc_add_rt_rule *rules,
|
||||
bool user_only)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int ipa_del_rt_rule(struct ipa_ioc_del_rt_rule *hdls)
|
||||
{
|
||||
return -EPERM;
|
||||
|
@ -1709,7 +1729,7 @@ static inline int ipa_commit_rt(enum ipa_ip_type ip)
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int ipa_reset_rt(enum ipa_ip_type ip)
|
||||
static inline int ipa_reset_rt(enum ipa_ip_type ip, bool user_only)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
@ -1742,6 +1762,12 @@ static inline int ipa_add_flt_rule(struct ipa_ioc_add_flt_rule *rules)
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int ipa_add_flt_rule_usr(struct ipa_ioc_add_flt_rule *rules,
|
||||
bool user_only)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int ipa_del_flt_rule(struct ipa_ioc_del_flt_rule *hdls)
|
||||
{
|
||||
return -EPERM;
|
||||
|
@ -1757,7 +1783,7 @@ static inline int ipa_commit_flt(enum ipa_ip_type ip)
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int ipa_reset_flt(enum ipa_ip_type ip)
|
||||
static inline int ipa_reset_flt(enum ipa_ip_type ip, bool user_only)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,9 @@
|
|||
#define IPA_IOCTL_DEL_VLAN_IFACE 53
|
||||
#define IPA_IOCTL_ADD_L2TP_VLAN_MAPPING 54
|
||||
#define IPA_IOCTL_DEL_L2TP_VLAN_MAPPING 55
|
||||
#define IPA_IOCTL_MAX 56
|
||||
#define IPA_IOCTL_CLEANUP 56
|
||||
#define IPA_IOCTL_QUERY_WLAN_CLIENT 57
|
||||
#define IPA_IOCTL_MAX 58
|
||||
|
||||
/**
|
||||
* max size of the header to be inserted
|
||||
|
@ -1912,6 +1914,10 @@ struct ipa_tether_device_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 *)
|
||||
#define IPA_IOC_CLEANUP _IO(IPA_IOC_MAGIC,\
|
||||
IPA_IOCTL_CLEANUP)
|
||||
#define IPA_IOC_QUERY_WLAN_CLIENT _IO(IPA_IOC_MAGIC,\
|
||||
IPA_IOCTL_QUERY_WLAN_CLIENT)
|
||||
/*
|
||||
* unique magic number of the Tethering bridge ioctls
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue