netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] TI DaVinci EMAC : Implement interrupt pacing functionality.
@ 2010-07-29 12:33 Sriramakrishnan
  2010-07-29 12:33 ` [PATCH 2/3] TI DaVinci EMAC: Fix asymmetric handling of packets in NAPI Poll function Sriramakrishnan
  2010-07-31  6:56 ` [PATCH 1/3] TI DaVinci EMAC : Implement interrupt pacing functionality David Miller
  0 siblings, 2 replies; 6+ messages in thread
From: Sriramakrishnan @ 2010-07-29 12:33 UTC (permalink / raw)
  To: netdev, davinci-linux-open-source; +Cc: nsekhar, anantgole, Sriramakrishnan

DaVinci EMAC module includes an interrupt pacing block that can
be programmed to throttle the rate at which interrupts are
generated. This patch implements interrupt pacing logic that can
be controlled through the ethtool interface(only rx_coalesce_usecs
param is honored)

Signed-off-by: Sriramakrishnan <srk@ti.com>
---
 drivers/net/davinci_emac.c |  133 +++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 131 insertions(+), 2 deletions(-)

diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 08e82b1..bc1b270 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -298,6 +298,11 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
 #define EMAC_CTRL_EWCTL		(0x4)
 #define EMAC_CTRL_EWINTTCNT	(0x8)
 
+/* EMAC DM644x control module masks */
+#define EMAC_DM644X_EWINTCNT_MASK	0x1FFFF
+#define EMAC_DM644X_INTMIN_INTVL	0x1
+#define EMAC_DM644X_INTMAX_INTVL	(EMAC_DM644X_EWINTCNT_MASK)
+
 /* EMAC MDIO related */
 /* Mask & Control defines */
 #define MDIO_CONTROL_CLKDIV	(0xFF)
@@ -318,8 +323,20 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
 #define MDIO_CONTROL		(0x04)
 
 /* EMAC DM646X control module registers */
-#define EMAC_DM646X_CMRXINTEN	(0x14)
-#define EMAC_DM646X_CMTXINTEN	(0x18)
+#define EMAC_DM646X_CMINTCTRL	0x0C
+#define EMAC_DM646X_CMRXINTEN	0x14
+#define EMAC_DM646X_CMTXINTEN	0x18
+#define EMAC_DM646X_CMRXINTMAX	0x70
+#define EMAC_DM646X_CMTXINTMAX	0x74
+
+/* EMAC DM646X control module masks */
+#define EMAC_DM646X_INTPACEEN		(0x3 << 16)
+#define EMAC_DM646X_INTPRESCALE_MASK	(0x7FF << 0)
+#define EMAC_DM646X_CMINTMAX_CNT	63
+#define EMAC_DM646X_CMINTMIN_CNT	2
+#define EMAC_DM646X_CMINTMAX_INTVL	(1000 / EMAC_DM646X_CMINTMIN_CNT)
+#define EMAC_DM646X_CMINTMIN_INTVL	((1000 / EMAC_DM646X_CMINTMAX_CNT) + 1)
+
 
 /* EMAC EOI codes for C0 */
 #define EMAC_DM646X_MAC_EOI_C0_RXEN	(0x01)
@@ -468,6 +485,8 @@ struct emac_priv {
 	u32 duplex; /* Link duplex: 0=Half, 1=Full */
 	u32 rx_buf_size;
 	u32 isr_count;
+	u32 coal_intvl;
+	u32 bus_freq_mhz;
 	u8 rmii_en;
 	u8 version;
 	struct net_device_stats net_dev_stats;
@@ -692,6 +711,103 @@ static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
 }
 
 /**
+ * emac_get_coalesce : Get interrupt coalesce settings for this device
+ * @ndev : The DaVinci EMAC network adapter
+ * @coal : ethtool coalesce settings structure
+ *
+ * Fetch the current interrupt coalesce settings
+ *
+ */
+static int emac_get_coalesce(struct net_device *ndev,
+				struct ethtool_coalesce *coal)
+{
+	struct emac_priv *priv = netdev_priv(ndev);
+
+	coal->rx_coalesce_usecs = priv->coal_intvl;
+	return 0;
+
+}
+
+/**
+ * emac_set_coalesce : Set interrupt coalesce settings for this device
+ * @ndev : The DaVinci EMAC network adapter
+ * @coal : ethtool coalesce settings structure
+ *
+ * Set interrupt coalesce parameters
+ *
+ */
+static int emac_set_coalesce(struct net_device *ndev,
+				struct ethtool_coalesce *coal)
+{
+	struct emac_priv *priv = netdev_priv(ndev);
+	u32 int_ctrl, num_interrupts = 0;
+	u32 prescale = 0, addnl_dvdr = 1, coal_intvl = 0;
+
+	if (!coal->rx_coalesce_usecs)
+		return -EINVAL;
+
+	coal_intvl = coal->rx_coalesce_usecs;
+
+	switch (priv->version) {
+	case EMAC_VERSION_2:
+		int_ctrl =  emac_ctrl_read(EMAC_DM646X_CMINTCTRL);
+		prescale = priv->bus_freq_mhz * 4;
+
+		if (coal_intvl < EMAC_DM646X_CMINTMIN_INTVL)
+			coal_intvl = EMAC_DM646X_CMINTMIN_INTVL;
+
+		if (coal_intvl > EMAC_DM646X_CMINTMAX_INTVL) {
+			/*
+			 * Interrupt pacer works with 4us Pulse, we can
+			 * throttle further by dilating the 4us pulse.
+			 */
+			addnl_dvdr = EMAC_DM646X_INTPRESCALE_MASK / prescale;
+
+			if (addnl_dvdr > 1) {
+				prescale *= addnl_dvdr;
+				if (coal_intvl > (EMAC_DM646X_CMINTMAX_INTVL
+							* addnl_dvdr))
+					coal_intvl = (EMAC_DM646X_CMINTMAX_INTVL
+							* addnl_dvdr);
+			} else {
+				addnl_dvdr = 1;
+				coal_intvl = EMAC_DM646X_CMINTMAX_INTVL;
+			}
+		}
+
+		num_interrupts = (1000 * addnl_dvdr) / coal_intvl;
+
+		int_ctrl |= EMAC_DM646X_INTPACEEN;
+		int_ctrl &= (~EMAC_DM646X_INTPRESCALE_MASK);
+		int_ctrl |= (prescale & EMAC_DM646X_INTPRESCALE_MASK);
+		emac_ctrl_write(EMAC_DM646X_CMINTCTRL, int_ctrl);
+
+		emac_ctrl_write(EMAC_DM646X_CMRXINTMAX, num_interrupts);
+		emac_ctrl_write(EMAC_DM646X_CMTXINTMAX, num_interrupts);
+
+		break;
+	default:
+		int_ctrl = emac_ctrl_read(EMAC_CTRL_EWINTTCNT);
+		int_ctrl &= (~EMAC_DM644X_EWINTCNT_MASK);
+		prescale = coal_intvl * priv->bus_freq_mhz;
+		if (prescale > EMAC_DM644X_EWINTCNT_MASK) {
+			prescale = EMAC_DM644X_EWINTCNT_MASK;
+			coal_intvl = prescale / priv->bus_freq_mhz;
+		}
+		emac_ctrl_write(EMAC_CTRL_EWINTTCNT, (int_ctrl | prescale));
+
+		break;
+	}
+
+	printk(KERN_INFO"Set coalesce to %d usecs.\n", coal_intvl);
+	priv->coal_intvl = coal_intvl;
+
+	return 0;
+
+}
+
+
+/**
  * ethtool_ops: DaVinci EMAC Ethtool structure
  *
  * Ethtool support for EMAC adapter
@@ -702,6 +818,8 @@ static const struct ethtool_ops ethtool_ops = {
 	.get_settings = emac_get_settings,
 	.set_settings = emac_set_settings,
 	.get_link = ethtool_op_get_link,
+	.get_coalesce = emac_get_coalesce,
+	.set_coalesce =  emac_set_coalesce,
 };
 
 /**
@@ -2437,6 +2555,14 @@ static int emac_dev_open(struct net_device *ndev)
 	/* Start/Enable EMAC hardware */
 	emac_hw_enable(priv);
 
+	/* Enable Interrupt pacing if configured */
+	if (priv->coal_intvl != 0) {
+		struct ethtool_coalesce coal;
+
+		coal.rx_coalesce_usecs = (priv->coal_intvl << 4);
+		emac_set_coalesce(ndev, &coal);
+	}
+
 	/* find the first phy */
 	priv->phydev = NULL;
 	if (priv->phy_mask) {
@@ -2677,6 +2803,9 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
 	priv->int_enable = pdata->interrupt_enable;
 	priv->int_disable = pdata->interrupt_disable;
 
+	priv->coal_intvl = 0;
+	priv->bus_freq_mhz = (u32)(emac_bus_frequency / 1000000);
+
 	emac_dev = &ndev->dev;
 	/* Get EMAC platform data */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
1.6.2.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] TI DaVinci EMAC: Fix asymmetric handling of packets in NAPI Poll function.
  2010-07-29 12:33 [PATCH 1/3] TI DaVinci EMAC : Implement interrupt pacing functionality Sriramakrishnan
@ 2010-07-29 12:33 ` Sriramakrishnan
  2010-07-29 12:34   ` [PATCH 3/3] TI DaVinci EMAC: Fix incorrect reference to EMAC_CTRL registers Sriramakrishnan
  2010-07-31  6:56   ` [PATCH 2/3] TI DaVinci EMAC: Fix asymmetric handling of packets in NAPI Poll function David Miller
  2010-07-31  6:56 ` [PATCH 1/3] TI DaVinci EMAC : Implement interrupt pacing functionality David Miller
  1 sibling, 2 replies; 6+ messages in thread
From: Sriramakrishnan @ 2010-07-29 12:33 UTC (permalink / raw)
  To: netdev, davinci-linux-open-source; +Cc: nsekhar, anantgole, Sriramakrishnan

The current implementation of NAPI poll function in the driver does not service
Rx packets, error condition even if a single Tx packet gets serviced in
the napi poll call. This behavior severely affects performance for specific use
cases. This patch modifies the poll function implementation to service tx/rx
packets in an identical manner.

Signed-off-by: Sriramakrishnan <srk@ti.com>
---
 drivers/net/davinci_emac.c |   21 ++++++++-------------
 1 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index bc1b270..4ee9af6 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -2266,7 +2266,7 @@ static int emac_poll(struct napi_struct *napi, int budget)
 	struct net_device *ndev = priv->ndev;
 	struct device *emac_dev = &ndev->dev;
 	u32 status = 0;
-	u32 num_pkts = 0;
+	u32 num_tx_pkts = 0, num_rx_pkts = 0;
 
 	/* Check interrupt vectors and call packet processing */
 	status = emac_read(EMAC_MACINVECTOR);
@@ -2277,27 +2277,19 @@ static int emac_poll(struct napi_struct *napi, int budget)
 		mask = EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC;
 
 	if (status & mask) {
-		num_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH,
+		num_tx_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH,
 					  EMAC_DEF_TX_MAX_SERVICE);
 	} /* TX processing */
 
-	if (num_pkts)
-		return budget;
-
 	mask = EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC;
 
 	if (priv->version == EMAC_VERSION_2)
 		mask = EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC;
 
 	if (status & mask) {
-		num_pkts = emac_rx_bdproc(priv, EMAC_DEF_RX_CH, budget);
+		num_rx_pkts = emac_rx_bdproc(priv, EMAC_DEF_RX_CH, budget);
 	} /* RX processing */
 
-	if (num_pkts < budget) {
-		napi_complete(napi);
-		emac_int_enable(priv);
-	}
-
 	mask = EMAC_DM644X_MAC_IN_VECTOR_HOST_INT;
 	if (priv->version == EMAC_VERSION_2)
 		mask = EMAC_DM646X_MAC_IN_VECTOR_HOST_INT;
@@ -2328,9 +2320,12 @@ static int emac_poll(struct napi_struct *napi, int budget)
 				dev_err(emac_dev, "RX Host error %s on ch=%d\n",
 					&emac_rxhost_errcodes[cause][0], ch);
 		}
-	} /* Host error processing */
+	} else if (num_rx_pkts < budget) {
+		napi_complete(napi);
+		emac_int_enable(priv);
+	}
 
-	return num_pkts;
+	return num_rx_pkts;
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-- 
1.6.2.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] TI DaVinci EMAC: Fix incorrect reference to EMAC_CTRL registers.
  2010-07-29 12:33 ` [PATCH 2/3] TI DaVinci EMAC: Fix asymmetric handling of packets in NAPI Poll function Sriramakrishnan
@ 2010-07-29 12:34   ` Sriramakrishnan
  2010-07-31  6:56     ` David Miller
  2010-07-31  6:56   ` [PATCH 2/3] TI DaVinci EMAC: Fix asymmetric handling of packets in NAPI Poll function David Miller
  1 sibling, 1 reply; 6+ messages in thread
From: Sriramakrishnan @ 2010-07-29 12:34 UTC (permalink / raw)
  To: netdev, davinci-linux-open-source; +Cc: nsekhar, anantgole, Sriramakrishnan

The EMAC modules control registers vary as per the version of the
EMAC module. EMAC_CTRL_EWCTL,EMAC_CTRL_EWINTTCNT are available
only on EMAC_VERSION_1. The emac_dump_regs() function accesses
these indiscriminately. This patch fixes the issue.

Signed-off-by: Sriramakrishnan <srk@ti.com>
---
 drivers/net/davinci_emac.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 4ee9af6..12196ad 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -565,9 +565,11 @@ static void emac_dump_regs(struct emac_priv *priv)
 
 	/* Print important registers in EMAC */
 	dev_info(emac_dev, "EMAC Basic registers\n");
-	dev_info(emac_dev, "EMAC: EWCTL: %08X, EWINTTCNT: %08X\n",
-		emac_ctrl_read(EMAC_CTRL_EWCTL),
-		emac_ctrl_read(EMAC_CTRL_EWINTTCNT));
+	if (priv->version == EMAC_VERSION_1) {
+		dev_info(emac_dev, "EMAC: EWCTL: %08X, EWINTTCNT: %08X\n",
+			emac_ctrl_read(EMAC_CTRL_EWCTL),
+			emac_ctrl_read(EMAC_CTRL_EWINTTCNT));
+	}
 	dev_info(emac_dev, "EMAC: TXID: %08X %s, RXID: %08X %s\n",
 		emac_read(EMAC_TXIDVER),
 		((emac_read(EMAC_TXCONTROL)) ? "enabled" : "disabled"),
-- 
1.6.2.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] TI DaVinci EMAC : Implement interrupt pacing functionality.
  2010-07-29 12:33 [PATCH 1/3] TI DaVinci EMAC : Implement interrupt pacing functionality Sriramakrishnan
  2010-07-29 12:33 ` [PATCH 2/3] TI DaVinci EMAC: Fix asymmetric handling of packets in NAPI Poll function Sriramakrishnan
@ 2010-07-31  6:56 ` David Miller
  1 sibling, 0 replies; 6+ messages in thread
From: David Miller @ 2010-07-31  6:56 UTC (permalink / raw)
  To: srk; +Cc: netdev, davinci-linux-open-source, nsekhar, anantgole

From: Sriramakrishnan <srk@ti.com>
Date: Thu, 29 Jul 2010 18:03:58 +0530

> DaVinci EMAC module includes an interrupt pacing block that can
> be programmed to throttle the rate at which interrupts are
> generated. This patch implements interrupt pacing logic that can
> be controlled through the ethtool interface(only rx_coalesce_usecs
> param is honored)
> 
> Signed-off-by: Sriramakrishnan <srk@ti.com>

Applied.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] TI DaVinci EMAC: Fix asymmetric handling of packets in NAPI Poll function.
  2010-07-29 12:33 ` [PATCH 2/3] TI DaVinci EMAC: Fix asymmetric handling of packets in NAPI Poll function Sriramakrishnan
  2010-07-29 12:34   ` [PATCH 3/3] TI DaVinci EMAC: Fix incorrect reference to EMAC_CTRL registers Sriramakrishnan
@ 2010-07-31  6:56   ` David Miller
  1 sibling, 0 replies; 6+ messages in thread
From: David Miller @ 2010-07-31  6:56 UTC (permalink / raw)
  To: srk; +Cc: netdev, davinci-linux-open-source, nsekhar, anantgole

From: Sriramakrishnan <srk@ti.com>
Date: Thu, 29 Jul 2010 18:03:59 +0530

> The current implementation of NAPI poll function in the driver does not service
> Rx packets, error condition even if a single Tx packet gets serviced in
> the napi poll call. This behavior severely affects performance for specific use
> cases. This patch modifies the poll function implementation to service tx/rx
> packets in an identical manner.
> 
> Signed-off-by: Sriramakrishnan <srk@ti.com>

Applied.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 3/3] TI DaVinci EMAC: Fix incorrect reference to EMAC_CTRL registers.
  2010-07-29 12:34   ` [PATCH 3/3] TI DaVinci EMAC: Fix incorrect reference to EMAC_CTRL registers Sriramakrishnan
@ 2010-07-31  6:56     ` David Miller
  0 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2010-07-31  6:56 UTC (permalink / raw)
  To: srk; +Cc: netdev, davinci-linux-open-source, nsekhar, anantgole

From: Sriramakrishnan <srk@ti.com>
Date: Thu, 29 Jul 2010 18:04:00 +0530

> The EMAC modules control registers vary as per the version of the
> EMAC module. EMAC_CTRL_EWCTL,EMAC_CTRL_EWINTTCNT are available
> only on EMAC_VERSION_1. The emac_dump_regs() function accesses
> these indiscriminately. This patch fixes the issue.
> 
> Signed-off-by: Sriramakrishnan <srk@ti.com>

Also applied, thank you.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-07-31  6:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-29 12:33 [PATCH 1/3] TI DaVinci EMAC : Implement interrupt pacing functionality Sriramakrishnan
2010-07-29 12:33 ` [PATCH 2/3] TI DaVinci EMAC: Fix asymmetric handling of packets in NAPI Poll function Sriramakrishnan
2010-07-29 12:34   ` [PATCH 3/3] TI DaVinci EMAC: Fix incorrect reference to EMAC_CTRL registers Sriramakrishnan
2010-07-31  6:56     ` David Miller
2010-07-31  6:56   ` [PATCH 2/3] TI DaVinci EMAC: Fix asymmetric handling of packets in NAPI Poll function David Miller
2010-07-31  6:56 ` [PATCH 1/3] TI DaVinci EMAC : Implement interrupt pacing functionality David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).