netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [net-next PATCH 1/1] drivers: net: cpsw: add support to show hw stats via ethtool get_regs
@ 2013-07-19 14:07 Mugunthan V N
  2013-07-20  0:32 ` David Miller
  0 siblings, 1 reply; 3+ messages in thread
From: Mugunthan V N @ 2013-07-19 14:07 UTC (permalink / raw)
  To: netdev; +Cc: davem, linux-omap, Mugunthan V N

Add support to show CPSW hardware statistics to user via ethtool get_regs
ops so user can find if there were any error reported or the system is
over loaded duing hagh data rate transfer.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/net/ethernet/ti/cpsw.c |   74 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 05a1674..64117f5 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -85,12 +85,14 @@ do {								\
 
 #define HOST_PORT_NUM		0
 #define SLIVER_SIZE		0x40
+#define CPSW_HW_STATS_LEN	36
 
 #define CPSW1_HOST_PORT_OFFSET	0x028
 #define CPSW1_SLAVE_OFFSET	0x050
 #define CPSW1_SLAVE_SIZE	0x040
 #define CPSW1_CPDMA_OFFSET	0x100
 #define CPSW1_STATERAM_OFFSET	0x200
+#define CPSW1_HW_STATS		0x400
 #define CPSW1_CPTS_OFFSET	0x500
 #define CPSW1_ALE_OFFSET	0x600
 #define CPSW1_SLIVER_OFFSET	0x700
@@ -99,6 +101,7 @@ do {								\
 #define CPSW2_SLAVE_OFFSET	0x200
 #define CPSW2_SLAVE_SIZE	0x100
 #define CPSW2_CPDMA_OFFSET	0x800
+#define CPSW2_HW_STATS		0x900
 #define CPSW2_STATERAM_OFFSET	0xa00
 #define CPSW2_CPTS_OFFSET	0xc00
 #define CPSW2_ALE_OFFSET	0xd00
@@ -332,6 +335,7 @@ struct cpsw_priv {
 	struct cpsw_platform_data	data;
 	struct cpsw_ss_regs __iomem	*regs;
 	struct cpsw_wr_regs __iomem	*wr_regs;
+	void __iomem			*hw_stats;
 	struct cpsw_host_regs __iomem	*host_port_regs;
 	u32				msg_enable;
 	u32				version;
@@ -723,6 +727,64 @@ static int cpsw_set_coalesce(struct net_device *ndev,
 	return 0;
 }
 
+static int cpsw_get_regs_len(struct net_device *ndev)
+{
+	int len;
+
+	len = CPSW_HW_STATS_LEN * sizeof(u32);
+	len += 2 * sizeof(struct cpdma_chan_stats);
+
+	return len;
+}
+
+static void cpsw_get_regs(struct net_device *ndev,
+			  struct ethtool_regs *regs, void *p)
+{
+	struct cpsw_priv *priv = netdev_priv(ndev);
+	struct cpdma_chan_stats	dma_stats;
+	u32 *reg = p;
+	int i;
+
+	/* update CPSW IP version */
+	regs->version = priv->version;
+
+	/* Packet Tx/Rx statistics */
+	for (i = 0; i < CPSW_HW_STATS_LEN; i++)
+		reg[i] = readl(((u32 *)priv->hw_stats) + i);
+
+	/* Rx DMA statistics */
+	cpdma_chan_get_stats(priv->rxch, &dma_stats);
+	reg[i++] = dma_stats.head_enqueue;
+	reg[i++] = dma_stats.tail_enqueue;
+	reg[i++] = dma_stats.pad_enqueue;
+	reg[i++] = dma_stats.misqueued;
+	reg[i++] = dma_stats.desc_alloc_fail;
+	reg[i++] = dma_stats.pad_alloc_fail;
+	reg[i++] = dma_stats.runt_receive_buff;
+	reg[i++] = dma_stats.runt_transmit_buff;
+	reg[i++] = dma_stats.empty_dequeue;
+	reg[i++] = dma_stats.busy_dequeue;
+	reg[i++] = dma_stats.good_dequeue;
+	reg[i++] = dma_stats.requeue;
+	reg[i++] = dma_stats.teardown_dequeue;
+
+	/* Tx DMA statistics */
+	cpdma_chan_get_stats(priv->txch, &dma_stats);
+	reg[i++] = dma_stats.head_enqueue;
+	reg[i++] = dma_stats.tail_enqueue;
+	reg[i++] = dma_stats.pad_enqueue;
+	reg[i++] = dma_stats.misqueued;
+	reg[i++] = dma_stats.desc_alloc_fail;
+	reg[i++] = dma_stats.pad_alloc_fail;
+	reg[i++] = dma_stats.runt_receive_buff;
+	reg[i++] = dma_stats.runt_transmit_buff;
+	reg[i++] = dma_stats.empty_dequeue;
+	reg[i++] = dma_stats.busy_dequeue;
+	reg[i++] = dma_stats.good_dequeue;
+	reg[i++] = dma_stats.requeue;
+	reg[i++] = dma_stats.teardown_dequeue;
+}
+
 static inline int __show_stat(char *buf, int maxlen, const char *name, u32 val)
 {
 	static char *leader = "........................................";
@@ -1344,9 +1406,10 @@ static void cpsw_get_drvinfo(struct net_device *ndev,
 {
 	struct cpsw_priv *priv = netdev_priv(ndev);
 
-	strlcpy(info->driver, "TI CPSW Driver v1.0", sizeof(info->driver));
+	strlcpy(info->driver, "cpsw", sizeof(info->driver));
 	strlcpy(info->version, "1.0", sizeof(info->version));
 	strlcpy(info->bus_info, priv->pdev->name, sizeof(info->bus_info));
+	info->regdump_len = cpsw_get_regs_len(ndev);
 }
 
 static u32 cpsw_get_msglevel(struct net_device *ndev)
@@ -1426,6 +1489,8 @@ static const struct ethtool_ops cpsw_ethtool_ops = {
 	.set_settings	= cpsw_set_settings,
 	.get_coalesce	= cpsw_get_coalesce,
 	.set_coalesce	= cpsw_set_coalesce,
+	.get_regs_len	= cpsw_get_regs_len,
+	.get_regs	= cpsw_get_regs,
 };
 
 static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
@@ -1623,6 +1688,7 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev,
 	priv_sl2->host_port = priv->host_port;
 	priv_sl2->host_port_regs = priv->host_port_regs;
 	priv_sl2->wr_regs = priv->wr_regs;
+	priv_sl2->hw_stats = priv->hw_stats;
 	priv_sl2->dma = priv->dma;
 	priv_sl2->txch = priv->txch;
 	priv_sl2->rxch = priv->rxch;
@@ -1780,7 +1846,8 @@ static int cpsw_probe(struct platform_device *pdev)
 	switch (priv->version) {
 	case CPSW_VERSION_1:
 		priv->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET;
-		priv->cpts->reg       = ss_regs + CPSW1_CPTS_OFFSET;
+		priv->hw_stats	     = ss_regs + CPSW1_HW_STATS;
+		priv->cpts->reg      = ss_regs + CPSW1_CPTS_OFFSET;
 		dma_params.dmaregs   = ss_regs + CPSW1_CPDMA_OFFSET;
 		dma_params.txhdp     = ss_regs + CPSW1_STATERAM_OFFSET;
 		ale_params.ale_regs  = ss_regs + CPSW1_ALE_OFFSET;
@@ -1791,7 +1858,8 @@ static int cpsw_probe(struct platform_device *pdev)
 		break;
 	case CPSW_VERSION_2:
 		priv->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET;
-		priv->cpts->reg       = ss_regs + CPSW2_CPTS_OFFSET;
+		priv->hw_stats	     = ss_regs + CPSW2_HW_STATS;
+		priv->cpts->reg      = ss_regs + CPSW2_CPTS_OFFSET;
 		dma_params.dmaregs   = ss_regs + CPSW2_CPDMA_OFFSET;
 		dma_params.txhdp     = ss_regs + CPSW2_STATERAM_OFFSET;
 		ale_params.ale_regs  = ss_regs + CPSW2_ALE_OFFSET;
-- 
1.7.9.5


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

* Re: [net-next PATCH 1/1] drivers: net: cpsw: add support to show hw stats via ethtool get_regs
  2013-07-19 14:07 [net-next PATCH 1/1] drivers: net: cpsw: add support to show hw stats via ethtool get_regs Mugunthan V N
@ 2013-07-20  0:32 ` David Miller
  2013-07-20  8:00   ` Mugunthan V N
  0 siblings, 1 reply; 3+ messages in thread
From: David Miller @ 2013-07-20  0:32 UTC (permalink / raw)
  To: mugunthanvnm; +Cc: netdev, linux-omap

From: Mugunthan V N <mugunthanvnm@ti.com>
Date: Fri, 19 Jul 2013 19:37:21 +0530

> Add support to show CPSW hardware statistics to user via ethtool get_regs
> ops so user can find if there were any error reported or the system is
> over loaded duing hagh data rate transfer.
> 
> Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>

This is not the correct way to provide this functionality.  ->get_regs()
is for dumping the raw hardware registers to userspace for low level
debugging purposes, not for providing HW specific statistics.

The correct thing to do is provide an appropriate implementation of
the ->get_strings() and ->get_ethtool_stats() methods.

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

* Re: [net-next PATCH 1/1] drivers: net: cpsw: add support to show hw stats via ethtool get_regs
  2013-07-20  0:32 ` David Miller
@ 2013-07-20  8:00   ` Mugunthan V N
  0 siblings, 0 replies; 3+ messages in thread
From: Mugunthan V N @ 2013-07-20  8:00 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-omap

On 7/20/2013 6:02 AM, David Miller wrote:
> From: Mugunthan V N <mugunthanvnm@ti.com>
> Date: Fri, 19 Jul 2013 19:37:21 +0530
>
>> Add support to show CPSW hardware statistics to user via ethtool get_regs
>> ops so user can find if there were any error reported or the system is
>> over loaded duing hagh data rate transfer.
>>
>> Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
> This is not the correct way to provide this functionality.  ->get_regs()
> is for dumping the raw hardware registers to userspace for low level
> debugging purposes, not for providing HW specific statistics.
>
> The correct thing to do is provide an appropriate implementation of
> the ->get_strings() and ->get_ethtool_stats() methods.
Will change the implementation and resubmit the patch.

Regards
Mugunthan V N

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

end of thread, other threads:[~2013-07-20  8:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-19 14:07 [net-next PATCH 1/1] drivers: net: cpsw: add support to show hw stats via ethtool get_regs Mugunthan V N
2013-07-20  0:32 ` David Miller
2013-07-20  8:00   ` Mugunthan V N

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).