msm: ipa: Add support for per client lan statistics
Per client lan statistics feature requires fetching data from IPA-Q6 and share it with user space application. Make changes to provide ioctl-interface to interact with IPA Q6 to get the per client lan statistics. Change-Id: If0af747cd86058eaa275170f42af1d9e93e81768 Acked-by: Abhishek Choubey <abchoube@qti.qualcomm.com> Acked-by: Pooja Kumari <kumarip@qti.qualcomm.com> Acked-by: Chaitanya Pratapa <cpratapa@qti.qualcomm.com> Signed-off-by: Mohammed Javid <mjavid@codeaurora.org> Signed-off-by: Utkarsh Saxena <usaxena@codeaurora.org>
This commit is contained in:
parent
b33f617917
commit
c961b0bbfc
11 changed files with 1111 additions and 76 deletions
|
@ -86,7 +86,9 @@ const char *ipa_event_name[] = {
|
|||
__stringify(ADD_VLAN_IFACE),
|
||||
__stringify(DEL_VLAN_IFACE),
|
||||
__stringify(ADD_L2TP_VLAN_MAPPING),
|
||||
__stringify(DEL_L2TP_VLAN_MAPPING)
|
||||
__stringify(DEL_L2TP_VLAN_MAPPING),
|
||||
__stringify(IPA_PER_CLIENT_STATS_CONNECT_EVENT),
|
||||
__stringify(IPA_PER_CLIENT_STATS_DISCONNECT_EVENT),
|
||||
};
|
||||
|
||||
const char *ipa_hdr_l2_type_name[] = {
|
||||
|
|
|
@ -992,8 +992,52 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case IPA_IOC_ADD_RT_RULE_EXT:
|
||||
if (copy_from_user(header,
|
||||
(const void __user *)arg,
|
||||
sizeof(struct ipa_ioc_add_rt_rule_ext))) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
pre_entry =
|
||||
((struct ipa_ioc_add_rt_rule_ext *)header)->num_rules;
|
||||
pyld_sz =
|
||||
sizeof(struct ipa_ioc_add_rt_rule_ext) +
|
||||
pre_entry * sizeof(struct ipa_rt_rule_add_ext);
|
||||
param = kzalloc(pyld_sz, GFP_KERNEL);
|
||||
if (!param) {
|
||||
retval = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
if (copy_from_user(param, (const void __user *)arg,
|
||||
pyld_sz)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
/* add check in case user-space module compromised */
|
||||
if (unlikely(
|
||||
((struct ipa_ioc_add_rt_rule_ext *)param)->num_rules
|
||||
!= pre_entry)) {
|
||||
IPAERR(" prevent memory corruption(%d not match %d)\n",
|
||||
((struct ipa_ioc_add_rt_rule_ext *)param)->
|
||||
num_rules,
|
||||
pre_entry);
|
||||
retval = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (ipa3_add_rt_rule_ext(
|
||||
(struct ipa_ioc_add_rt_rule_ext *)param)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (copy_to_user((void __user *)arg, param, pyld_sz)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IPA_IOC_ADD_RT_RULE_AFTER:
|
||||
if (copy_from_user(header, (u8 *)arg,
|
||||
if (copy_from_user(header, (const void __user *)arg,
|
||||
sizeof(struct ipa_ioc_add_rt_rule_after))) {
|
||||
|
||||
retval = -EFAULT;
|
||||
|
|
|
@ -67,7 +67,9 @@ const char *ipa3_event_name[] = {
|
|||
__stringify(ADD_VLAN_IFACE),
|
||||
__stringify(DEL_VLAN_IFACE),
|
||||
__stringify(ADD_L2TP_VLAN_MAPPING),
|
||||
__stringify(DEL_L2TP_VLAN_MAPPING)
|
||||
__stringify(DEL_L2TP_VLAN_MAPPING),
|
||||
__stringify(IPA_PER_CLIENT_STATS_CONNECT_EVENT),
|
||||
__stringify(IPA_PER_CLIENT_STATS_DISCONNECT_EVENT),
|
||||
};
|
||||
|
||||
const char *ipa3_hdr_l2_type_name[] = {
|
||||
|
|
|
@ -435,6 +435,7 @@ struct ipa3_rt_entry {
|
|||
int id;
|
||||
u16 prio;
|
||||
u16 rule_id;
|
||||
u16 rule_id_valid;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1615,6 +1616,8 @@ 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_ext(struct ipa_ioc_add_rt_rule_ext *rules);
|
||||
|
||||
int ipa3_add_rt_rule_after(struct ipa_ioc_add_rt_rule_after *rules);
|
||||
|
||||
int ipa3_del_rt_rule(struct ipa_ioc_del_rt_rule *hdls);
|
||||
|
|
|
@ -1363,6 +1363,74 @@ int ipa3_qmi_stop_data_qouta(void)
|
|||
resp.resp.error, "ipa_stop_data_usage_quota_req_msg_v01");
|
||||
}
|
||||
|
||||
int ipa3_qmi_enable_per_client_stats(
|
||||
struct ipa_enable_per_client_stats_req_msg_v01 *req,
|
||||
struct ipa_enable_per_client_stats_resp_msg_v01 *resp)
|
||||
{
|
||||
struct msg_desc req_desc, resp_desc;
|
||||
int rc;
|
||||
|
||||
req_desc.max_msg_len =
|
||||
QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_MAX_MSG_LEN_V01;
|
||||
req_desc.msg_id =
|
||||
QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01;
|
||||
req_desc.ei_array =
|
||||
ipa3_enable_per_client_stats_req_msg_data_v01_ei;
|
||||
|
||||
resp_desc.max_msg_len =
|
||||
QMI_IPA_ENABLE_PER_CLIENT_STATS_RESP_MAX_MSG_LEN_V01;
|
||||
resp_desc.msg_id =
|
||||
QMI_IPA_ENABLE_PER_CLIENT_STATS_RESP_V01;
|
||||
resp_desc.ei_array =
|
||||
ipa3_enable_per_client_stats_resp_msg_data_v01_ei;
|
||||
|
||||
IPAWANDBG("Sending QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01\n");
|
||||
|
||||
rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, req,
|
||||
sizeof(struct ipa_enable_per_client_stats_req_msg_v01),
|
||||
&resp_desc, resp,
|
||||
sizeof(struct ipa_enable_per_client_stats_resp_msg_v01),
|
||||
QMI_SEND_STATS_REQ_TIMEOUT_MS);
|
||||
|
||||
IPAWANDBG("QMI_IPA_ENABLE_PER_CLIENT_STATS_RESP_V01 received\n");
|
||||
|
||||
return ipa3_check_qmi_response(rc,
|
||||
QMI_IPA_ENABLE_PER_CLIENT_STATS_REQ_V01, resp->resp.result,
|
||||
resp->resp.error, "ipa3_qmi_enable_per_client_stats");
|
||||
}
|
||||
|
||||
int ipa3_qmi_get_per_client_packet_stats(
|
||||
struct ipa_get_stats_per_client_req_msg_v01 *req,
|
||||
struct ipa_get_stats_per_client_resp_msg_v01 *resp)
|
||||
{
|
||||
struct msg_desc req_desc, resp_desc;
|
||||
int rc;
|
||||
|
||||
req_desc.max_msg_len = QMI_IPA_GET_STATS_PER_CLIENT_REQ_MAX_MSG_LEN_V01;
|
||||
req_desc.msg_id = QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01;
|
||||
req_desc.ei_array = ipa3_get_stats_per_client_req_msg_data_v01_ei;
|
||||
|
||||
resp_desc.max_msg_len =
|
||||
QMI_IPA_GET_STATS_PER_CLIENT_RESP_MAX_MSG_LEN_V01;
|
||||
resp_desc.msg_id = QMI_IPA_GET_STATS_PER_CLIENT_RESP_V01;
|
||||
resp_desc.ei_array = ipa3_get_stats_per_client_resp_msg_data_v01_ei;
|
||||
|
||||
IPAWANDBG("Sending QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01\n");
|
||||
|
||||
rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, req,
|
||||
sizeof(struct ipa_get_stats_per_client_req_msg_v01),
|
||||
&resp_desc, resp,
|
||||
sizeof(struct ipa_get_stats_per_client_resp_msg_v01),
|
||||
QMI_SEND_STATS_REQ_TIMEOUT_MS);
|
||||
|
||||
IPAWANDBG("QMI_IPA_GET_STATS_PER_CLIENT_RESP_V01 received\n");
|
||||
|
||||
return ipa3_check_qmi_response(rc,
|
||||
QMI_IPA_GET_STATS_PER_CLIENT_REQ_V01, resp->resp.result,
|
||||
resp->resp.error,
|
||||
"struct ipa_get_stats_per_client_req_msg_v01");
|
||||
}
|
||||
|
||||
void ipa3_qmi_init(void)
|
||||
{
|
||||
mutex_init(&ipa3_qmi_lock);
|
||||
|
|
|
@ -32,54 +32,58 @@
|
|||
|
||||
#define IPAWANDBG(fmt, args...) \
|
||||
do { \
|
||||
pr_debug(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \
|
||||
pr_debug(DEV_NAME " %s:%d " fmt, __func__,\
|
||||
__LINE__, ## args); \
|
||||
IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define IPAWANDBG_LOW(fmt, args...) \
|
||||
do { \
|
||||
pr_debug(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \
|
||||
pr_debug(DEV_NAME " %s:%d " fmt, __func__,\
|
||||
__LINE__, ## args); \
|
||||
IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
} while (0)
|
||||
|
||||
#define IPAWANERR(fmt, args...) \
|
||||
do { \
|
||||
pr_err(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \
|
||||
pr_err(DEV_NAME " %s:%d " fmt, __func__,\
|
||||
__LINE__, ## args); \
|
||||
IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
} while (0)
|
||||
|
||||
#define IPAWANINFO(fmt, args...) \
|
||||
do { \
|
||||
pr_info(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \
|
||||
pr_info(DEV_NAME " %s:%d " fmt, __func__,\
|
||||
__LINE__, ## args); \
|
||||
IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
DEV_NAME " %s:%d " fmt, ## args); \
|
||||
} while (0)
|
||||
|
||||
extern struct ipa3_qmi_context *ipa3_qmi_ctx;
|
||||
|
||||
struct ipa3_qmi_context {
|
||||
struct ipa_ioc_ext_intf_prop q6_ul_filter_rule[MAX_NUM_Q6_RULE];
|
||||
u32 q6_ul_filter_rule_hdl[MAX_NUM_Q6_RULE];
|
||||
int num_ipa_install_fltr_rule_req_msg;
|
||||
struct ipa_install_fltr_rule_req_msg_v01
|
||||
struct ipa_ioc_ext_intf_prop q6_ul_filter_rule[MAX_NUM_Q6_RULE];
|
||||
u32 q6_ul_filter_rule_hdl[MAX_NUM_Q6_RULE];
|
||||
int num_ipa_install_fltr_rule_req_msg;
|
||||
struct ipa_install_fltr_rule_req_msg_v01
|
||||
ipa_install_fltr_rule_req_msg_cache[MAX_NUM_QMI_RULE_CACHE];
|
||||
int num_ipa_install_fltr_rule_req_ex_msg;
|
||||
struct ipa_install_fltr_rule_req_ex_msg_v01
|
||||
int num_ipa_install_fltr_rule_req_ex_msg;
|
||||
struct ipa_install_fltr_rule_req_ex_msg_v01
|
||||
ipa_install_fltr_rule_req_ex_msg_cache[MAX_NUM_QMI_RULE_CACHE];
|
||||
int num_ipa_fltr_installed_notif_req_msg;
|
||||
struct ipa_fltr_installed_notif_req_msg_v01
|
||||
int num_ipa_fltr_installed_notif_req_msg;
|
||||
struct ipa_fltr_installed_notif_req_msg_v01
|
||||
ipa_fltr_installed_notif_req_msg_cache[MAX_NUM_QMI_RULE_CACHE];
|
||||
bool modem_cfg_emb_pipe_flt;
|
||||
bool modem_cfg_emb_pipe_flt;
|
||||
};
|
||||
|
||||
struct ipa3_rmnet_mux_val {
|
||||
|
@ -95,56 +99,69 @@ extern struct elem_info ipa3_init_modem_driver_req_msg_data_v01_ei[];
|
|||
extern struct elem_info ipa3_init_modem_driver_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_indication_reg_req_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_indication_reg_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_master_driver_init_complt_ind_msg_data_v01_ei[];
|
||||
|
||||
extern struct elem_info
|
||||
ipa3_master_driver_init_complt_ind_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_install_fltr_rule_req_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_install_fltr_rule_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_fltr_installed_notif_req_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_fltr_installed_notif_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_enable_force_clear_datapath_req_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_enable_force_clear_datapath_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_disable_force_clear_datapath_req_msg_data_v01_ei[];
|
||||
|
||||
extern struct elem_info
|
||||
ipa3_enable_force_clear_datapath_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_enable_force_clear_datapath_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_disable_force_clear_datapath_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_disable_force_clear_datapath_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_config_req_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_config_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_get_data_stats_req_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_get_data_stats_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_get_apn_data_stats_req_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_get_apn_data_stats_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_set_data_usage_quota_req_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_set_data_usage_quota_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_data_usage_quota_reached_ind_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_stop_data_usage_quota_req_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_stop_data_usage_quota_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_init_modem_driver_cmplt_req_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_init_modem_driver_cmplt_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_install_fltr_rule_req_ex_msg_data_v01_ei[];
|
||||
extern struct elem_info ipa3_install_fltr_rule_resp_ex_msg_data_v01_ei[];
|
||||
|
||||
extern struct elem_info
|
||||
ipa3_install_fltr_rule_req_ex_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_install_fltr_rule_resp_ex_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_ul_firewall_rule_type_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_ul_firewall_config_result_type_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_per_client_stats_info_type_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_enable_per_client_stats_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_enable_per_client_stats_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_get_stats_per_client_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_get_stats_per_client_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_configure_ul_firewall_rules_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_configure_ul_firewall_rules_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_configure_ul_firewall_rules_ind_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_get_apn_data_stats_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_get_apn_data_stats_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_set_data_usage_quota_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_set_data_usage_quota_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_data_usage_quota_reached_ind_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_stop_data_usage_quota_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_stop_data_usage_quota_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_init_modem_driver_cmplt_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_init_modem_driver_cmplt_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_install_fltr_rule_req_ex_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_install_fltr_rule_resp_ex_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_ul_firewall_rule_type_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_ul_firewall_config_result_type_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_per_client_stats_info_type_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_enable_per_client_stats_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_enable_per_client_stats_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_get_stats_per_client_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_get_stats_per_client_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_configure_ul_firewall_rules_req_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_configure_ul_firewall_rules_resp_msg_data_v01_ei[];
|
||||
extern struct elem_info
|
||||
ipa3_configure_ul_firewall_rules_ind_msg_data_v01_ei[];
|
||||
|
||||
/**
|
||||
* struct ipa3_rmnet_context - IPA rmnet context
|
||||
|
@ -219,6 +236,16 @@ int rmnet_ipa3_query_tethering_stats_all(
|
|||
struct wan_ioctl_query_tether_stats_all *data);
|
||||
|
||||
int rmnet_ipa3_reset_tethering_stats(struct wan_ioctl_reset_tether_stats *data);
|
||||
int rmnet_ipa3_set_lan_client_info(struct wan_ioctl_lan_client_info *data);
|
||||
|
||||
int rmnet_ipa3_clear_lan_client_info(struct wan_ioctl_lan_client_info *data);
|
||||
|
||||
int rmnet_ipa3_send_lan_client_msg(struct wan_ioctl_send_lan_client_msg *data);
|
||||
|
||||
int rmnet_ipa3_enable_per_client_stats(bool *data);
|
||||
|
||||
int rmnet_ipa3_query_per_client_stats(
|
||||
struct wan_ioctl_query_per_client_stats *data);
|
||||
|
||||
int ipa3_qmi_get_data_stats(struct ipa_get_data_stats_req_msg_v01 *req,
|
||||
struct ipa_get_data_stats_resp_msg_v01 *resp);
|
||||
|
@ -232,6 +259,14 @@ int ipa3_qmi_stop_data_qouta(void);
|
|||
|
||||
void ipa3_q6_handshake_complete(bool ssr_bootup);
|
||||
|
||||
int ipa3_qmi_enable_per_client_stats(
|
||||
struct ipa_enable_per_client_stats_req_msg_v01 *req,
|
||||
struct ipa_enable_per_client_stats_resp_msg_v01 *resp);
|
||||
|
||||
int ipa3_qmi_get_per_client_packet_stats(
|
||||
struct ipa_get_stats_per_client_req_msg_v01 *req,
|
||||
struct ipa_get_stats_per_client_resp_msg_v01 *resp);
|
||||
|
||||
void ipa3_qmi_init(void);
|
||||
|
||||
void ipa3_qmi_cleanup(void);
|
||||
|
@ -348,12 +383,28 @@ static inline int ipa3_qmi_stop_data_qouta(void)
|
|||
|
||||
static inline void ipa3_q6_handshake_complete(bool ssr_bootup) { }
|
||||
|
||||
static inline int ipa3_qmi_enable_per_client_stats(
|
||||
struct ipa_enable_per_client_stats_req_msg_v01 *req,
|
||||
struct ipa_enable_per_client_stats_resp_msg_v01 *resp)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int ipa3_qmi_get_per_client_packet_stats(
|
||||
struct ipa_get_stats_per_client_req_msg_v01 *req,
|
||||
struct ipa_get_stats_per_client_resp_msg_v01 *resp)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline void ipa3_qmi_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void ipa3_qmi_cleanup(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RMNET_IPA3 */
|
||||
|
|
|
@ -918,7 +918,8 @@ static int __ipa_rt_validate_hndls(const struct ipa_rt_rule *rule,
|
|||
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)
|
||||
struct ipa3_hdr_proc_ctx_entry *proc_ctx,
|
||||
u16 rule_id)
|
||||
{
|
||||
int id;
|
||||
|
||||
|
@ -933,11 +934,16 @@ static int __ipa_create_rt_entry(struct ipa3_rt_entry **entry,
|
|||
(*(entry))->tbl = tbl;
|
||||
(*(entry))->hdr = hdr;
|
||||
(*(entry))->proc_ctx = proc_ctx;
|
||||
id = ipa3_alloc_rule_id(&tbl->rule_ids);
|
||||
if (id < 0) {
|
||||
IPAERR("failed to allocate rule id\n");
|
||||
WARN_ON(1);
|
||||
goto alloc_rule_id_fail;
|
||||
if (rule_id) {
|
||||
id = rule_id;
|
||||
(*(entry))->rule_id_valid = 1;
|
||||
} else {
|
||||
id = ipa3_alloc_rule_id(&tbl->rule_ids);
|
||||
if (id < 0) {
|
||||
IPAERR("failed to allocate rule id\n");
|
||||
WARN_ON(1);
|
||||
goto alloc_rule_id_fail;
|
||||
}
|
||||
}
|
||||
(*(entry))->rule_id = id;
|
||||
|
||||
|
@ -984,7 +990,8 @@ 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)
|
||||
const struct ipa_rt_rule *rule, u8 at_rear, u32 *rule_hdl,
|
||||
u16 rule_id)
|
||||
{
|
||||
struct ipa3_rt_tbl *tbl;
|
||||
struct ipa3_rt_entry *entry;
|
||||
|
@ -1012,7 +1019,8 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (__ipa_create_rt_entry(&entry, rule, tbl, hdr, proc_ctx))
|
||||
if (__ipa_create_rt_entry(&entry, rule, tbl, hdr, proc_ctx,
|
||||
rule_id))
|
||||
goto error;
|
||||
|
||||
if (at_rear)
|
||||
|
@ -1043,7 +1051,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))
|
||||
if (__ipa_create_rt_entry(&entry, rule, tbl, hdr, proc_ctx, 0))
|
||||
goto error;
|
||||
|
||||
list_add(&entry->link, &((*add_after_entry)->link));
|
||||
|
@ -1087,8 +1095,54 @@ int ipa3_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)) {
|
||||
IPAERR_RL("failed to add rt rule %d\n", i);
|
||||
&rules->rules[i].rt_rule_hdl,
|
||||
0)) {
|
||||
IPAERR("failed to add rt rule %d\n", i);
|
||||
rules->rules[i].status = IPA_RT_STATUS_OF_ADD_FAILED;
|
||||
} else {
|
||||
rules->rules[i].status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rules->commit)
|
||||
if (ipa3_ctx->ctrl->ipa3_commit_rt(rules->ip)) {
|
||||
ret = -EPERM;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
bail:
|
||||
mutex_unlock(&ipa3_ctx->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa3_add_rt_rule_ext() - Add the specified routing rules to SW with rule id
|
||||
* and optionally commit to IPA HW
|
||||
* @rules: [inout] set of routing rules to add
|
||||
*
|
||||
* Returns: 0 on success, negative on failure
|
||||
*
|
||||
* Note: Should not be called from atomic context
|
||||
*/
|
||||
int ipa3_add_rt_rule_ext(struct ipa_ioc_add_rt_rule_ext *rules)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (rules == NULL || rules->num_rules == 0 || rules->ip >= IPA_IP_MAX) {
|
||||
IPAERR("bad parm\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&ipa3_ctx->lock);
|
||||
for (i = 0; i < rules->num_rules; i++) {
|
||||
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].rule_id)) {
|
||||
IPAERR("failed to add rt rule %d\n", i);
|
||||
rules->rules[i].status = IPA_RT_STATUS_OF_ADD_FAILED;
|
||||
} else {
|
||||
rules->rules[i].status = 0;
|
||||
|
@ -1229,7 +1283,9 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
|
|||
IPADBG("del rt rule tbl_idx=%d rule_cnt=%d rule_id=%d\n ref_cnt=%u",
|
||||
entry->tbl->idx, entry->tbl->rule_cnt,
|
||||
entry->rule_id, entry->tbl->ref_cnt);
|
||||
idr_remove(&entry->tbl->rule_ids, entry->rule_id);
|
||||
/* if rule id was allocated from idr, remove it */
|
||||
if (!entry->rule_id_valid)
|
||||
idr_remove(&entry->tbl->rule_ids, entry->rule_id);
|
||||
if (entry->tbl->rule_cnt == 0 && entry->tbl->ref_cnt == 0) {
|
||||
if (__ipa_del_rt_tbl(entry->tbl))
|
||||
IPAERR_RL("fail to del RT tbl\n");
|
||||
|
|
|
@ -142,6 +142,10 @@ struct rmnet_ipa3_context {
|
|||
u32 ipa3_to_apps_hdl;
|
||||
struct mutex pipe_handle_guard;
|
||||
struct mutex add_mux_channel_lock;
|
||||
struct mutex per_client_stats_guard;
|
||||
struct ipa_tether_device_info
|
||||
tether_device
|
||||
[IPACM_MAX_CLIENT_DEVICE_TYPES];
|
||||
};
|
||||
|
||||
static struct rmnet_ipa3_context *rmnet_ipa3_ctx;
|
||||
|
@ -2571,7 +2575,9 @@ static void rmnet_ipa_free_msg(void *buff, u32 len, u32 type)
|
|||
}
|
||||
|
||||
if (type != IPA_TETHERING_STATS_UPDATE_STATS &&
|
||||
type != IPA_TETHERING_STATS_UPDATE_NETWORK_STATS) {
|
||||
type != IPA_TETHERING_STATS_UPDATE_NETWORK_STATS &&
|
||||
type != IPA_PER_CLIENT_STATS_CONNECT_EVENT &&
|
||||
type != IPA_PER_CLIENT_STATS_DISCONNECT_EVENT) {
|
||||
IPAWANERR("Wrong type given. buff %p type %d\n",
|
||||
buff, type);
|
||||
}
|
||||
|
@ -3317,8 +3323,488 @@ void ipa3_q6_handshake_complete(bool ssr_bootup)
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool rmnet_ipa3_check_any_client_inited
|
||||
(
|
||||
enum ipacm_per_client_device_type device_type
|
||||
)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (; i < IPA_MAX_NUM_HW_PATH_CLIENTS; i++) {
|
||||
if (rmnet_ipa3_ctx->tether_device[device_type].
|
||||
lan_client[i].client_idx != -1 &&
|
||||
rmnet_ipa3_ctx->tether_device[device_type].
|
||||
lan_client[i].inited) {
|
||||
IPAWANERR("Found client index: %d which is inited\n",
|
||||
i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int rmnet_ipa3_get_lan_client_info
|
||||
(
|
||||
enum ipacm_per_client_device_type device_type,
|
||||
uint8_t mac[]
|
||||
)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
IPAWANDBG("Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2],
|
||||
mac[3], mac[4], mac[5]);
|
||||
|
||||
for (; i < IPA_MAX_NUM_HW_PATH_CLIENTS; i++) {
|
||||
if (memcmp(
|
||||
rmnet_ipa3_ctx->tether_device[device_type].
|
||||
lan_client[i].mac,
|
||||
mac,
|
||||
IPA_MAC_ADDR_SIZE) == 0) {
|
||||
IPAWANDBG("Matched client index: %d\n", i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int rmnet_ipa3_delete_lan_client_info
|
||||
(
|
||||
enum ipacm_per_client_device_type device_type,
|
||||
int lan_clnt_idx
|
||||
)
|
||||
{
|
||||
struct ipa_lan_client *lan_client = NULL;
|
||||
int i;
|
||||
|
||||
/* Check if the request is to clean up all clients. */
|
||||
if (lan_clnt_idx == 0xffffffff) {
|
||||
/* Reset the complete device info. */
|
||||
memset(&rmnet_ipa3_ctx->tether_device[device_type], 0,
|
||||
sizeof(struct ipa_tether_device_info));
|
||||
rmnet_ipa3_ctx->tether_device[device_type].ul_src_pipe = -1;
|
||||
for (i = 0; i < IPA_MAX_NUM_HW_PATH_CLIENTS; i++)
|
||||
rmnet_ipa3_ctx->tether_device[device_type].
|
||||
lan_client[i].client_idx = -1;
|
||||
} else {
|
||||
lan_client =
|
||||
&rmnet_ipa3_ctx->tether_device[device_type].
|
||||
lan_client[lan_clnt_idx];
|
||||
/* Reset the client info before sending the message. */
|
||||
memset(lan_client, 0, sizeof(struct ipa_lan_client));
|
||||
lan_client->client_idx = -1;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* rmnet_ipa3_set_lan_client_info() -
|
||||
* @data - IOCTL data
|
||||
*
|
||||
* This function handles WAN_IOC_SET_LAN_CLIENT_INFO.
|
||||
* It is used to store LAN client information which
|
||||
* is used to fetch the packet stats for a client.
|
||||
*
|
||||
* Return codes:
|
||||
* 0: Success
|
||||
* -EINVAL: Invalid args provided
|
||||
*/
|
||||
int rmnet_ipa3_set_lan_client_info(
|
||||
struct wan_ioctl_lan_client_info *data)
|
||||
{
|
||||
|
||||
struct ipa_lan_client *lan_client = NULL;
|
||||
|
||||
|
||||
IPAWANDBG("Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
data->mac[0], data->mac[1], data->mac[2],
|
||||
data->mac[3], data->mac[4], data->mac[5]);
|
||||
|
||||
/* Check if Device type is valid. */
|
||||
if (data->device_type >= IPACM_MAX_CLIENT_DEVICE_TYPES ||
|
||||
data->device_type < 0) {
|
||||
IPAWANERR("Invalid Device type: %d\n", data->device_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check if Client index is valid. */
|
||||
if (data->client_idx >= IPA_MAX_NUM_HW_PATH_CLIENTS ||
|
||||
data->client_idx < 0) {
|
||||
IPAWANERR("Invalid Client Index: %d\n", data->client_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
if (data->client_init) {
|
||||
/* check if the client is already inited. */
|
||||
if (rmnet_ipa3_ctx->tether_device[data->device_type]
|
||||
.lan_client[data->client_idx].inited) {
|
||||
IPAWANERR("Client already inited: %d:%d\n",
|
||||
data->device_type, data->client_idx);
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
lan_client =
|
||||
&rmnet_ipa3_ctx->tether_device[data->device_type].
|
||||
lan_client[data->client_idx];
|
||||
|
||||
memcpy(lan_client->mac, data->mac, IPA_MAC_ADDR_SIZE);
|
||||
|
||||
lan_client->client_idx = data->client_idx;
|
||||
|
||||
/* Update the Source pipe. */
|
||||
rmnet_ipa3_ctx->tether_device[data->device_type].ul_src_pipe =
|
||||
ipa3_get_ep_mapping(data->ul_src_pipe);
|
||||
|
||||
/* Update the header length if not set. */
|
||||
if (!rmnet_ipa3_ctx->tether_device[data->device_type].hdr_len)
|
||||
rmnet_ipa3_ctx->tether_device[data->device_type].hdr_len =
|
||||
data->hdr_len;
|
||||
|
||||
lan_client->inited = true;
|
||||
|
||||
rmnet_ipa3_ctx->tether_device[data->device_type].num_clients++;
|
||||
|
||||
IPAWANDBG("Set the lan client info: %d, %d, %d\n",
|
||||
lan_client->client_idx,
|
||||
rmnet_ipa3_ctx->tether_device[data->device_type].ul_src_pipe,
|
||||
rmnet_ipa3_ctx->tether_device[data->device_type].num_clients);
|
||||
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* rmnet_ipa3_delete_lan_client_info() -
|
||||
* @data - IOCTL data
|
||||
*
|
||||
* This function handles WAN_IOC_DELETE_LAN_CLIENT_INFO.
|
||||
* It is used to delete LAN client information which
|
||||
* is used to fetch the packet stats for a client.
|
||||
*
|
||||
* Return codes:
|
||||
* 0: Success
|
||||
* -EINVAL: Invalid args provided
|
||||
*/
|
||||
int rmnet_ipa3_clear_lan_client_info(
|
||||
struct wan_ioctl_lan_client_info *data)
|
||||
{
|
||||
|
||||
struct ipa_lan_client *lan_client = NULL;
|
||||
|
||||
|
||||
IPAWANDBG("Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
data->mac[0], data->mac[1], data->mac[2],
|
||||
data->mac[3], data->mac[4], data->mac[5]);
|
||||
|
||||
/* Check if Device type is valid. */
|
||||
if (data->device_type >= IPACM_MAX_CLIENT_DEVICE_TYPES ||
|
||||
data->device_type < 0) {
|
||||
IPAWANERR("Invalid Device type: %d\n", data->device_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check if Client index is valid. */
|
||||
if (data->client_idx >= IPA_MAX_NUM_HW_PATH_CLIENTS ||
|
||||
data->client_idx < 0) {
|
||||
IPAWANERR("Invalid Client Index: %d\n", data->client_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
lan_client =
|
||||
&rmnet_ipa3_ctx->tether_device[data->device_type].
|
||||
lan_client[data->client_idx];
|
||||
|
||||
if (!data->client_init) {
|
||||
/* check if the client is already de-inited. */
|
||||
if (!lan_client->inited) {
|
||||
IPAWANERR("Client already de-inited: %d:%d\n",
|
||||
data->device_type, data->client_idx);
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
lan_client->inited = false;
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* rmnet_ipa3_send_lan_client_msg() -
|
||||
* @data - IOCTL data
|
||||
*
|
||||
* This function handles WAN_IOC_SEND_LAN_CLIENT_MSG.
|
||||
* It is used to send LAN client information to IPACM.
|
||||
*
|
||||
* Return codes:
|
||||
* 0: Success
|
||||
* -EINVAL: Invalid args provided
|
||||
*/
|
||||
int rmnet_ipa3_send_lan_client_msg(
|
||||
struct wan_ioctl_send_lan_client_msg *data)
|
||||
{
|
||||
struct ipa_msg_meta msg_meta;
|
||||
int rc;
|
||||
struct ipa_lan_client_msg *lan_client;
|
||||
|
||||
/* Notify IPACM to reset the client index. */
|
||||
lan_client = kzalloc(sizeof(struct ipa_lan_client_msg),
|
||||
GFP_KERNEL);
|
||||
if (!lan_client) {
|
||||
IPAWANERR("Can't allocate memory for tether_info\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
|
||||
memcpy(lan_client, &data->lan_client,
|
||||
sizeof(struct ipa_lan_client_msg));
|
||||
msg_meta.msg_type = data->client_event;
|
||||
msg_meta.msg_len = sizeof(struct ipa_lan_client_msg);
|
||||
|
||||
rc = ipa_send_msg(&msg_meta, lan_client, rmnet_ipa_free_msg);
|
||||
if (rc) {
|
||||
IPAWANERR("ipa_send_msg failed: %d\n", rc);
|
||||
kfree(lan_client);
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* rmnet_ipa3_enable_per_client_stats() -
|
||||
* @data - IOCTL data
|
||||
*
|
||||
* This function handles WAN_IOC_ENABLE_PER_CLIENT_STATS.
|
||||
* It is used to indicate Q6 to start capturing per client stats.
|
||||
*
|
||||
* Return codes:
|
||||
* 0: Success
|
||||
* -EINVAL: Invalid args provided
|
||||
*/
|
||||
int rmnet_ipa3_enable_per_client_stats(
|
||||
bool *data)
|
||||
{
|
||||
struct ipa_enable_per_client_stats_req_msg_v01 *req;
|
||||
struct ipa_enable_per_client_stats_resp_msg_v01 *resp;
|
||||
int rc;
|
||||
|
||||
req =
|
||||
kzalloc(sizeof(struct ipa_enable_per_client_stats_req_msg_v01),
|
||||
GFP_KERNEL);
|
||||
if (!req) {
|
||||
IPAWANERR("Can't allocate memory for stats message\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
resp =
|
||||
kzalloc(sizeof(struct ipa_enable_per_client_stats_resp_msg_v01),
|
||||
GFP_KERNEL);
|
||||
if (!resp) {
|
||||
IPAWANERR("Can't allocate memory for stats message\n");
|
||||
kfree(req);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(req, 0,
|
||||
sizeof(struct ipa_enable_per_client_stats_req_msg_v01));
|
||||
memset(resp, 0,
|
||||
sizeof(struct ipa_enable_per_client_stats_resp_msg_v01));
|
||||
|
||||
if (*data)
|
||||
req->enable_per_client_stats = 1;
|
||||
else
|
||||
req->enable_per_client_stats = 0;
|
||||
|
||||
rc = ipa3_qmi_enable_per_client_stats(req, resp);
|
||||
if (rc) {
|
||||
IPAWANERR("can't enable per client stats\n");
|
||||
kfree(req);
|
||||
kfree(resp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
kfree(req);
|
||||
kfree(resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rmnet_ipa3_query_per_client_stats(
|
||||
struct wan_ioctl_query_per_client_stats *data)
|
||||
{
|
||||
struct ipa_get_stats_per_client_req_msg_v01 *req;
|
||||
struct ipa_get_stats_per_client_resp_msg_v01 *resp;
|
||||
int rc, lan_clnt_idx, lan_clnt_idx1, i;
|
||||
struct ipa_lan_client *lan_client = NULL;
|
||||
|
||||
|
||||
IPAWANDBG("Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
data->client_info[0].mac[0],
|
||||
data->client_info[0].mac[1],
|
||||
data->client_info[0].mac[2],
|
||||
data->client_info[0].mac[3],
|
||||
data->client_info[0].mac[4],
|
||||
data->client_info[0].mac[5]);
|
||||
|
||||
/* Check if Device type is valid. */
|
||||
if (data->device_type >= IPACM_MAX_CLIENT_DEVICE_TYPES ||
|
||||
data->device_type < 0) {
|
||||
IPAWANERR("Invalid Device type: %d\n", data->device_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check if num_clients is valid. */
|
||||
if (data->num_clients != IPA_MAX_NUM_HW_PATH_CLIENTS &&
|
||||
data->num_clients != 1) {
|
||||
IPAWANERR("Invalid number of clients: %d\n", data->num_clients);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
|
||||
if (data->num_clients == 1) {
|
||||
/* Check if the client info is valid.*/
|
||||
lan_clnt_idx1 = rmnet_ipa3_get_lan_client_info(
|
||||
data->device_type,
|
||||
data->client_info[0].mac);
|
||||
if (lan_clnt_idx1 < 0) {
|
||||
IPAWANERR("Client info not available return.\n");
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
return -EINVAL;
|
||||
}
|
||||
lan_client =
|
||||
&rmnet_ipa3_ctx->tether_device[data->device_type].
|
||||
lan_client[lan_clnt_idx1];
|
||||
/*
|
||||
* Check if disconnect flag is set and
|
||||
* see if all the clients info are cleared.
|
||||
*/
|
||||
if (data->disconnect_clnt &&
|
||||
lan_client->inited) {
|
||||
IPAWANERR("Client not inited. Try again.\n");
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Max number of clients. */
|
||||
/* Check if disconnect flag is set and
|
||||
* see if all the clients info are cleared.
|
||||
*/
|
||||
if (data->disconnect_clnt &&
|
||||
rmnet_ipa3_check_any_client_inited(data->device_type)) {
|
||||
IPAWANERR("CLient not inited. Try again.\n");
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
return -EAGAIN;
|
||||
}
|
||||
lan_clnt_idx1 = 0xffffffff;
|
||||
}
|
||||
|
||||
req = kzalloc(sizeof(struct ipa_get_stats_per_client_req_msg_v01),
|
||||
GFP_KERNEL);
|
||||
if (!req) {
|
||||
IPAWANERR("Can't allocate memory for stats message\n");
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
return -ENOMEM;
|
||||
}
|
||||
resp = kzalloc(sizeof(struct ipa_get_stats_per_client_resp_msg_v01),
|
||||
GFP_KERNEL);
|
||||
if (!resp) {
|
||||
IPAWANERR("Can't allocate memory for stats message\n");
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
kfree(req);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(req, 0, sizeof(struct ipa_get_stats_per_client_req_msg_v01));
|
||||
memset(resp, 0, sizeof(struct ipa_get_stats_per_client_resp_msg_v01));
|
||||
|
||||
if (data->reset_stats) {
|
||||
req->reset_stats_valid = true;
|
||||
req->reset_stats = true;
|
||||
IPAWANDBG("fetch and reset the client stats\n");
|
||||
}
|
||||
|
||||
req->client_id = lan_clnt_idx1;
|
||||
req->src_pipe_id =
|
||||
rmnet_ipa3_ctx->tether_device[data->device_type].ul_src_pipe;
|
||||
|
||||
IPAWANDBG("fetch the client stats for %d, %d\n", req->client_id,
|
||||
req->src_pipe_id);
|
||||
|
||||
rc = ipa3_qmi_get_per_client_packet_stats(req, resp);
|
||||
if (rc) {
|
||||
IPAWANERR("can't get per client stats\n");
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
kfree(req);
|
||||
kfree(resp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (resp->per_client_stats_list_valid) {
|
||||
for (i = 0; i < resp->per_client_stats_list_len
|
||||
&& i < IPA_MAX_NUM_HW_PATH_CLIENTS; i++) {
|
||||
/* Subtract the header bytes from the DL bytes. */
|
||||
data->client_info[i].ipv4_rx_bytes =
|
||||
(resp->per_client_stats_list[i].num_dl_ipv4_bytes) -
|
||||
(rmnet_ipa3_ctx->
|
||||
tether_device[data->device_type].hdr_len *
|
||||
resp->per_client_stats_list[i].num_dl_ipv4_pkts);
|
||||
/* UL header bytes are subtracted by Q6. */
|
||||
data->client_info[i].ipv4_tx_bytes =
|
||||
resp->per_client_stats_list[i].num_ul_ipv4_bytes;
|
||||
/* Subtract the header bytes from the DL bytes. */
|
||||
data->client_info[i].ipv6_rx_bytes =
|
||||
(resp->per_client_stats_list[i].num_dl_ipv6_bytes) -
|
||||
(rmnet_ipa3_ctx->
|
||||
tether_device[data->device_type].hdr_len *
|
||||
resp->per_client_stats_list[i].num_dl_ipv6_pkts);
|
||||
/* UL header bytes are subtracted by Q6. */
|
||||
data->client_info[i].ipv6_tx_bytes =
|
||||
resp->per_client_stats_list[i].num_ul_ipv6_bytes;
|
||||
|
||||
IPAWANDBG("tx_b_v4(%lu)v6(%lu)rx_b_v4(%lu) v6(%lu)\n",
|
||||
(unsigned long int) data->client_info[i].ipv4_tx_bytes,
|
||||
(unsigned long int) data->client_info[i].ipv6_tx_bytes,
|
||||
(unsigned long int) data->client_info[i].ipv4_rx_bytes,
|
||||
(unsigned long int) data->client_info[i].ipv6_rx_bytes);
|
||||
|
||||
/* Get the lan client index. */
|
||||
lan_clnt_idx = resp->per_client_stats_list[i].client_id;
|
||||
/* Check if lan_clnt_idx is valid. */
|
||||
if (lan_clnt_idx < 0 ||
|
||||
lan_clnt_idx >= IPA_MAX_NUM_HW_PATH_CLIENTS) {
|
||||
IPAWANERR("Lan client index not valid.\n");
|
||||
mutex_unlock(
|
||||
&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
kfree(req);
|
||||
kfree(resp);
|
||||
ipa_assert();
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(data->client_info[i].mac,
|
||||
rmnet_ipa3_ctx->
|
||||
tether_device[data->device_type].
|
||||
lan_client[lan_clnt_idx].mac,
|
||||
IPA_MAC_ADDR_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
if (data->disconnect_clnt) {
|
||||
rmnet_ipa3_delete_lan_client_info(data->device_type,
|
||||
lan_clnt_idx1);
|
||||
}
|
||||
|
||||
mutex_unlock(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
kfree(req);
|
||||
kfree(resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init ipa3_wwan_init(void)
|
||||
{
|
||||
int i, j;
|
||||
rmnet_ipa3_ctx = kzalloc(sizeof(*rmnet_ipa3_ctx), GFP_KERNEL);
|
||||
if (!rmnet_ipa3_ctx) {
|
||||
IPAWANERR("no memory\n");
|
||||
|
@ -3330,6 +3816,14 @@ static int __init ipa3_wwan_init(void)
|
|||
|
||||
mutex_init(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
mutex_init(&rmnet_ipa3_ctx->add_mux_channel_lock);
|
||||
mutex_init(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
/* Reset the Lan Stats. */
|
||||
for (i = 0; i < IPACM_MAX_CLIENT_DEVICE_TYPES; i++) {
|
||||
rmnet_ipa3_ctx->tether_device[i].ul_src_pipe = -1;
|
||||
for (j = 0; j < IPA_MAX_NUM_HW_PATH_CLIENTS; j++)
|
||||
rmnet_ipa3_ctx->tether_device[i].
|
||||
lan_client[j].client_idx = -1;
|
||||
}
|
||||
rmnet_ipa3_ctx->ipa3_to_apps_hdl = -1;
|
||||
rmnet_ipa3_ctx->apps_to_ipa3_hdl = -1;
|
||||
|
||||
|
@ -3352,6 +3846,7 @@ static void __exit ipa3_wwan_cleanup(void)
|
|||
ipa3_qmi_cleanup();
|
||||
mutex_destroy(&rmnet_ipa3_ctx->pipe_handle_guard);
|
||||
mutex_destroy(&rmnet_ipa3_ctx->add_mux_channel_lock);
|
||||
mutex_destroy(&rmnet_ipa3_ctx->per_client_stats_guard);
|
||||
ret = subsys_notif_unregister_notifier(
|
||||
rmnet_ipa3_ctx->subsys_notify_handle, &ipa3_ssr_notifier);
|
||||
if (ret)
|
||||
|
|
|
@ -50,6 +50,15 @@
|
|||
#define WAN_IOC_QUERY_TETHER_STATS_ALL32 _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_QUERY_TETHER_STATS_ALL, \
|
||||
compat_uptr_t)
|
||||
#define WAN_IOCTL_ENABLE_PER_CLIENT_STATS32 _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_ENABLE_PER_CLIENT_STATS, \
|
||||
compat_uptr_t)
|
||||
#define WAN_IOCTL_QUERY_PER_CLIENT_STATS32 _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_QUERY_PER_CLIENT_STATS, \
|
||||
compat_uptr_t)
|
||||
#define WAN_IOCTL_SET_LAN_CLIENT_INFO32 _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_SET_LAN_CLIENT_INFO, \
|
||||
compat_uptr_t)
|
||||
#endif
|
||||
|
||||
static unsigned int dev_num = 1;
|
||||
|
@ -316,6 +325,122 @@ static long ipa3_wan_ioctl(struct file *filp,
|
|||
}
|
||||
break;
|
||||
|
||||
case WAN_IOC_ENABLE_PER_CLIENT_STATS:
|
||||
IPAWANDBG_LOW("got WAN_IOC_ENABLE_PER_CLIENT_STATS :>>>\n");
|
||||
pyld_sz = sizeof(bool);
|
||||
param = kzalloc(pyld_sz, GFP_KERNEL);
|
||||
if (!param) {
|
||||
retval = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
if (copy_from_user(param, (const void __user *)arg,
|
||||
pyld_sz)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rmnet_ipa3_enable_per_client_stats(
|
||||
(bool *)param)) {
|
||||
IPAWANERR("WAN_IOC_ENABLE_PER_CLIENT_STATS failed\n");
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case WAN_IOC_QUERY_PER_CLIENT_STATS:
|
||||
IPAWANDBG_LOW("got WAN_IOC_QUERY_PER_CLIENT_STATS :>>>\n");
|
||||
pyld_sz = sizeof(struct wan_ioctl_query_per_client_stats);
|
||||
param = kzalloc(pyld_sz, GFP_KERNEL);
|
||||
if (!param) {
|
||||
retval = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
if (copy_from_user(param, (const void __user *)arg,
|
||||
pyld_sz)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
retval = rmnet_ipa3_query_per_client_stats(
|
||||
(struct wan_ioctl_query_per_client_stats *)param);
|
||||
if (retval) {
|
||||
IPAWANERR("WAN_IOC_QUERY_PER_CLIENT_STATS failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *)arg, param, pyld_sz)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WAN_IOC_SET_LAN_CLIENT_INFO:
|
||||
IPAWANDBG_LOW("got WAN_IOC_SET_LAN_CLIENT_INFO :>>>\n");
|
||||
pyld_sz = sizeof(struct wan_ioctl_lan_client_info);
|
||||
param = kzalloc(pyld_sz, GFP_KERNEL);
|
||||
if (!param) {
|
||||
retval = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
if (copy_from_user(param, (const void __user *)arg,
|
||||
pyld_sz)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (rmnet_ipa3_set_lan_client_info(
|
||||
(struct wan_ioctl_lan_client_info *)param)) {
|
||||
IPAWANERR("WAN_IOC_SET_LAN_CLIENT_INFO failed\n");
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WAN_IOC_CLEAR_LAN_CLIENT_INFO:
|
||||
IPAWANDBG_LOW("got WAN_IOC_CLEAR_LAN_CLIENT_INFO :>>>\n");
|
||||
pyld_sz = sizeof(struct wan_ioctl_lan_client_info);
|
||||
param = kzalloc(pyld_sz, GFP_KERNEL);
|
||||
if (!param) {
|
||||
retval = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
if (copy_from_user(param, (const void __user *)arg,
|
||||
pyld_sz)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (rmnet_ipa3_clear_lan_client_info(
|
||||
(struct wan_ioctl_lan_client_info *)param)) {
|
||||
IPAWANERR("WAN_IOC_CLEAR_LAN_CLIENT_INFO failed\n");
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WAN_IOC_SEND_LAN_CLIENT_MSG:
|
||||
IPAWANDBG_LOW("got WAN_IOC_SEND_LAN_CLIENT_MSG :>>>\n");
|
||||
pyld_sz = sizeof(struct wan_ioctl_send_lan_client_msg);
|
||||
param = kzalloc(pyld_sz, GFP_KERNEL);
|
||||
if (!param) {
|
||||
retval = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
if (copy_from_user(param, (const void __user *)arg,
|
||||
pyld_sz)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (rmnet_ipa3_send_lan_client_msg(
|
||||
(struct wan_ioctl_send_lan_client_msg *)
|
||||
param)) {
|
||||
IPAWANERR("IOC_SEND_LAN_CLIENT_MSG failed\n");
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
retval = -ENOTTY;
|
||||
}
|
||||
|
|
|
@ -127,6 +127,17 @@
|
|||
*/
|
||||
#define IPA_WAN_MSG_IPv6_ADDR_GW_LEN 4
|
||||
|
||||
/**
|
||||
* max number of lan clients supported per device type
|
||||
* for LAN stats via HW.
|
||||
*/
|
||||
#define IPA_MAX_NUM_HW_PATH_CLIENTS 16
|
||||
|
||||
/**
|
||||
* max number of destination pipes possible for a client.
|
||||
*/
|
||||
#define QMI_IPA_MAX_CLIENT_DST_PIPES 4
|
||||
|
||||
/**
|
||||
* the attributes of the rule (routing or filtering)
|
||||
*/
|
||||
|
@ -447,7 +458,14 @@ enum ipa_vlan_l2tp_event {
|
|||
IPA_VLAN_L2TP_EVENT_MAX,
|
||||
};
|
||||
|
||||
#define IPA_EVENT_MAX_NUM (IPA_VLAN_L2TP_EVENT_MAX)
|
||||
enum ipa_per_client_stats_event {
|
||||
IPA_PER_CLIENT_STATS_CONNECT_EVENT = IPA_VLAN_L2TP_EVENT_MAX,
|
||||
IPA_PER_CLIENT_STATS_DISCONNECT_EVENT,
|
||||
IPA_PER_CLIENT_STATS_EVENT_MAX,
|
||||
IPA_EVENT_MAX_NUM = IPA_PER_CLIENT_STATS_EVENT_MAX,
|
||||
};
|
||||
|
||||
#define IPA_EVENT_MAX_NUM ((int)IPA_PER_CLIENT_STATS_EVENT_MAX)
|
||||
#define IPA_EVENT_MAX ((int)IPA_EVENT_MAX_NUM)
|
||||
|
||||
/**
|
||||
|
@ -1060,6 +1078,48 @@ struct ipa_rt_rule_del {
|
|||
int status;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ipa_rt_rule_add_ext - routing rule descriptor includes in
|
||||
* and out parameters
|
||||
* @rule: actual rule to be added
|
||||
* @at_rear: add at back of routing table, it is NOT possible to add rules at
|
||||
* the rear of the "default" routing tables
|
||||
* @rt_rule_hdl: output parameter, handle to rule, valid when status is 0
|
||||
* @status: output parameter, status of routing rule add operation,
|
||||
* @rule_id: rule_id to be assigned to the routing rule. In case client
|
||||
* specifies rule_id as 0 the driver will assign a new rule_id
|
||||
* 0 for success,
|
||||
* -1 for failure
|
||||
*/
|
||||
struct ipa_rt_rule_add_ext {
|
||||
struct ipa_rt_rule rule;
|
||||
uint8_t at_rear;
|
||||
uint32_t rt_rule_hdl;
|
||||
int status;
|
||||
uint16_t rule_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ipa_ioc_add_rt_rule - routing rule addition parameters (supports
|
||||
* multiple rules and commit with rule_id);
|
||||
*
|
||||
* all rules MUST be added to same table
|
||||
* @commit: should rules be written to IPA HW also?
|
||||
* @ip: IP family of rule
|
||||
* @rt_tbl_name: name of routing table resource
|
||||
* @num_rules: number of routing rules that follow
|
||||
* @ipa_rt_rule_add_ext rules: all rules need to go back to back here,
|
||||
* no pointers
|
||||
*/
|
||||
struct ipa_ioc_add_rt_rule_ext {
|
||||
uint8_t commit;
|
||||
enum ipa_ip_type ip;
|
||||
char rt_tbl_name[IPA_RESOURCE_NAME_MAX];
|
||||
uint8_t num_rules;
|
||||
struct ipa_rt_rule_add_ext rules[0];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct ipa_ioc_del_rt_rule - routing rule deletion parameters (supports
|
||||
* multiple headers and commit)
|
||||
|
@ -1619,6 +1679,52 @@ enum ipacm_client_enum {
|
|||
IPACM_CLIENT_WLAN,
|
||||
IPACM_CLIENT_MAX
|
||||
};
|
||||
|
||||
enum ipacm_per_client_device_type {
|
||||
IPACM_CLIENT_DEVICE_TYPE_USB = 0,
|
||||
IPACM_CLIENT_DEVICE_TYPE_WLAN = 1,
|
||||
IPACM_CLIENT_DEVICE_TYPE_ETH = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* max number of device types supported.
|
||||
*/
|
||||
#define IPACM_MAX_CLIENT_DEVICE_TYPES 3
|
||||
|
||||
/**
|
||||
* @lanIface - Name of the lan interface
|
||||
* @mac: Mac address of the client.
|
||||
*/
|
||||
struct ipa_lan_client_msg {
|
||||
char lanIface[IPA_RESOURCE_NAME_MAX];
|
||||
uint8_t mac[IPA_MAC_ADDR_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ipa_lan_client - lan client data
|
||||
* @mac: MAC Address of the client.
|
||||
* @client_idx: Client Index.
|
||||
* @inited: Bool to indicate whether client info is set.
|
||||
*/
|
||||
struct ipa_lan_client {
|
||||
uint8_t mac[IPA_MAC_ADDR_SIZE];
|
||||
int8_t client_idx;
|
||||
uint8_t inited;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ipa_tether_device_info - tether device info indicated from IPACM
|
||||
* @ul_src_pipe: Source pipe of the lan client.
|
||||
* @hdr_len: Header length of the client.
|
||||
* @num_clients: Number of clients connected.
|
||||
*/
|
||||
struct ipa_tether_device_info {
|
||||
int32_t ul_src_pipe;
|
||||
uint8_t hdr_len;
|
||||
uint32_t num_clients;
|
||||
struct ipa_lan_client lan_client[IPA_MAX_NUM_HW_PATH_CLIENTS];
|
||||
};
|
||||
|
||||
/**
|
||||
* actual IOCTLs supported by IPA driver
|
||||
*/
|
||||
|
@ -1631,6 +1737,9 @@ enum ipacm_client_enum {
|
|||
#define IPA_IOC_ADD_RT_RULE _IOWR(IPA_IOC_MAGIC, \
|
||||
IPA_IOCTL_ADD_RT_RULE, \
|
||||
struct ipa_ioc_add_rt_rule *)
|
||||
#define IPA_IOC_ADD_RT_RULE_EXT _IOWR(IPA_IOC_MAGIC, \
|
||||
IPA_IOCTL_ADD_RT_RULE_EXT, \
|
||||
struct ipa_ioc_add_rt_rule_ext *)
|
||||
#define IPA_IOC_ADD_RT_RULE_AFTER _IOWR(IPA_IOC_MAGIC, \
|
||||
IPA_IOCTL_ADD_RT_RULE_AFTER, \
|
||||
struct ipa_ioc_add_rt_rule_after *)
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
#define WAN_IOCTL_QUERY_DL_FILTER_STATS 8
|
||||
#define WAN_IOCTL_ADD_FLT_RULE_EX 9
|
||||
#define WAN_IOCTL_QUERY_TETHER_STATS_ALL 10
|
||||
#define WAN_IOCTL_ADD_UL_FLT_RULE 11
|
||||
#define WAN_IOCTL_ENABLE_PER_CLIENT_STATS 12
|
||||
#define WAN_IOCTL_QUERY_PER_CLIENT_STATS 13
|
||||
#define WAN_IOCTL_SET_LAN_CLIENT_INFO 14
|
||||
#define WAN_IOCTL_CLEAR_LAN_CLIENT_INFO 15
|
||||
#define WAN_IOCTL_SEND_LAN_CLIENT_MSG 16
|
||||
|
||||
/* User space may not have this defined. */
|
||||
#ifndef IFNAMSIZ
|
||||
|
@ -126,6 +132,57 @@ struct wan_ioctl_query_dl_filter_stats {
|
|||
uint32_t index;
|
||||
};
|
||||
|
||||
struct wan_ioctl_send_lan_client_msg {
|
||||
/* Lan client info. */
|
||||
struct ipa_lan_client_msg lan_client;
|
||||
/* Event to indicate whether client is
|
||||
* connected or disconnected.
|
||||
*/
|
||||
enum ipa_per_client_stats_event client_event;
|
||||
};
|
||||
|
||||
struct wan_ioctl_lan_client_info {
|
||||
/* Device type of the client. */
|
||||
enum ipacm_per_client_device_type device_type;
|
||||
/* MAC Address of the client. */
|
||||
uint8_t mac[IPA_MAC_ADDR_SIZE];
|
||||
/* Init client. */
|
||||
uint8_t client_init;
|
||||
/* Client Index */
|
||||
int8_t client_idx;
|
||||
/* Header length of the client. */
|
||||
uint8_t hdr_len;
|
||||
/* Source pipe of the lan client. */
|
||||
enum ipa_client_type ul_src_pipe;
|
||||
};
|
||||
|
||||
struct wan_ioctl_per_client_info {
|
||||
/* MAC Address of the client. */
|
||||
uint8_t mac[IPA_MAC_ADDR_SIZE];
|
||||
/* Ipv4 UL traffic bytes. */
|
||||
uint64_t ipv4_tx_bytes;
|
||||
/* Ipv4 DL traffic bytes. */
|
||||
uint64_t ipv4_rx_bytes;
|
||||
/* Ipv6 UL traffic bytes. */
|
||||
uint64_t ipv6_tx_bytes;
|
||||
/* Ipv6 DL traffic bytes. */
|
||||
uint64_t ipv6_rx_bytes;
|
||||
};
|
||||
|
||||
struct wan_ioctl_query_per_client_stats {
|
||||
/* Device type of the client. */
|
||||
enum ipacm_per_client_device_type device_type;
|
||||
/* Indicate whether to reset the stats (use 1) or not */
|
||||
uint8_t reset_stats;
|
||||
/* Indicates whether client is disconnected. */
|
||||
uint8_t disconnect_clnt;
|
||||
/* Number of clients. */
|
||||
uint8_t num_clients;
|
||||
/* Client information. */
|
||||
struct wan_ioctl_per_client_info
|
||||
client_info[IPA_MAX_NUM_HW_PATH_CLIENTS];
|
||||
};
|
||||
|
||||
#define WAN_IOC_ADD_FLT_RULE _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_ADD_FLT_RULE, \
|
||||
struct ipa_install_fltr_rule_req_msg_v01 *)
|
||||
|
@ -170,4 +227,27 @@ struct wan_ioctl_query_dl_filter_stats {
|
|||
WAN_IOCTL_QUERY_TETHER_STATS_ALL, \
|
||||
struct wan_ioctl_query_tether_stats_all *)
|
||||
|
||||
#define WAN_IOC_ADD_UL_FLT_RULE _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_ADD_UL_FLT_RULE, \
|
||||
struct ipa_configure_ul_firewall_rules_req_msg_v01 *)
|
||||
|
||||
#define WAN_IOC_ENABLE_PER_CLIENT_STATS _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_ENABLE_PER_CLIENT_STATS, \
|
||||
bool *)
|
||||
|
||||
#define WAN_IOC_QUERY_PER_CLIENT_STATS _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_QUERY_PER_CLIENT_STATS, \
|
||||
struct wan_ioctl_query_per_client_stats *)
|
||||
|
||||
#define WAN_IOC_SET_LAN_CLIENT_INFO _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_SET_LAN_CLIENT_INFO, \
|
||||
struct wan_ioctl_lan_client_info *)
|
||||
|
||||
#define WAN_IOC_SEND_LAN_CLIENT_MSG _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_SEND_LAN_CLIENT_MSG, \
|
||||
struct wan_ioctl_send_lan_client_msg *)
|
||||
|
||||
#define WAN_IOC_CLEAR_LAN_CLIENT_INFO _IOWR(WAN_IOC_MAGIC, \
|
||||
WAN_IOCTL_CLEAR_LAN_CLIENT_INFO, \
|
||||
struct wan_ioctl_lan_client_info *)
|
||||
#endif /* _RMNET_IPA_FD_IOCTL_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue