From 4df2e1c28e8e3baadd50bdafa40fb35ea99cc52f Mon Sep 17 00:00:00 2001
From: Murat Sezgin <msezgin@codeaurora.org>
Date: Fri, 26 Feb 2016 14:59:20 -0800
Subject: net: ppp: rx/tx error and dropped pkt stats support

ppp_update_stats functions accepts rx/tx errors and dropped
pkt stats args.

Change-Id: Iba2f6ea2114d8a4678254332fec0ef7bc35bed2c
Signed-off-by: ratheesh kannoth <rkannoth@codeaurora.org>
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
---
 drivers/net/ppp/ppp_generic.c |  8 +++++++-
 include/linux/ppp_channel.h   |  4 +++-
 net/l2tp/l2tp_core.c          | 24 ++++++++++++++++++++++++
 net/l2tp/l2tp_core.h          |  2 ++
 4 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 58b889e..9cf7fe3 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -3360,7 +3360,9 @@ static void *unit_find(struct idr *p, int n)
 /* Updates the PPP interface statistics. */
 void ppp_update_stats(struct net_device *dev, unsigned long rx_packets,
 		      unsigned long rx_bytes, unsigned long tx_packets,
-		      unsigned long tx_bytes)
+		      unsigned long tx_bytes, unsigned long rx_errors,
+		      unsigned long tx_errors, unsigned long rx_dropped,
+		      unsigned long tx_dropped)
 {
 	struct ppp *ppp;
 
@@ -3375,11 +3377,15 @@ void ppp_update_stats(struct net_device *dev, unsigned long rx_packets,
 	ppp_xmit_lock(ppp);
 	ppp->stats64.tx_packets += tx_packets;
 	ppp->stats64.tx_bytes += tx_bytes;
+	ppp->dev->stats.tx_errors += tx_errors;
+	ppp->dev->stats.tx_dropped += tx_dropped;
 	ppp_xmit_unlock(ppp);
 
 	ppp_recv_lock(ppp);
 	ppp->stats64.rx_packets += rx_packets;
 	ppp->stats64.rx_bytes += rx_bytes;
+	ppp->dev->stats.rx_errors += rx_errors;
+	ppp->dev->stats.rx_dropped += rx_dropped;
 	ppp_recv_unlock(ppp);
 }
 
diff --git a/include/linux/ppp_channel.h b/include/linux/ppp_channel.h
index db352ff..82d51537 100644
--- a/include/linux/ppp_channel.h
+++ b/include/linux/ppp_channel.h
@@ -82,7 +82,9 @@ extern int ppp_is_multilink(struct net_device *dev);
  */
 extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets,
 			     unsigned long rx_bytes, unsigned long tx_packets,
-			     unsigned long tx_bytes);
+			     unsigned long tx_bytes, unsigned long rx_errors,
+			     unsigned long tx_errors, unsigned long rx_dropped,
+			     unsigned long tx_dropped);
 
 /* Called by the channel when it can send some more data. */
 extern void ppp_output_wakeup(struct ppp_channel *);
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 425b95e..b098099 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -355,6 +355,30 @@ err_tlock:
 }
 EXPORT_SYMBOL_GPL(l2tp_session_register);
 
+void l2tp_stats_update(struct l2tp_tunnel *tunnel,
+		       struct l2tp_session *session,
+		       struct l2tp_stats *stats)
+{
+	atomic_long_add(atomic_long_read(&stats->rx_packets),
+			&tunnel->stats.rx_packets);
+	atomic_long_add(atomic_long_read(&stats->rx_bytes),
+			&tunnel->stats.rx_bytes);
+	atomic_long_add(atomic_long_read(&stats->tx_packets),
+			&tunnel->stats.tx_packets);
+	atomic_long_add(atomic_long_read(&stats->tx_bytes),
+			&tunnel->stats.tx_bytes);
+
+	atomic_long_add(atomic_long_read(&stats->rx_packets),
+			&session->stats.rx_packets);
+	atomic_long_add(atomic_long_read(&stats->rx_bytes),
+			&session->stats.rx_bytes);
+	atomic_long_add(atomic_long_read(&stats->tx_packets),
+			&session->stats.tx_packets);
+	atomic_long_add(atomic_long_read(&stats->tx_bytes),
+			&session->stats.tx_bytes);
+}
+EXPORT_SYMBOL_GPL(l2tp_stats_update);
+
 /*****************************************************************************
  * Receive data handling
  *****************************************************************************/
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 2db3d50..5cc42a4 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -200,6 +200,8 @@ struct l2tp_session *l2tp_session_get(const struct net *net, u32 session_id);
 struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth);
 struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
 						const char *ifname);
+void l2tp_stats_update(struct l2tp_tunnel *tunnel, struct l2tp_session *session,
+		       struct l2tp_stats *stats);
 
 int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id,
 		       u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg,
-- 
cgit v1.1

