summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c3
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.h3
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_utils.c2
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c103
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/rmnet_ipa_fd_ioctl.c30
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c3
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h3
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_utils.c2
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c99
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c31
-rw-r--r--include/uapi/linux/msm_ipa.h14
-rw-r--r--include/uapi/linux/rmnet_ipa_fd_ioctl.h17
12 files changed, 292 insertions, 18 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
index e48c19c522a7..cb95f6e98956 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
@@ -80,6 +80,9 @@ const char *ipa_event_name[] = {
__stringify(ECM_DISCONNECT),
__stringify(IPA_TETHERING_STATS_UPDATE_STATS),
__stringify(IPA_TETHERING_STATS_UPDATE_NETWORK_STATS),
+ __stringify(IPA_QUOTA_REACH),
+ __stringify(IPA_SSR_BEFORE_SHUTDOWN),
+ __stringify(IPA_SSR_AFTER_POWERUP),
};
const char *ipa_hdr_l2_type_name[] = {
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.h b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.h
index 96554af9aefd..1f5d619ef573 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.h
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.h
@@ -177,6 +177,9 @@ int rmnet_ipa_set_tether_client_pipe(struct wan_ioctl_set_tether_client_pipe
int rmnet_ipa_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
bool reset);
+int rmnet_ipa_query_tethering_stats_all(
+ struct wan_ioctl_query_tether_stats_all *data);
+
int rmnet_ipa_reset_tethering_stats(struct wan_ioctl_reset_tether_stats *data);
int ipa_qmi_get_data_stats(struct ipa_get_data_stats_req_msg_v01 *req,
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
index d53121292c03..be3c890db25c 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
@@ -946,7 +946,7 @@ int ipa2_get_ep_mapping(enum ipa_client_type client)
void ipa2_set_client(int index, enum ipacm_client_enum client, bool uplink)
{
- if (client >= IPACM_CLIENT_MAX || client < IPACM_CLIENT_USB) {
+ if (client > IPACM_CLIENT_MAX || client < IPACM_CLIENT_USB) {
IPAERR("Bad client number! client =%d\n", client);
} else if (index >= IPA_MAX_NUM_PIPES || index < 0) {
IPAERR("Bad pipe index! index =%d\n", index);
diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
index 774077494ea5..da014427852b 100644
--- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
@@ -2334,6 +2334,29 @@ static struct platform_driver rmnet_ipa_driver = {
.remove = ipa_wwan_remove,
};
+/**
+ * rmnet_ipa_send_ssr_notification(bool ssr_done) - send SSR notification
+ *
+ * This function sends the SSR notification before modem shutdown and
+ * after_powerup from SSR framework, to user-space module
+ */
+static void rmnet_ipa_send_ssr_notification(bool ssr_done)
+{
+ struct ipa_msg_meta msg_meta;
+ int rc;
+
+ memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
+ if (ssr_done)
+ msg_meta.msg_type = IPA_SSR_AFTER_POWERUP;
+ else
+ msg_meta.msg_type = IPA_SSR_BEFORE_SHUTDOWN;
+ rc = ipa_send_msg(&msg_meta, NULL, NULL);
+ if (rc) {
+ IPAWANERR("ipa_send_msg failed: %d\n", rc);
+ return;
+ }
+}
+
static int ssr_notifier_cb(struct notifier_block *this,
unsigned long code,
void *data)
@@ -2341,6 +2364,8 @@ static int ssr_notifier_cb(struct notifier_block *this,
if (ipa_rmnet_ctx.ipa_rmnet_ssr) {
if (SUBSYS_BEFORE_SHUTDOWN == code) {
pr_info("IPA received MPSS BEFORE_SHUTDOWN\n");
+ /* send SSR before-shutdown notification to IPACM */
+ rmnet_ipa_send_ssr_notification(false);
atomic_set(&is_ssr, 1);
ipa_q6_pre_shutdown_cleanup();
if (ipa_netdevs[0])
@@ -2517,6 +2542,26 @@ static void rmnet_ipa_get_network_stats_and_update(void)
}
/**
+ * rmnet_ipa_send_quota_reach_ind() - send quota_reach notification from
+ * IPA Modem
+ * This function sends the quota_reach indication from the IPA Modem driver
+ * via QMI, to user-space module
+ */
+static void rmnet_ipa_send_quota_reach_ind(void)
+{
+ struct ipa_msg_meta msg_meta;
+ int rc;
+
+ memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
+ msg_meta.msg_type = IPA_QUOTA_REACH;
+ rc = ipa_send_msg(&msg_meta, NULL, NULL);
+ if (rc) {
+ IPAWANERR("ipa_send_msg failed: %d\n", rc);
+ return;
+ }
+}
+
+/**
* rmnet_ipa_poll_tethering_stats() - Tethering stats polling IOCTL handler
* @data - IOCTL data
*
@@ -2796,7 +2841,7 @@ int rmnet_ipa_query_tethering_stats_modem(
IPAWANERR("reset the pipe stats\n");
} else {
/* print tethered-client enum */
- IPAWANDBG_LOW("Tethered-client enum(%d)\n", data->ipa_client);
+ IPAWANDBG("Tethered-client enum(%d)\n", data->ipa_client);
}
rc = ipa_qmi_get_data_stats(req, resp);
@@ -2805,10 +2850,6 @@ int rmnet_ipa_query_tethering_stats_modem(
kfree(req);
kfree(resp);
return rc;
- } else if (reset) {
- kfree(req);
- kfree(resp);
- return 0;
}
if (resp->dl_dst_pipe_stats_list_valid) {
@@ -2854,7 +2895,7 @@ int rmnet_ipa_query_tethering_stats_modem(
}
}
}
- IPAWANDBG_LOW("v4_rx_p(%lu) v6_rx_p(%lu) v4_rx_b(%lu) v6_rx_b(%lu)\n",
+ IPAWANDBG("v4_rx_p(%lu) v6_rx_p(%lu) v4_rx_b(%lu) v6_rx_b(%lu)\n",
(unsigned long int) data->ipv4_rx_packets,
(unsigned long int) data->ipv6_rx_packets,
(unsigned long int) data->ipv4_rx_bytes,
@@ -2904,7 +2945,7 @@ int rmnet_ipa_query_tethering_stats_modem(
}
}
}
- IPAWANDBG_LOW("tx_p_v4(%lu)v6(%lu)tx_b_v4(%lu) v6(%lu)\n",
+ IPAWANDBG("tx_p_v4(%lu)v6(%lu)tx_b_v4(%lu) v6(%lu)\n",
(unsigned long int) data->ipv4_tx_packets,
(unsigned long int) data->ipv6_tx_packets,
(unsigned long int) data->ipv4_tx_bytes,
@@ -2946,6 +2987,49 @@ int rmnet_ipa_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
return rc;
}
+int rmnet_ipa_query_tethering_stats_all(
+ struct wan_ioctl_query_tether_stats_all *data)
+{
+ struct wan_ioctl_query_tether_stats tether_stats;
+ enum ipa_upstream_type upstream_type;
+ int rc = 0;
+
+ memset(&tether_stats, 0, sizeof(struct wan_ioctl_query_tether_stats));
+ /* get IPA backhaul type */
+ upstream_type = find_upstream_type(data->upstreamIface);
+
+ if (upstream_type == IPA_UPSTEAM_MAX) {
+ IPAWANERR(" Wrong upstreamIface name %s\n",
+ data->upstreamIface);
+ } else if (upstream_type == IPA_UPSTEAM_WLAN) {
+ IPAWANDBG_LOW(" query wifi-backhaul stats\n");
+ rc = rmnet_ipa_query_tethering_stats_wifi(
+ &tether_stats, data->reset_stats);
+ if (rc) {
+ IPAWANERR("wlan WAN_IOC_QUERY_TETHER_STATS failed\n");
+ return rc;
+ }
+ data->tx_bytes = tether_stats.ipv4_tx_bytes
+ + tether_stats.ipv6_tx_bytes;
+ data->rx_bytes = tether_stats.ipv4_rx_bytes
+ + tether_stats.ipv6_rx_bytes;
+ } else {
+ IPAWANDBG_LOW(" query modem-backhaul stats\n");
+ tether_stats.ipa_client = data->ipa_client;
+ rc = rmnet_ipa_query_tethering_stats_modem(
+ &tether_stats, data->reset_stats);
+ if (rc) {
+ IPAWANERR("modem WAN_IOC_QUERY_TETHER_STATS failed\n");
+ return rc;
+ }
+ data->tx_bytes = tether_stats.ipv4_tx_bytes
+ + tether_stats.ipv6_tx_bytes;
+ data->rx_bytes = tether_stats.ipv4_rx_bytes
+ + tether_stats.ipv6_rx_bytes;
+ }
+ return rc;
+}
+
int rmnet_ipa_reset_tethering_stats(struct wan_ioctl_reset_tether_stats *data)
{
enum ipa_upstream_type upstream_type;
@@ -3047,6 +3131,8 @@ void ipa_broadcast_quota_reach_ind(u32 mux_id,
IPAWANERR("putting nlmsg: <%s> <%s> <%s>\n",
alert_msg, iface_name_l, iface_name_m);
kobject_uevent_env(&(ipa_netdevs[0]->dev.kobj), KOBJ_CHANGE, envp);
+
+ rmnet_ipa_send_quota_reach_ind();
}
/**
@@ -3071,6 +3157,9 @@ void ipa_q6_handshake_complete(bool ssr_bootup)
*/
ipa2_proxy_clk_unvote();
+ /* send SSR power-up notification to IPACM */
+ rmnet_ipa_send_ssr_notification(true);
+
/*
* It is required to recover the network stats after
* SSR recovery
diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa_fd_ioctl.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa_fd_ioctl.c
index 46bfe021eb4b..02bdd0334e7f 100644
--- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa_fd_ioctl.c
+++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa_fd_ioctl.c
@@ -47,6 +47,10 @@
#define WAN_IOC_QUERY_DL_FILTER_STATS32 _IOWR(WAN_IOC_MAGIC, \
WAN_IOCTL_QUERY_DL_FILTER_STATS, \
compat_uptr_t)
+#define WAN_IOC_QUERY_TETHER_STATS_ALL32 _IOWR(WAN_IOC_MAGIC, \
+ WAN_IOCTL_QUERY_TETHER_STATS_ALL, \
+ compat_uptr_t)
+
#endif
static unsigned int dev_num = 1;
@@ -238,6 +242,32 @@ static long wan_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
break;
+ case WAN_IOC_QUERY_TETHER_STATS_ALL:
+ IPAWANDBG_LOW("got WAN_IOC_QUERY_TETHER_STATS_ALL :>>>\n");
+ pyld_sz = sizeof(struct wan_ioctl_query_tether_stats_all);
+ param = kzalloc(pyld_sz, GFP_KERNEL);
+ if (!param) {
+ retval = -ENOMEM;
+ break;
+ }
+ if (copy_from_user(param, (u8 *)arg, pyld_sz)) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (rmnet_ipa_query_tethering_stats_all(
+ (struct wan_ioctl_query_tether_stats_all *)param)) {
+ IPAWANERR("WAN_IOC_QUERY_TETHER_STATS failed\n");
+ retval = -EFAULT;
+ break;
+ }
+
+ if (copy_to_user((u8 *)arg, param, pyld_sz)) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
+
case WAN_IOC_RESET_TETHER_STATS:
IPAWANDBG_LOW("got WAN_IOC_RESET_TETHER_STATS :>>>\n");
pyld_sz = sizeof(struct wan_ioctl_reset_tether_stats);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
index 72eb3808c7a4..fbf84ab7d2d4 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
@@ -61,6 +61,9 @@ const char *ipa3_event_name[] = {
__stringify(ECM_DISCONNECT),
__stringify(IPA_TETHERING_STATS_UPDATE_STATS),
__stringify(IPA_TETHERING_STATS_UPDATE_NETWORK_STATS),
+ __stringify(IPA_QUOTA_REACH),
+ __stringify(IPA_SSR_BEFORE_SHUTDOWN),
+ __stringify(IPA_SSR_AFTER_POWERUP),
};
const char *ipa3_hdr_l2_type_name[] = {
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
index 6cd82f84bf13..d5d850309696 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
@@ -190,6 +190,9 @@ int rmnet_ipa3_set_tether_client_pipe(struct wan_ioctl_set_tether_client_pipe
int rmnet_ipa3_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
bool reset);
+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 ipa3_qmi_get_data_stats(struct ipa_get_data_stats_req_msg_v01 *req,
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 5ffc1f23f47c..d19de2a7bdb5 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -1002,7 +1002,7 @@ u8 ipa3_get_qmb_master_sel(enum ipa_client_type client)
void ipa3_set_client(int index, enum ipacm_client_enum client, bool uplink)
{
- if (client >= IPACM_CLIENT_MAX || client < IPACM_CLIENT_USB) {
+ if (client > IPACM_CLIENT_MAX || client < IPACM_CLIENT_USB) {
IPAERR("Bad client number! client =%d\n", client);
} else if (index >= IPA3_MAX_NUM_PIPES || index < 0) {
IPAERR("Bad pipe index! index =%d\n", index);
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index 04e5862cd960..1bd4f7fda1b7 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -2455,6 +2455,29 @@ static struct platform_driver rmnet_ipa_driver = {
.remove = ipa3_wwan_remove,
};
+/**
+ * rmnet_ipa_send_ssr_notification(bool ssr_done) - send SSR notification
+ *
+ * This function sends the SSR notification before modem shutdown and
+ * after_powerup from SSR framework, to user-space module
+ */
+static void rmnet_ipa_send_ssr_notification(bool ssr_done)
+{
+ struct ipa_msg_meta msg_meta;
+ int rc;
+
+ memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
+ if (ssr_done)
+ msg_meta.msg_type = IPA_SSR_AFTER_POWERUP;
+ else
+ msg_meta.msg_type = IPA_SSR_BEFORE_SHUTDOWN;
+ rc = ipa_send_msg(&msg_meta, NULL, NULL);
+ if (rc) {
+ IPAWANERR("ipa_send_msg failed: %d\n", rc);
+ return;
+ }
+}
+
static int ipa3_ssr_notifier_cb(struct notifier_block *this,
unsigned long code,
void *data)
@@ -2465,6 +2488,8 @@ static int ipa3_ssr_notifier_cb(struct notifier_block *this,
switch (code) {
case SUBSYS_BEFORE_SHUTDOWN:
IPAWANINFO("IPA received MPSS BEFORE_SHUTDOWN\n");
+ /* send SSR before-shutdown notification to IPACM */
+ rmnet_ipa_send_ssr_notification(false);
atomic_set(&rmnet_ipa3_ctx->is_ssr, 1);
ipa3_q6_pre_shutdown_cleanup();
if (IPA_NETDEV())
@@ -2641,6 +2666,26 @@ static void rmnet_ipa_get_network_stats_and_update(void)
}
/**
+ * rmnet_ipa_send_quota_reach_ind() - send quota_reach notification from
+ * IPA Modem
+ * This function sends the quota_reach indication from the IPA Modem driver
+ * via QMI, to user-space module
+ */
+static void rmnet_ipa_send_quota_reach_ind(void)
+{
+ struct ipa_msg_meta msg_meta;
+ int rc;
+
+ memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
+ msg_meta.msg_type = IPA_QUOTA_REACH;
+ rc = ipa_send_msg(&msg_meta, NULL, NULL);
+ if (rc) {
+ IPAWANERR("ipa_send_msg failed: %d\n", rc);
+ return;
+ }
+}
+
+/**
* rmnet_ipa3_poll_tethering_stats() - Tethering stats polling IOCTL handler
* @data - IOCTL data
*
@@ -2921,7 +2966,7 @@ static int rmnet_ipa3_query_tethering_stats_modem(
IPAWANERR("reset the pipe stats\n");
} else {
/* print tethered-client enum */
- IPAWANDBG_LOW("Tethered-client enum(%d)\n", data->ipa_client);
+ IPAWANDBG("Tethered-client enum(%d)\n", data->ipa_client);
}
rc = ipa3_qmi_get_data_stats(req, resp);
@@ -2930,10 +2975,6 @@ static int rmnet_ipa3_query_tethering_stats_modem(
kfree(req);
kfree(resp);
return rc;
- } else if (reset) {
- kfree(req);
- kfree(resp);
- return 0;
}
if (resp->dl_dst_pipe_stats_list_valid) {
@@ -3071,6 +3112,49 @@ int rmnet_ipa3_query_tethering_stats(struct wan_ioctl_query_tether_stats *data,
return rc;
}
+int rmnet_ipa3_query_tethering_stats_all(
+ struct wan_ioctl_query_tether_stats_all *data)
+{
+ struct wan_ioctl_query_tether_stats tether_stats;
+ enum ipa_upstream_type upstream_type;
+ int rc = 0;
+
+ memset(&tether_stats, 0, sizeof(struct wan_ioctl_query_tether_stats));
+ /* get IPA backhaul type */
+ upstream_type = find_upstream_type(data->upstreamIface);
+
+ if (upstream_type == IPA_UPSTEAM_MAX) {
+ IPAWANERR(" Wrong upstreamIface name %s\n",
+ data->upstreamIface);
+ } else if (upstream_type == IPA_UPSTEAM_WLAN) {
+ IPAWANDBG_LOW(" query wifi-backhaul stats\n");
+ rc = rmnet_ipa3_query_tethering_stats_wifi(
+ &tether_stats, data->reset_stats);
+ if (rc) {
+ IPAWANERR("wlan WAN_IOC_QUERY_TETHER_STATS failed\n");
+ return rc;
+ }
+ data->tx_bytes = tether_stats.ipv4_tx_bytes
+ + tether_stats.ipv6_tx_bytes;
+ data->rx_bytes = tether_stats.ipv4_rx_bytes
+ + tether_stats.ipv6_rx_bytes;
+ } else {
+ IPAWANDBG_LOW(" query modem-backhaul stats\n");
+ tether_stats.ipa_client = data->ipa_client;
+ rc = rmnet_ipa3_query_tethering_stats_modem(
+ &tether_stats, data->reset_stats);
+ if (rc) {
+ IPAWANERR("modem WAN_IOC_QUERY_TETHER_STATS failed\n");
+ return rc;
+ }
+ data->tx_bytes = tether_stats.ipv4_tx_bytes
+ + tether_stats.ipv6_tx_bytes;
+ data->rx_bytes = tether_stats.ipv4_rx_bytes
+ + tether_stats.ipv6_rx_bytes;
+ }
+ return rc;
+}
+
int rmnet_ipa3_reset_tethering_stats(struct wan_ioctl_reset_tether_stats *data)
{
enum ipa_upstream_type upstream_type;
@@ -3168,6 +3252,8 @@ void ipa3_broadcast_quota_reach_ind(u32 mux_id,
alert_msg, iface_name_l, iface_name_m);
kobject_uevent_env(&(IPA_NETDEV()->dev.kobj),
KOBJ_CHANGE, envp);
+
+ rmnet_ipa_send_quota_reach_ind();
}
/**
@@ -3192,6 +3278,9 @@ void ipa3_q6_handshake_complete(bool ssr_bootup)
*/
ipa3_proxy_clk_unvote();
+ /* send SSR power-up notification to IPACM */
+ rmnet_ipa_send_ssr_notification(true);
+
/*
* It is required to recover the network stats after
* SSR recovery
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
index ffd127a21ed1..51bbec464e4d 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, 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
@@ -47,6 +47,9 @@
#define WAN_IOC_QUERY_DL_FILTER_STATS32 _IOWR(WAN_IOC_MAGIC, \
WAN_IOCTL_QUERY_DL_FILTER_STATS, \
compat_uptr_t)
+#define WAN_IOC_QUERY_TETHER_STATS_ALL32 _IOWR(WAN_IOC_MAGIC, \
+ WAN_IOCTL_QUERY_TETHER_STATS_ALL, \
+ compat_uptr_t)
#endif
static unsigned int dev_num = 1;
@@ -265,6 +268,32 @@ static long ipa3_wan_ioctl(struct file *filp,
}
break;
+ case WAN_IOC_QUERY_TETHER_STATS_ALL:
+ IPAWANDBG_LOW("got WAN_IOC_QUERY_TETHER_STATS_ALL :>>>\n");
+ pyld_sz = sizeof(struct wan_ioctl_query_tether_stats_all);
+ param = kzalloc(pyld_sz, GFP_KERNEL);
+ if (!param) {
+ retval = -ENOMEM;
+ break;
+ }
+ if (copy_from_user(param, (u8 *)arg, pyld_sz)) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (rmnet_ipa3_query_tethering_stats_all(
+ (struct wan_ioctl_query_tether_stats_all *)param)) {
+ IPAWANERR("WAN_IOC_QUERY_TETHER_STATS failed\n");
+ retval = -EFAULT;
+ break;
+ }
+
+ if (copy_to_user((u8 *)arg, param, pyld_sz)) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
+
case WAN_IOC_RESET_TETHER_STATS:
IPAWANDBG_LOW("device %s got WAN_IOC_RESET_TETHER_STATS :>>>\n",
DRIVER_NAME);
diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h
index 16e4b8e30b07..51569b7e7aa0 100644
--- a/include/uapi/linux/msm_ipa.h
+++ b/include/uapi/linux/msm_ipa.h
@@ -394,10 +394,20 @@ enum ipa_tethering_stats_event {
IPA_TETHERING_STATS_UPDATE_STATS = IPA_ECM_EVENT_MAX,
IPA_TETHERING_STATS_UPDATE_NETWORK_STATS,
IPA_TETHERING_STATS_EVENT_MAX,
- IPA_EVENT_MAX_NUM = IPA_TETHERING_STATS_EVENT_MAX
};
-#define IPA_EVENT_MAX ((int)IPA_EVENT_MAX_NUM)
+enum ipa_quota_event {
+ IPA_QUOTA_REACH = IPA_TETHERING_STATS_EVENT_MAX,
+ IPA_QUOTA_EVENT_MAX,
+};
+
+enum ipa_ssr_event {
+ IPA_SSR_BEFORE_SHUTDOWN = IPA_QUOTA_EVENT_MAX,
+ IPA_SSR_AFTER_POWERUP,
+ IPA_SSR_EVENT_MAX
+};
+
+#define IPA_EVENT_MAX_NUM ((int)IPA_SSR_EVENT_MAX)
/**
* enum ipa_rm_resource_name - IPA RM clients identification names
diff --git a/include/uapi/linux/rmnet_ipa_fd_ioctl.h b/include/uapi/linux/rmnet_ipa_fd_ioctl.h
index 228bfe8274c6..f04ac495a5c0 100644
--- a/include/uapi/linux/rmnet_ipa_fd_ioctl.h
+++ b/include/uapi/linux/rmnet_ipa_fd_ioctl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, 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
@@ -32,6 +32,7 @@
#define WAN_IOCTL_RESET_TETHER_STATS 7
#define WAN_IOCTL_QUERY_DL_FILTER_STATS 8
#define WAN_IOCTL_ADD_FLT_RULE_EX 9
+#define WAN_IOCTL_QUERY_TETHER_STATS_ALL 10
/* User space may not have this defined. */
#ifndef IFNAMSIZ
@@ -99,6 +100,16 @@ struct wan_ioctl_query_tether_stats {
uint64_t ipv6_rx_bytes;
};
+struct wan_ioctl_query_tether_stats_all {
+ /* Name of the upstream interface */
+ char upstreamIface[IFNAMSIZ];
+ /* enum of tether interface */
+ enum ipacm_client_enum ipa_client;
+ uint8_t reset_stats;
+ uint64_t tx_bytes;
+ uint64_t rx_bytes;
+};
+
struct wan_ioctl_reset_tether_stats {
/* Name of the upstream interface, not support now */
char upstreamIface[IFNAMSIZ];
@@ -155,4 +166,8 @@ struct wan_ioctl_query_dl_filter_stats {
WAN_IOCTL_ADD_FLT_RULE_EX, \
struct ipa_install_fltr_rule_req_ex_msg_v01 *)
+#define WAN_IOC_QUERY_TETHER_STATS_ALL _IOWR(WAN_IOC_MAGIC, \
+ WAN_IOCTL_QUERY_TETHER_STATS_ALL, \
+ struct wan_ioctl_query_tether_stats_all *)
+
#endif /* _RMNET_IPA_FD_IOCTL_H */