From 5c855c53a83d2120f8f878f3adcb997418a3839b Mon Sep 17 00:00:00 2001
From: Aastha Mehta <aasthakm@mpi-sws.org>
Date: Sun, 9 Sep 2018 13:50:53 +0000
Subject: [PATCH] interceptions in nic driver to track tx pkts xmitted

---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h   |  1 +
 .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.h   | 17 +++++++++++
 .../net/ethernet/broadcom/bnx2x/bnx2x_main.c  |  1 +
 .../net/ethernet/broadcom/bnx2x/sme/xen_sme.c | 28 +++++++++++++++++++
 .../net/ethernet/broadcom/bnx2x/sme/xen_sme.h |  6 +++-
 .../broadcom/bnx2x/sme/xen_sme_hooks.c        | 15 ++++++++++
 .../broadcom/bnx2x/sme/xen_sme_hooks.h        |  2 ++
 7 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 153f68fd1..038514c1a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -520,6 +520,7 @@ struct bnx2x_fp_txdata {
 #ifdef CONFIG_XEN_SME
   u16     swi_tx_pkt_prod;
   u16     swi_tx_bd_prod;
+  u32     tx_used;
 #endif
 	unsigned long		tx_pkt;
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 156e054f2..1d2d5ebcb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -768,8 +768,17 @@ static inline u16 bnx2x_tx_avail(struct bnx2x *bp,
 	prod = txdata->tx_bd_prod;
 	cons = txdata->tx_bd_cons;
 
+#if CONFIG_XEN_SME
+  used = (s16) xsl_intercept_tx_avail(bp, txdata);
+  if (used < 0) {
+#endif
+
 	used = SUB_S16(prod, cons);
 
+#if CONFIG_XEN_SME
+  }
+#endif
+
 #ifdef BNX2X_STOP_ON_ERROR
 	WARN_ON(used < 0);
 	WARN_ON(used > txdata->tx_ring_size);
@@ -782,9 +791,17 @@ static inline u16 bnx2x_tx_avail(struct bnx2x *bp,
 static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata)
 {
 	u16 hw_cons;
+#if CONFIG_XEN_SME
+  int ret = 0;
+#endif
 
 	/* Tell compiler that status block fields can change */
 	barrier();
+#if CONFIG_XEN_SME
+  ret = xsl_intercept_tx_queue_has_work(txdata);
+  if (ret >= 0)
+    return ret;
+#endif
 	hw_cons = le16_to_cpu(*txdata->tx_cons_sb);
 	return hw_cons != txdata->tx_pkt_cons;
 }
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index e26e2cccb..d0c0cfc2c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -6455,6 +6455,7 @@ static void bnx2x_init_tx_ring_one(struct bnx2x_fp_txdata *txdata)
 #ifdef CONFIG_XEN_SME
   txdata->swi_tx_pkt_prod = 0;
   txdata->swi_tx_bd_prod = 0;
+  txdata->tx_used = 0;
 #endif
 }
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme.c b/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme.c
index f98fd0401..b47fb6f0a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme.c
@@ -142,6 +142,32 @@ sme_intercept_free_tx_skbs_queue(struct bnx2x_fastpath *fp)
   }
 }
 
+int
+(*lnk_intercept_tx_avail) (struct bnx2x *bp, struct bnx2x_fp_txdata *txdata) = 0;
+EXPORT_SYMBOL(lnk_intercept_tx_avail);
+static int
+sme_intercept_tx_avail(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata)
+{
+  if (lnk_intercept_tx_avail) {
+    return lnk_intercept_tx_avail(bp, txdata);
+  }
+
+  return -1;
+}
+
+int
+(*lnk_intercept_tx_queue_has_work) (struct bnx2x_fp_txdata *txdata) = 0;
+EXPORT_SYMBOL(lnk_intercept_tx_queue_has_work);
+static int
+sme_intercept_tx_queue_has_work(struct bnx2x_fp_txdata *txdata)
+{
+  if (lnk_intercept_tx_queue_has_work) {
+    return lnk_intercept_tx_queue_has_work(txdata);
+  }
+
+  return -1;
+}
+
 void
 (*lnk_parse_rx_data) (void *dev, int fp_idx, uint16_t rx_bd_prod,
 		uint16_t rx_bd_cons, uint16_t comp_prod, uint16_t comp_cons,
@@ -224,6 +250,8 @@ struct sme_hook_list xen_sme_hooks[NUM_XEN_SME_HOOKS] = {
   SME_HOOK_INIT(intercept_xmit_stop_queue, sme_intercept_xmit_stop_queue),
   SME_HOOK_INIT(intercept_tx_int, sme_intercept_tx_int),
   SME_HOOK_INIT(intercept_free_tx_skbs_queue, sme_intercept_free_tx_skbs_queue),
+  SME_HOOK_INIT(intercept_tx_avail, sme_intercept_tx_avail),
+  SME_HOOK_INIT(intercept_tx_queue_has_work, sme_intercept_tx_queue_has_work),
 	SME_HOOK_INIT(parse_rx_data, sme_parse_rx_data),
 	SME_HOOK_INIT(print_sk_buff, sme_print_sk_buff),
 	SME_HOOK_INIT(intercept_rx_path, sme_intercept_rx_path),
diff --git a/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme.h b/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme.h
index 63beb1fb8..2390535ff 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme.h
@@ -42,6 +42,8 @@ union sme_list_options {
       struct netdev_queue *txq, struct bnx2x_fp_txdata *txdata);
   int (*intercept_tx_int) (struct net_device *dev, struct bnx2x_fp_txdata *txdata);
   void (*intercept_free_tx_skbs_queue) (struct bnx2x_fastpath *fp);
+  int (*intercept_tx_avail) (struct bnx2x *bp, struct bnx2x_fp_txdata *txdata);
+  int (*intercept_tx_queue_has_work) (struct bnx2x_fp_txdata *txdata);
 	void (*parse_rx_data) (void *dev, int fp_idx, uint16_t rx_bd_prod,
 			uint16_t rx_bd_cons, uint16_t comp_prod, uint16_t comp_cons,
 			char *data, int data_len, char *extra_dbg_string);
@@ -65,6 +67,8 @@ struct sme_hook_heads {
   struct list_head intercept_xmit_stop_queue;
   struct list_head intercept_tx_int;
   struct list_head intercept_free_tx_skbs_queue;
+  struct list_head intercept_tx_avail;
+  struct list_head intercept_tx_queue_has_work;
 	struct list_head parse_rx_data;
 	struct list_head print_sk_buff;
 	struct list_head intercept_rx_path;
@@ -82,7 +86,7 @@ struct sme_hook_list {
 { .head = &xen_sme_hook_heads.HEAD, .hook = { . HEAD = HOOK } }
 
 // increment this every time a new hook is added
-#define NUM_XEN_SME_HOOKS 13
+#define NUM_XEN_SME_HOOKS 15
 
 extern struct sme_hook_heads xen_sme_hook_heads;
 extern struct sme_hook_list xen_sme_hooks[NUM_XEN_SME_HOOKS];
diff --git a/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme_hooks.c b/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme_hooks.c
index d29e3afa1..fb3b60f98 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme_hooks.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme_hooks.c
@@ -49,6 +49,9 @@ struct sme_hook_heads xen_sme_hook_heads = {
   .intercept_tx_int = LIST_HEAD_INIT(xen_sme_hook_heads.intercept_tx_int),
   .intercept_free_tx_skbs_queue =
     LIST_HEAD_INIT(xen_sme_hook_heads.intercept_free_tx_skbs_queue),
+  .intercept_tx_avail = LIST_HEAD_INIT(xen_sme_hook_heads.intercept_tx_avail),
+  .intercept_tx_queue_has_work =
+    LIST_HEAD_INIT(xen_sme_hook_heads.intercept_tx_queue_has_work),
 	.parse_rx_data = LIST_HEAD_INIT(xen_sme_hook_heads.parse_rx_data),
 	.print_sk_buff = LIST_HEAD_INIT(xen_sme_hook_heads.print_sk_buff),
 	.intercept_rx_path = LIST_HEAD_INIT(xen_sme_hook_heads.intercept_rx_path),
@@ -122,6 +125,18 @@ void xsl_intercept_free_tx_skbs_queue(struct bnx2x_fastpath *fp)
 }
 EXPORT_SYMBOL(xsl_intercept_free_tx_skbs_queue);
 
+int xsl_intercept_tx_avail(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata)
+{
+  return call_sme_int_hook(intercept_tx_avail, -1, bp, txdata);
+}
+EXPORT_SYMBOL(xsl_intercept_tx_avail);
+
+int xsl_intercept_tx_queue_has_work(struct bnx2x_fp_txdata *txdata)
+{
+  return call_sme_int_hook(intercept_tx_queue_has_work, -1, txdata);
+}
+EXPORT_SYMBOL(xsl_intercept_tx_queue_has_work);
+
 void xsl_parse_rx_data(void *dev, int fp_idx, uint16_t rx_bd_prod,
 		uint16_t rx_bd_cons, uint16_t comp_prod, uint16_t comp_cons,
 		char *data, int data_len, char *extra_dbg_string)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme_hooks.h b/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme_hooks.h
index 18b313bba..a4a31e51c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme_hooks.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/sme/xen_sme_hooks.h
@@ -34,6 +34,8 @@ void xsl_intercept_xmit_stop_queue(struct net_device *dev, struct netdev_queue *
     struct bnx2x_fp_txdata *txdata);
 int xsl_intercept_tx_int(struct net_device *dev, struct bnx2x_fp_txdata *txdata);
 void xsl_intercept_free_tx_skbs_queue(struct bnx2x_fastpath *fp);
+int xsl_intercept_tx_avail(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata);
+int xsl_intercept_tx_queue_has_work(struct bnx2x_fp_txdata *txdata);
 
 void xsl_parse_rx_data(void *dev, int fp_idx, uint16_t rx_bd_prod,
 		uint16_t rx_bd_cons, uint16_t comp_prod, uint16_t comp_cons, char *data,
-- 
GitLab