* [PATCH 0/6] Add CPTS PTP driver support
@ 2012-10-16 22:45 Mugunthan V N
  2012-10-16 22:45 ` [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version Mugunthan V N
                   ` (6 more replies)
  0 siblings, 7 replies; 38+ messages in thread
From: Mugunthan V N @ 2012-10-16 22:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, Richard Cochran, Mugunthan V N
This patch series contains driver implementation for TI Common Platform
Time Sync (CPTS) driver for PTP packet timestamping.
CPTS is found in following TI SoC.
* AM335X - http://www.ti.com/litv/pdf/spruh73c
* DM814X - http://www.ti.com/litv/pdf/sprugz8
The Common Platform Time Sync (CPTS) module is used to facilitate host
control of time sync operations. It enables compliance with the IEEE 1588-2008
standard for a precision clock synchronization protocol
This patch series is tested over vanilla kernel with the below patches
http://marc.info/?l=linux-arm-kernel&m=135032863723906&w=2
Tested both L2 and L4 PTP packet timestamping
Mugunthan V N (6):
  drivers: net: ethernet: cpsw: add support for CPSW register offset
    changes in different IP version
  drivers: net: ethernet: davinci_cpdma: add clear api for statistics
    interrupt
  drivers: net: ethernet: cpsw: add multicast address to ALE table
  ptp: add api to get ptp seq id and event type from skb
  drivers: net: ethernet: cpts: implement cpts hardware clock
  drivers: net: ethernet: cpsw: implement timestamping capabilities in
    cpsw
 Documentation/devicetree/bindings/net/cpsw.txt |    3 +
 drivers/net/ethernet/ti/Kconfig                |   10 +
 drivers/net/ethernet/ti/Makefile               |    2 +-
 drivers/net/ethernet/ti/cpsw.c                 |  409 ++++++++++++++++++++++--
 drivers/net/ethernet/ti/cpsw_ale.c             |   31 ++-
 drivers/net/ethernet/ti/cpsw_ale.h             |    1 +
 drivers/net/ethernet/ti/cpts.c                 |  399 +++++++++++++++++++++++
 drivers/net/ethernet/ti/cpts.h                 |  118 +++++++
 drivers/net/ethernet/ti/davinci_cpdma.c        |    8 +
 drivers/net/ethernet/ti/davinci_cpdma.h        |    1 +
 include/linux/platform_data/cpsw.h             |    1 +
 include/linux/ptp_classify.h                   |   42 +++
 12 files changed, 991 insertions(+), 34 deletions(-)
 create mode 100644 drivers/net/ethernet/ti/cpts.c
 create mode 100644 drivers/net/ethernet/ti/cpts.h
^ permalink raw reply	[flat|nested] 38+ messages in thread
* [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version
  2012-10-16 22:45 [PATCH 0/6] Add CPTS PTP driver support Mugunthan V N
@ 2012-10-16 22:45 ` Mugunthan V N
  2012-10-18  2:45   ` Richard Cochran
  2012-10-16 22:45 ` [PATCH 2/6] drivers: net: ethernet: davinci_cpdma: add clear api for statistics interrupt Mugunthan V N
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 38+ messages in thread
From: Mugunthan V N @ 2012-10-16 22:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, Richard Cochran, Mugunthan V N
Register offsets for slave register are different between the CPSW IP
found in TI814X and AM335X, so this patch adds support to access slave
registers with CPSW versions
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/net/ethernet/ti/cpsw.c |   86 +++++++++++++++++++++++++++++++---------
 1 files changed, 67 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index df55e24..cdf9ecc 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -70,6 +70,11 @@ do {								\
 		dev_notice(priv->dev, format, ## __VA_ARGS__);	\
 } while (0)
 
+#define CPSW_VERSION_1		0x19010a
+#define CPSW_VERSION_2		0x19010c
+#define cpsw_slave_reg(priv, slave, reg)				\
+	((slave)->regs + (priv)->slave_reg_ofs[(reg)])
+
 #define CPSW_MAJOR_VERSION(reg)		(reg >> 8 & 0x7)
 #define CPSW_MINOR_VERSION(reg)		(reg & 0xff)
 #define CPSW_RTL_VERSION(reg)		((reg >> 11) & 0x1f)
@@ -117,6 +122,48 @@ do {								\
 			disable_irq_nosync(priv->irqs_table[i]); \
 	} while (0);
 
+enum CPSW_SLAVE_REG_OFS {
+	MAX_BLKS,
+	BLK_CNT,
+	FLOW_THRESH,
+	PORT_VLAN,
+	TX_PRI_MAP,
+	TS_CTL,
+	TS_SEQ_LTYPE,
+	TS_VLAN,
+	SA_LO,
+	SA_HI,
+	PORT_CONTROL,
+	TS_SEQ_MTYPE,
+	TS_CONTROL,
+};
+
+static const u32 slave_reg_map_ip_v1[] = {
+	[MAX_BLKS]	= 0x00,
+	[BLK_CNT]	= 0x04,
+	[FLOW_THRESH]	= 0x08,
+	[PORT_VLAN]	= 0x0c,
+	[TX_PRI_MAP]	= 0x10,
+	[TS_CTL]	= 0x14,
+	[TS_SEQ_LTYPE]	= 0x18,
+	[TS_VLAN]	= 0x1c,
+	[SA_LO]		= 0x20,
+	[SA_HI]		= 0x24,
+};
+
+static const u32 slave_reg_map_ip_v2[] = {
+	[PORT_CONTROL]	= 0x00,
+	[TS_CONTROL]	= 0x04,
+	[MAX_BLKS]	= 0x08,
+	[BLK_CNT]	= 0x0c,
+	[FLOW_THRESH]	= 0x10,
+	[PORT_VLAN]	= 0x14,
+	[TX_PRI_MAP]	= 0x18,
+	[TS_SEQ_MTYPE]	= 0x1c,
+	[SA_LO]		= 0x20,
+	[SA_HI]		= 0x24,
+};
+
 static int debug_level;
 module_param(debug_level, int, 0);
 MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)");
@@ -146,19 +193,13 @@ struct cpsw_regs {
 	u32	soft_reset;
 	u32	stat_port_en;
 	u32	ptype;
-};
-
-struct cpsw_slave_regs {
-	u32	max_blks;
-	u32	blk_cnt;
-	u32	flow_thresh;
-	u32	port_vlan;
-	u32	tx_pri_map;
-	u32	ts_ctl;
-	u32	ts_seq_ltype;
-	u32	ts_vlan;
-	u32	sa_lo;
-	u32	sa_hi;
+	u32	soft_idle;
+	u32	thru_rate;
+	u32	gap_thresh;
+	u32	tx_start_wds;
+	u32	flow_control;
+	u32	vlan_ltype;
+	u32	ts_ltype;
 };
 
 struct cpsw_host_regs {
@@ -185,7 +226,7 @@ struct cpsw_sliver_regs {
 };
 
 struct cpsw_slave {
-	struct cpsw_slave_regs __iomem	*regs;
+	void __iomem			*regs;
 	struct cpsw_sliver_regs __iomem	*sliver;
 	int				slave_num;
 	u32				mac_control;
@@ -215,6 +256,8 @@ struct cpsw_priv {
 	struct cpdma_ctlr		*dma;
 	struct cpdma_chan		*txch, *rxch;
 	struct cpsw_ale			*ale;
+	u32				cpsw_version;
+	u32				*slave_reg_ofs;
 	/* snapshot of IRQ numbers */
 	u32 irqs_table[4];
 	u32 num_irqs;
@@ -359,8 +402,8 @@ static inline void soft_reset(const char *module, void __iomem *reg)
 static void cpsw_set_slave_mac(struct cpsw_slave *slave,
 			       struct cpsw_priv *priv)
 {
-	__raw_writel(mac_hi(priv->mac_addr), &slave->regs->sa_hi);
-	__raw_writel(mac_lo(priv->mac_addr), &slave->regs->sa_lo);
+	writel(mac_hi(priv->mac_addr), cpsw_slave_reg(priv, slave, SA_HI));
+	writel(mac_lo(priv->mac_addr), cpsw_slave_reg(priv, slave, SA_LO));
 }
 
 static void _cpsw_adjust_link(struct cpsw_slave *slave,
@@ -445,8 +488,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
 	soft_reset(name, &slave->sliver->soft_reset);
 
 	/* setup priority mapping */
-	__raw_writel(RX_PRIORITY_MAPPING, &slave->sliver->rx_pri_map);
-	__raw_writel(TX_PRIORITY_MAPPING, &slave->regs->tx_pri_map);
+	writel(RX_PRIORITY_MAPPING, &slave->sliver->rx_pri_map);
+	writel(TX_PRIORITY_MAPPING, cpsw_slave_reg(priv, slave, TX_PRI_MAP));
 
 	/* setup max packet size, and mac address */
 	__raw_writel(priv->rx_packet_max, &slave->sliver->rx_maxlen);
@@ -505,7 +548,12 @@ static int cpsw_ndo_open(struct net_device *ndev)
 
 	pm_runtime_get_sync(&priv->pdev->dev);
 
-	reg = __raw_readl(&priv->regs->id_ver);
+	reg = readl(&priv->regs->id_ver);
+	priv->cpsw_version = reg;
+	if (reg == CPSW_VERSION_1)
+		priv->slave_reg_ofs = (u32 *)slave_reg_map_ip_v1;
+	else
+		priv->slave_reg_ofs = (u32 *)slave_reg_map_ip_v2;
 
 	dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n",
 		 CPSW_MAJOR_VERSION(reg), CPSW_MINOR_VERSION(reg),
-- 
1.7.0.4
^ permalink raw reply related	[flat|nested] 38+ messages in thread
* [PATCH 2/6] drivers: net: ethernet: davinci_cpdma: add clear api for statistics interrupt
  2012-10-16 22:45 [PATCH 0/6] Add CPTS PTP driver support Mugunthan V N
  2012-10-16 22:45 ` [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version Mugunthan V N
@ 2012-10-16 22:45 ` Mugunthan V N
  2012-10-18  2:48   ` Richard Cochran
  2012-10-16 22:45 ` [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Mugunthan V N
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 38+ messages in thread
From: Mugunthan V N @ 2012-10-16 22:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, Richard Cochran, Mugunthan V N
Adding api to clear statistics interrupt which is generated by
CPTS event pend, stat pend, mdio interrupts
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/net/ethernet/ti/davinci_cpdma.c |    8 ++++++++
 drivers/net/ethernet/ti/davinci_cpdma.h |    1 +
 2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
index d15c888..656712c 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -63,6 +63,8 @@
 
 #define CPDMA_TEARDOWN_VALUE	0xfffffffc
 
+#define CPDMA_STAT_PEND_EOI	0x3
+
 struct cpdma_desc {
 	/* hardware fields */
 	u32			hw_next;
@@ -479,6 +481,12 @@ void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr)
 	dma_reg_write(ctlr, CPDMA_MACEOIVECTOR, 0);
 }
 
+void cpdma_ctlr_eoi_statistics(struct cpdma_ctlr *ctlr)
+{
+	dma_reg_write(ctlr, CPDMA_MACEOIVECTOR, CPDMA_STAT_PEND_EOI);
+}
+EXPORT_SYMBOL_GPL(cpdma_ctlr_eoi_statistics);
+
 struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr *ctlr, int chan_num,
 				     cpdma_handler_fn handler)
 {
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.h b/drivers/net/ethernet/ti/davinci_cpdma.h
index afa19a0..e25e9d5 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.h
+++ b/drivers/net/ethernet/ti/davinci_cpdma.h
@@ -87,6 +87,7 @@ int cpdma_chan_process(struct cpdma_chan *chan, int quota);
 
 int cpdma_ctlr_int_ctrl(struct cpdma_ctlr *ctlr, bool enable);
 void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr);
+void cpdma_ctlr_eoi_statistics(struct cpdma_ctlr *ctlr);
 int cpdma_chan_int_ctrl(struct cpdma_chan *chan, bool enable);
 
 enum cpdma_control {
-- 
1.7.0.4
^ permalink raw reply related	[flat|nested] 38+ messages in thread
* [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2012-10-16 22:45 [PATCH 0/6] Add CPTS PTP driver support Mugunthan V N
  2012-10-16 22:45 ` [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version Mugunthan V N
  2012-10-16 22:45 ` [PATCH 2/6] drivers: net: ethernet: davinci_cpdma: add clear api for statistics interrupt Mugunthan V N
@ 2012-10-16 22:45 ` Mugunthan V N
  2012-10-18  2:49   ` Richard Cochran
  2012-10-21 11:26   ` Richard Cochran
  2012-10-16 22:45 ` [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb Mugunthan V N
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 38+ messages in thread
From: Mugunthan V N @ 2012-10-16 22:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, Richard Cochran, Mugunthan V N
Adding multicast address to ALE table via netdev ops to subscribe, transmit
or receive multicast frames to and from the network
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/net/ethernet/ti/cpsw.c     |   27 +++++++++++++++++++++++++++
 drivers/net/ethernet/ti/cpsw_ale.c |   31 ++++++++++++++++++++++++++++---
 drivers/net/ethernet/ti/cpsw_ale.h |    1 +
 3 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index cdf9ecc..b6af1c6 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -75,6 +75,8 @@ do {								\
 #define cpsw_slave_reg(priv, slave, reg)				\
 	((slave)->regs + (priv)->slave_reg_ofs[(reg)])
 
+#define ALE_ALL_PORTS		0x7
+
 #define CPSW_MAJOR_VERSION(reg)		(reg >> 8 & 0x7)
 #define CPSW_MINOR_VERSION(reg)		(reg & 0xff)
 #define CPSW_RTL_VERSION(reg)		((reg >> 11) & 0x1f)
@@ -271,6 +273,30 @@ struct cpsw_priv {
 			(func)((priv)->slaves + idx, ##arg);	\
 	} while (0)
 
+static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+{
+	struct cpsw_priv *priv = netdev_priv(ndev);
+
+	if (ndev->flags & IFF_PROMISC) {
+		/* Enable promiscuous mode */
+		dev_err(priv->dev, "Ignoring Promiscuous mode\n");
+		return;
+	}
+
+	/* Clear all mcast from ALE */
+	cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port);
+
+	if (!netdev_mc_empty(ndev)) {
+		struct netdev_hw_addr *ha;
+
+		/* program multicast address list into ALE register */
+		netdev_for_each_mc_addr(ha, ndev) {
+			cpsw_ale_add_mcast(priv->ale, (u8 *)ha->addr,
+				ALE_ALL_PORTS << priv->host_port, 0, 0);
+		}
+	}
+}
+
 static void cpsw_intr_enable(struct cpsw_priv *priv)
 {
 	__raw_writel(0xFF, &priv->ss_regs->tx_en);
@@ -721,6 +747,7 @@ static const struct net_device_ops cpsw_netdev_ops = {
 	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_tx_timeout		= cpsw_ndo_tx_timeout,
 	.ndo_get_stats		= cpsw_ndo_get_stats,
+	.ndo_set_rx_mode	= cpsw_ndo_set_rx_mode,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= cpsw_ndo_poll_controller,
 #endif
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index ca0d48a..0e9ccc2 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 #include <linux/stat.h>
 #include <linux/sysfs.h>
+#include <linux/etherdevice.h>
 
 #include "cpsw_ale.h"
 
@@ -211,10 +212,34 @@ static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry,
 	mask &= ~port_mask;
 
 	/* free if only remaining port is host port */
-	if (mask == BIT(ale->params.ale_ports))
-		cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
-	else
+	if (mask)
 		cpsw_ale_set_port_mask(ale_entry, mask);
+	else
+		cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);
+}
+
+int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask)
+{
+	u32 ale_entry[ALE_ENTRY_WORDS];
+	int ret, idx;
+
+	for (idx = 0; idx < ale->params.ale_entries; idx++) {
+		cpsw_ale_read(ale, idx, ale_entry);
+		ret = cpsw_ale_get_entry_type(ale_entry);
+		if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR)
+			continue;
+
+		if (cpsw_ale_get_mcast(ale_entry)) {
+			u8 addr[6];
+
+			cpsw_ale_get_addr(ale_entry, addr);
+			if (!is_broadcast_ether_addr(addr))
+				cpsw_ale_flush_mcast(ale, ale_entry, port_mask);
+		}
+
+		cpsw_ale_write(ale, idx, ale_entry);
+	}
+	return 0;
 }
 
 static void cpsw_ale_flush_ucast(struct cpsw_ale *ale, u32 *ale_entry,
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h
index a95b37b..2bd09cb 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.h
+++ b/drivers/net/ethernet/ti/cpsw_ale.h
@@ -80,6 +80,7 @@ void cpsw_ale_stop(struct cpsw_ale *ale);
 
 int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout);
 int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask);
+int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask);
 int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, int flags);
 int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port);
 int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
-- 
1.7.0.4
^ permalink raw reply related	[flat|nested] 38+ messages in thread
* [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb
  2012-10-16 22:45 [PATCH 0/6] Add CPTS PTP driver support Mugunthan V N
                   ` (2 preceding siblings ...)
  2012-10-16 22:45 ` [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Mugunthan V N
@ 2012-10-16 22:45 ` Mugunthan V N
  2012-10-16 23:10   ` Ben Hutchings
  2012-10-18  2:55   ` Richard Cochran
  2012-10-16 22:45 ` [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock Mugunthan V N
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 38+ messages in thread
From: Mugunthan V N @ 2012-10-16 22:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, Richard Cochran, Mugunthan V N
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 include/linux/ptp_classify.h |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
index 1dc420b..9b3b55b 100644
--- a/include/linux/ptp_classify.h
+++ b/include/linux/ptp_classify.h
@@ -137,4 +137,46 @@ static inline int ptp_filter_init(struct sock_filter *f, int len)
 	{OP_RETA,	0,   0, 0			}, /*              */ \
 /*L6x*/	{OP_RETK,	0,   0, PTP_CLASS_NONE		},
 
+static inline int ptp_get_skb_event(struct sk_buff *skb, u32 ptp_class,
+				    u16 *evt_seqid, u8 *evt_msgtype)
+{
+	u16 *seqid;
+	unsigned int offset;
+	u8 *msgtype, *data = skb->data;
+
+	switch (ptp_class) {
+	case PTP_CLASS_V1_IPV4:
+	case PTP_CLASS_V2_IPV4:
+		offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
+		break;
+	case PTP_CLASS_V1_IPV6:
+	case PTP_CLASS_V2_IPV6:
+		offset = OFF_PTP6;
+		break;
+	case PTP_CLASS_V2_L2:
+		offset = ETH_HLEN;
+		break;
+	case PTP_CLASS_V2_VLAN:
+		offset = ETH_HLEN + VLAN_HLEN;
+		break;
+	default:
+		return 0;
+	}
+
+	if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid))
+		return 0;
+
+	if (unlikely(ptp_class & PTP_CLASS_V1))
+		msgtype = data + offset + OFF_PTP_CONTROL;
+	else
+		msgtype = data + offset;
+
+	seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
+
+	*evt_seqid = ntohs(*seqid);
+	*evt_msgtype = *msgtype & 0xf;
+
+	return 0;
+}
+
 #endif
-- 
1.7.0.4
^ permalink raw reply related	[flat|nested] 38+ messages in thread
* [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock
  2012-10-16 22:45 [PATCH 0/6] Add CPTS PTP driver support Mugunthan V N
                   ` (3 preceding siblings ...)
  2012-10-16 22:45 ` [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb Mugunthan V N
@ 2012-10-16 22:45 ` Mugunthan V N
  2012-10-20 13:43   ` Richard Cochran
  2012-10-16 22:45 ` [PATCH 6/6] drivers: net: ethernet: cpsw: implement timestamping capabilities in cpsw Mugunthan V N
  2012-10-21 18:46 ` [PATCH 0/6] Add CPTS PTP driver support Richard Cochran
  6 siblings, 1 reply; 38+ messages in thread
From: Mugunthan V N @ 2012-10-16 22:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, Richard Cochran, Mugunthan V N
Implement of hardware clock and network packet time stamping
using CPTS module.
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/net/ethernet/ti/Kconfig  |   10 +
 drivers/net/ethernet/ti/Makefile |    2 +-
 drivers/net/ethernet/ti/cpts.c   |  399 ++++++++++++++++++++++++++++++++++++++
 drivers/net/ethernet/ti/cpts.h   |  118 +++++++++++
 4 files changed, 528 insertions(+), 1 deletions(-)
 create mode 100644 drivers/net/ethernet/ti/cpts.c
 create mode 100644 drivers/net/ethernet/ti/cpts.h
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index b26cbda..6db7e6c 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -60,6 +60,16 @@ config TI_CPSW
 	  To compile this driver as a module, choose M here: the module
 	  will be called cpsw.
 
+config TI_CPTS
+	boolean "TI Common Platform Time Sync (CPTS) Support"
+	depends on TI_CPSW && (PTP_1588_CLOCK=y)
+	---help---
+	  This driver supports the Common Platform Time Sync unit of
+	  the CPSW Ethernet Switch.
+
+	  The unit can time stamp PTP UDP/IPv4
+	  and Layer 2 packets, and the driver offers a PTP Hardware Clock.
+
 config TLAN
 	tristate "TI ThunderLAN support"
 	depends on (PCI || EISA)
diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile
index 91bd8bb..c65148e 100644
--- a/drivers/net/ethernet/ti/Makefile
+++ b/drivers/net/ethernet/ti/Makefile
@@ -8,4 +8,4 @@ obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
 obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o
 obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o
 obj-$(CONFIG_TI_CPSW) += ti_cpsw.o
-ti_cpsw-y := cpsw_ale.o cpsw.o
+ti_cpsw-y := cpsw_ale.o cpsw.o cpts.o
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
new file mode 100644
index 0000000..dd2b37b
--- /dev/null
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -0,0 +1,399 @@
+/*
+ * Texas Instruments Common Platform Time Sync PTP Clock Driver
+ *
+ * Copyright (C) 2012 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+/*
+ * PTP 1588 clock using the CPTS
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/ptp_classify.h>
+#include <linux/ptp_clock_kernel.h>
+#include <plat/clock.h>
+#include <linux/clk.h>
+#include <linux/skbuff.h>
+
+#include "cpts.h"
+
+#ifdef CONFIG_TI_CPTS
+
+#define nanosec_to_cptscount(cpts, ns)	(div_u64((ns),			\
+					(cpts)->time_offs_correction))
+#define cptscount_to_nanosec(cpts, ns)	((ns) * (cpts)->time_offs_correction)
+
+static struct sock_filter ptp_filter[] = {
+	PTP_FILTER
+};
+
+void cpts_systime_write(struct cpts_priv *cpts, u64 ns)
+{
+	ns = nanosec_to_cptscount(cpts, ns);
+	writel((u32)(ns & 0xffffffff), &cpts->reg->ts_load_val);
+	writel(CPTS_TS_LOAD_CMD, &cpts->reg->ts_load_en);
+	cpts->tshi = (u32)(ns >> 32);
+}
+
+int cpts_systime_read(struct cpts_priv *cpts, u64 *ns)
+{
+	int ret = 0;
+	int i;
+
+	cpts->time_push = 0;
+	writel(CPTS_TS_PUSH_CMD, &cpts->reg->ts_push);
+	for (i = 0; i < CPTS_EVT_RETRY_COUNT; i++) {
+		cpts_event_fifo_read(cpts);
+		if (cpts->time_push)
+			break;
+	}
+	if (i >= CPTS_EVT_RETRY_COUNT) {
+		*ns = 0;
+		return -EBUSY;
+	}
+
+	*ns = cpts->time_push;
+	return ret;
+}
+
+static int cpts_evt_expired(struct cpts_evts *evt)
+{
+	return time_after(jiffies, evt->timeout);
+}
+
+static void cpts_rx_timestamp_pop(struct cpts_priv *cpts,
+			      struct sk_buff *skb, u32 evt_high)
+{
+	struct skb_shared_hwtstamps *shhwtstamps;
+	struct list_head *this, *next;
+	struct cpts_evts *evt;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpts->lock, flags);
+	list_for_each_safe(this, next, &cpts->ts_list) {
+		evt = list_entry(this, struct cpts_evts, list);
+		if (evt_high == evt->event_high) {
+			shhwtstamps = skb_hwtstamps(skb);
+			memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+			shhwtstamps->hwtstamp = ns_to_ktime(evt->ts);
+			list_del_init(&evt->list);
+			list_add(&evt->list, &cpts->ts_pool);
+			break;
+		} else if (cpts_evt_expired(evt)) {
+			list_del_init(&evt->list);
+			list_add(&evt->list, &cpts->ts_pool);
+		}
+	}
+	spin_unlock_irqrestore(&cpts->lock, flags);
+}
+
+static void cpts_tx_timestamp_pop(struct cpts_priv *cpts,
+			      struct sk_buff *skb, u32 evt_high)
+{
+	struct skb_shared_hwtstamps shhwtstamps;
+	struct list_head *this, *next;
+	struct cpts_evts *evt;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpts->lock, flags);
+	list_for_each_safe(this, next, &cpts->ts_list) {
+		evt = list_entry(this, struct cpts_evts, list);
+		if (evt_high == evt->event_high) {
+			memset(&shhwtstamps, 0,
+				sizeof(struct skb_shared_hwtstamps));
+			shhwtstamps.hwtstamp = ns_to_ktime(evt->ts);
+			skb_tstamp_tx(skb, &shhwtstamps);
+			list_del_init(&evt->list);
+			list_add(&evt->list, &cpts->ts_pool);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&cpts->lock, flags);
+}
+
+/*
+ * PTP clock operations
+ */
+
+static int ptp_cpts_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+	unsigned long freq, target_freq, current_freq;
+	int diff;
+	int neg_adj = 0;
+	u64 adj;
+	struct cpts_priv *cpts = container_of(ptp, struct cpts_priv,
+			caps);
+
+	if (IS_ERR(cpts->refclk)) {
+		/* No clock to adjust frequency */
+		return 0;
+	}
+	current_freq = cpts->refclk->recalc(
+			cpts->refclk);
+	freq = cpts->initial_freq;
+
+	if (ppb < 0) {
+		neg_adj = 1;
+		ppb = -ppb;
+	}
+
+	adj = freq;
+	adj *= ppb;
+	diff = div_u64(adj, GHZ_COUNTS_PER_SEC);
+	target_freq = (neg_adj ? freq - diff : freq + diff);
+
+	clk_set_rate(cpts->refclk, target_freq);
+
+	return 0;
+}
+
+static int ptp_cpts_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	s64 now;
+	unsigned long flags;
+	struct cpts_priv *cpts = container_of(ptp,
+			struct cpts_priv, caps);
+
+	spin_lock_irqsave(&cpts->lock, flags);
+
+	cpts_systime_read(cpts, &now);
+	now += delta;
+	cpts_systime_write(cpts, now);
+
+	spin_unlock_irqrestore(&cpts->lock, flags);
+
+	return 0;
+}
+
+static int ptp_cpts_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+{
+	u64 ns;
+	unsigned long flags;
+	struct cpts_priv *cpts = container_of(ptp,
+			struct cpts_priv, caps);
+
+	spin_lock_irqsave(&cpts->lock, flags);
+
+	cpts_systime_read(cpts, &ns);
+
+	spin_unlock_irqrestore(&cpts->lock, flags);
+
+	*ts = ns_to_timespec(ns);
+	return 0;
+}
+
+static int ptp_cpts_settime(struct ptp_clock_info *ptp,
+			   const struct timespec *ts)
+{
+	u64 ns;
+	unsigned long flags;
+	struct cpts_priv *cpts = container_of(ptp,
+			struct cpts_priv, caps);
+
+	ns = timespec_to_ns(ts);
+
+	spin_lock_irqsave(&cpts->lock, flags);
+
+	cpts_systime_write(cpts, ns);
+
+	spin_unlock_irqrestore(&cpts->lock, flags);
+
+	return 0;
+}
+
+static int ptp_cpts_enable(struct ptp_clock_info *ptp,
+			  struct ptp_clock_request *rq, int on)
+{
+	return -EOPNOTSUPP;
+}
+
+static struct ptp_clock_info ptp_cpts_caps = {
+	.owner		= THIS_MODULE,
+	.name		= "CTPS timer",
+	.n_ext_ts	= EXT_TS_INSTANCE_CNT,
+	.pps		= 0,
+	.adjfreq	= ptp_cpts_adjfreq,
+	.adjtime	= ptp_cpts_adjtime,
+	.gettime	= ptp_cpts_gettime,
+	.settime	= ptp_cpts_settime,
+	.enable		= ptp_cpts_enable,
+};
+
+void cpts_event_fifo_read(struct cpts_priv *cpts)
+{
+	while (readl(&cpts->reg->intstat_raw) & 0x01) {
+		u64 ts;
+		u32 event_high;
+		u32 event_tslo;
+		u32 evt_type;
+		struct cpts_evts *evt;
+
+		event_high = readl(&cpts->reg->event_high);
+		event_tslo = readl(&cpts->reg->event_low);
+		writel(CPTS_EVT_POP, &cpts->reg->event_pop);
+
+		if (cpts->first_half && event_tslo & CPTS_CNT_FIRST_HALF)
+			ts = (u64)(cpts->tshi - 1); /* this is misaligned ts */
+		else
+			ts = (u64)(cpts->tshi);
+		ts = (ts << 32) | event_tslo;
+		ts = cptscount_to_nanosec(cpts, ts);
+
+		evt_type = event_high & CPTS_EVT_MASK;
+
+		switch (evt_type) {
+		case CPTS_TS_PUSH:
+			/*Push TS to Read */
+			cpts->time_push = ts;
+			break;
+
+		case CPTS_TS_ROLLOVER:
+			/* Roll over */
+			cpts->tshi++;
+			cpts->first_half = true;
+			break;
+
+		case CPTS_TS_HROLLOVER:
+			/* Half Roll Over */
+			cpts->first_half = false;
+			break;
+
+		case CPTS_TS_HW_PUSH:
+			/* HW TS Push */
+			pr_err("CPTS hwts are not utilized\n");
+			/* TBD */
+			break;
+
+		case CPTS_TS_ETH_RX:
+			/* Ethernet Rx Ts */
+			if (!cpts->enable_rxts)
+				break;
+			evt = list_first_entry(&cpts->ts_pool,
+					       struct cpts_evts, list);
+			list_del_init(&evt->list);
+			evt->event_high = event_high & CPTS_EVT_TS_MASK;
+			evt->ts = ts;
+			list_add_tail(&evt->list, &cpts->ts_list);
+			break;
+
+		case CPTS_TS_ETH_TX:
+			/* Ethernet Tx Ts */
+			if (!cpts->enable_txts)
+				break;
+			evt = list_first_entry(&cpts->ts_pool,
+					       struct cpts_evts, list);
+			list_del_init(&evt->list);
+			evt->event_high = event_high & CPTS_EVT_TS_MASK;
+			evt->ts = ts;
+			list_add_tail(&evt->list, &cpts->ts_list);
+			break;
+		}
+	}
+}
+
+void cpts_rx_timestamp(struct cpts_priv *cpts, struct sk_buff *skb)
+{
+	u32 evt_high = 0;
+	u16 seq_id = 0;
+	u8 evt_type = 0;
+	u32 ptp_class = 0;
+
+	if (!cpts->enable_rxts)
+		return;
+
+	ptp_class = sk_run_filter(skb, ptp_filter);
+	if (ptp_class == PTP_CLASS_NONE)
+		return;
+
+	ptp_get_skb_event(skb, ptp_class, &seq_id, &evt_type);
+	evt_high = seq_id | (evt_type << 16) | CPTS_TS_ETH_RX;
+	cpts_rx_timestamp_pop(cpts, skb, evt_high);
+}
+
+void cpts_tx_timestamp(struct cpts_priv *cpts, struct sk_buff *skb)
+{
+	u32 evt_high = 0;
+	u16 seq_id = 0;
+	u8 evt_type = 0;
+	u32 ptp_class = 0;
+
+	if (!cpts->enable_txts)
+		return;
+
+	ptp_class = sk_run_filter(skb, ptp_filter);
+	if (ptp_class == PTP_CLASS_NONE)
+		return;
+
+	ptp_get_skb_event(skb, ptp_class, &seq_id, &evt_type);
+	evt_high = seq_id | (evt_type << 16) | CPTS_TS_ETH_TX;
+	cpts_tx_timestamp_pop(cpts, skb, evt_high);
+}
+
+void cpts_unregister(struct cpts_priv *cpts)
+{
+	if (!IS_ERR(cpts->refclk)) {
+		clk_disable(cpts->refclk);
+		clk_put(cpts->refclk);
+	}
+	if (!IS_ERR(cpts->ptp_clock))
+		ptp_clock_unregister(cpts->ptp_clock);
+}
+
+int cpts_register(struct device *dev, struct cpts_priv *cpts)
+{
+	int i;
+	u32 reg;
+
+	reg = readl(&cpts->reg->id_ver);
+	if (reg != CPTS_VERSION) {
+		pr_err("cpts: Cannot find CPTS\n");
+		return -ENODEV;
+	}
+
+	if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) {
+		pr_err("cpts: bad ptp filter\n");
+		return -EINVAL;
+	}
+
+	cpts->refclk = clk_get(NULL, CPTS_REF_CLOCK_NAME);
+	if (IS_ERR(cpts->refclk)) {
+		pr_err("cpts: Could not get %s clk\n", CPTS_REF_CLOCK_NAME);
+		return PTR_ERR(cpts->ptp_clock);
+	}
+	clk_enable(cpts->refclk);
+	spin_lock_init(&cpts->lock);
+
+	INIT_LIST_HEAD(&cpts->ts_list);
+	INIT_LIST_HEAD(&cpts->ts_pool);
+	for (i = 0; i < CPTS_TS_POOL_SIZE; i++)
+		list_add(&cpts->ts_pool_data[i].list, &cpts->ts_pool);
+
+	cpts->initial_freq = cpts->refclk->recalc(cpts->refclk);
+	cpts->time_offs_correction = GHZ_COUNTS_PER_SEC/cpts->initial_freq;
+	cpts->caps = ptp_cpts_caps;
+
+	cpts->ptp_clock = ptp_clock_register(&cpts->caps, dev);
+	if (IS_ERR(cpts->ptp_clock)) {
+		clk_disable(cpts->refclk);
+		clk_put(cpts->refclk);
+		return PTR_ERR(cpts->ptp_clock);
+	}
+
+	pr_info("Found CPTS and initializing...\n");
+	/* Enable CPTS */
+	writel(CPTS_CTRL_EN, &cpts->reg->control);
+	/* Enable CPTS Interrupt */
+	writel(CPTS_INTR_EN, &cpts->reg->int_enable);
+
+	return 0;
+}
+
+#endif
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
new file mode 100644
index 0000000..bc48dc4
--- /dev/null
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -0,0 +1,118 @@
+/*
+ * Texas Instruments Common Platform Time Sync Header
+ *
+ * Copyright (C) 2012 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __TI_CPTS_H__
+#define __TI_CPTS_H__
+
+#include <linux/ptp_clock_kernel.h>
+#include <linux/device.h>
+#include <linux/skbuff.h>
+
+#define CPTS_VERSION			0x4e8a0101
+#define CPTS_CTRL_EN			BIT(0)
+#define CPTS_INTR_EN			BIT(0)
+#define CPTS_EVT_POP			BIT(0)
+#define CPTS_TS_PUSH_CMD		BIT(0)
+#define CPTS_TS_LOAD_CMD		BIT(0)
+#define CPTS_TS_PUSH			0x0
+#define CPTS_TS_ROLLOVER		(0x1 << 20)
+#define CPTS_TS_HROLLOVER		(0x2 << 20)
+#define CPTS_TS_HW_PUSH			(0x3 << 20)
+#define CPTS_TS_ETH_RX			(0x4 << 20)
+#define CPTS_TS_ETH_TX			(0x5 << 20)
+#define CPSW_801_1Q_LTYPE		0x88f7
+#define CPSW_SEQ_ID_OFS			0x1e
+#define CPTS_CNT_FIRST_HALF		BIT(31)
+#define CPTS_EVT_MASK			0xf00000
+#define CPTS_EVT_RETRY_COUNT		20
+#define CPTS_INT_MASK			BIT(0)
+#define CPTS_EVT_TS_MASK		0xffffff
+#define GHZ_COUNTS_PER_SEC		1000000000ULL
+
+#define CPTS_TS_POOL_SIZE		32
+
+#define CPTS_READ_TS_MAX_TRY		20
+#define CPTS_REF_CLOCK_NAME		"cpsw_cpts_rft_clk"
+#define EXT_TS_INSTANCE_CNT		4
+/*
+ * CPTS Regs
+ */
+struct cpts_regs {
+	u32	id_ver;
+	u32	control;
+	u32	rftclk_sel;
+	u32	ts_push;
+	u32	ts_load_val;
+	u32	ts_load_en;
+	u32	mem_allign1[2];
+	u32	intstat_raw;
+	u32	intstat_masked;
+	u32	int_enable;
+	u32	mem_allign2;
+	u32	event_pop;
+	u32	event_low;
+	u32	event_high;
+};
+
+/*
+ * CPTS Events
+ */
+struct cpts_evts {
+	struct list_head	list;
+	u32			event_high;
+	u64			ts;
+	unsigned long		timeout;
+};
+
+/*
+ * Time Handle
+ */
+struct cpts_priv {
+	spinlock_t			lock;
+	struct ptp_clock		*ptp_clock;
+	struct ptp_clock_info		caps;
+	struct cpts_regs __iomem	*reg;
+	struct list_head		ts_list;
+	struct list_head		ts_pool;
+	struct cpts_evts		ts_pool_data[CPTS_TS_POOL_SIZE];
+	struct clk			*refclk;
+	u64				time_push;
+	bool				enable_txts;
+	bool				enable_rxts;
+	u32				tshi;
+	bool				first_half;
+	u32				initial_freq;
+	u32				time_offs_correction;
+};
+
+#ifdef CONFIG_TI_CPTS
+
+void cpts_rx_timestamp(struct cpts_priv *cpts, struct sk_buff *skb);
+void cpts_tx_timestamp(struct cpts_priv *cpts, struct sk_buff *skb);
+int cpts_register(struct device *dev, struct cpts_priv *cpts);
+void cpts_unregister(struct cpts_priv *cpts);
+void cpts_event_fifo_read(struct cpts_priv *cpts);
+
+#else
+
+#define cpts_rx_timestamp(cpts, skb)
+#define cpts_tx_timestamp(cpts, skb)
+#define cpts_register(dev, cpts) (-ENODEV)
+#define cpts_unregister(cpts)
+#define cpts_event_fifo_read(cpts)
+
+#endif
+
+#endif
-- 
1.7.0.4
^ permalink raw reply related	[flat|nested] 38+ messages in thread
* [PATCH 6/6] drivers: net: ethernet: cpsw: implement timestamping capabilities in cpsw
  2012-10-16 22:45 [PATCH 0/6] Add CPTS PTP driver support Mugunthan V N
                   ` (4 preceding siblings ...)
  2012-10-16 22:45 ` [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock Mugunthan V N
@ 2012-10-16 22:45 ` Mugunthan V N
  2012-10-21 18:11   ` Richard Cochran
  2012-10-21 18:46 ` [PATCH 0/6] Add CPTS PTP driver support Richard Cochran
  6 siblings, 1 reply; 38+ messages in thread
From: Mugunthan V N @ 2012-10-16 22:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, Richard Cochran, Mugunthan V N
This patch implements timestamping capabilities in cpsw through IOCTL interface
to enable and disable PTP time stamping and adds hardware time stamps to the
packet's skb buffer using cpts api
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 Documentation/devicetree/bindings/net/cpsw.txt |    3 +
 drivers/net/ethernet/ti/cpsw.c                 |  296 +++++++++++++++++++++++-
 include/linux/platform_data/cpsw.h             |    1 +
 3 files changed, 289 insertions(+), 11 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt
index dcaabe9..7111019 100644
--- a/Documentation/devicetree/bindings/net/cpsw.txt
+++ b/Documentation/devicetree/bindings/net/cpsw.txt
@@ -16,6 +16,7 @@ Required properties:
 - ale_entries		: Specifies No of entries ALE can hold
 - host_port_reg_ofs	: Specifies host port register offset
 - hw_stats_reg_ofs	: Specifies hardware statistics register offset
+- cpts_reg_ofs		: Specifies the offset of the CPTS registers
 - bd_ram_ofs		: Specifies internal desciptor RAM offset
 - bd_ram_size		: Specifies internal descriptor RAM size
 - rx_descs		: Specifies number of Rx descriptors
@@ -52,6 +53,7 @@ Examples:
 		ale_entries = <1024>;
 		host_port_reg_ofs = <0x108>;
 		hw_stats_reg_ofs = <0x900>;
+		cpts_reg_ofs = <0xc00>;
 		bd_ram_ofs = <0x2000>;
 		bd_ram_size = <0x2000>;
 		no_bd_ram = <0>;
@@ -86,6 +88,7 @@ Examples:
 		ale_entries = <1024>;
 		host_port_reg_ofs = <0x108>;
 		hw_stats_reg_ofs = <0x900>;
+		cpts_reg_ofs = <0xc00>;
 		bd_ram_ofs = <0x2000>;
 		bd_ram_size = <0x2000>;
 		no_bd_ram = <0>;
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index b6af1c6..45babaa 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -31,11 +31,13 @@
 #include <linux/of.h>
 #include <linux/of_net.h>
 #include <linux/of_device.h>
+#include <linux/net_tstamp.h>
 
 #include <linux/platform_data/cpsw.h>
 
 #include "cpsw_ale.h"
 #include "davinci_cpdma.h"
+#include "cpts.h"
 
 #define CPSW_DEBUG	(NETIF_MSG_HW		| NETIF_MSG_WOL		| \
 			 NETIF_MSG_DRV		| NETIF_MSG_LINK	| \
@@ -124,6 +126,41 @@ do {								\
 			disable_irq_nosync(priv->irqs_table[i]); \
 	} while (0);
 
+#define CPSW_MISC_INTR_EN		BIT(4)
+
+#define CPSW_EVT_SYNC_EN		BIT(0)
+#define CPSW_EVT_DELAY_REQ_EN		BIT(1)
+#define CPSW_EVT_PDELAY_REQ_EN		BIT(2)
+#define CPSW_EVT_PDELAY_RESP_EN		BIT(3)
+#define CPSW_EVT_MSG_TYPE_EN		(CPSW_EVT_SYNC_EN |		\
+					 CPSW_EVT_DELAY_REQ_EN |	\
+					 CPSW_EVT_PDELAY_REQ_EN |	\
+					 CPSW_EVT_PDELAY_RESP_EN)
+#define CPSW_V1_TS_RX_EN		BIT(0)
+#define CPSW_V1_TS_TX_EN		BIT(4)
+#define CPSW_V1_MSG_TYPE_OFS		16
+#define CPSW_V1_SEQ_ID_OFS_SHIFT	16
+
+#define CPSW_V2_TS_RX_EN		BIT(0)
+#define CPSW_V2_TS_TX_EN		BIT(1)
+#define CPSW_V2_TS_LTYPE_1_EN		BIT(2)
+#define CPSW_V2_TS_LTYPE_2_EN		BIT(3)
+#define CPSW_V2_TS_ANNEX_D_EN		BIT(4)
+#define CPSW_V2_TS_320			BIT(14)
+#define CPSW_V2_TS_319			BIT(13)
+#define CPSW_V2_TS_132			BIT(12)
+#define CPSW_V2_TS_131			BIT(11)
+#define CPSW_V2_TS_130			BIT(10)
+#define CPSW_V2_TS_129			BIT(9)
+#define CPSW_V2_TS_TTL			BIT(8)
+#define CPSW_V2_SEQ_ID_OFS_SHIFT	16
+#define CPSW_V2_TS_EN		(CPSW_V2_TS_ANNEX_D_EN |		\
+				CPSW_V2_TS_LTYPE_1_EN |			\
+				CPSW_V2_TS_320 | CPSW_V2_TS_319 |	\
+				CPSW_V2_TS_132 | CPSW_V2_TS_131 |	\
+				CPSW_V2_TS_130 | CPSW_V2_TS_129 |	\
+				CPSW_V2_TS_TTL)
+
 enum CPSW_SLAVE_REG_OFS {
 	MAX_BLKS,
 	BLK_CNT,
@@ -248,6 +285,7 @@ struct cpsw_priv {
 	struct cpsw_regs __iomem	*regs;
 	struct cpsw_ss_regs __iomem	*ss_regs;
 	struct cpsw_host_regs __iomem	*host_port_regs;
+	struct cpts_priv		*cpts;
 	u32				msg_enable;
 	struct net_device_stats		stats;
 	int				rx_packet_max;
@@ -263,6 +301,7 @@ struct cpsw_priv {
 	/* snapshot of IRQ numbers */
 	u32 irqs_table[4];
 	u32 num_irqs;
+	u32 statistics_irq;
 };
 
 #define napi_to_priv(napi)	container_of(napi, struct cpsw_priv, napi)
@@ -297,6 +336,180 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
 	}
 }
 
+#ifdef CONFIG_TI_CPTS
+
+#define cpts_interrupt(priv)						   \
+	do {								   \
+		if (unlikely(readl(&priv->cpts->reg->intstat_raw) & 0x01))  \
+			cpts_event_fifo_read(priv->cpts);		   \
+	} while (0)
+
+static int cpts_enable_ts(struct cpsw_priv *priv, bool tx_state, bool rx_state)
+{
+	u32 ts_en = 0;
+	u32 seq_id = 0;
+
+	if (priv->cpsw_version == CPSW_VERSION_1) {
+		if (tx_state || rx_state) {
+			/* Enable TS */
+			if (tx_state)
+				ts_en = CPSW_V1_TS_TX_EN;
+			if (rx_state)
+				ts_en |= CPSW_V1_TS_RX_EN;
+			ts_en |= CPSW_EVT_MSG_TYPE_EN << CPSW_V1_MSG_TYPE_OFS;
+
+			writel(ts_en, cpsw_slave_reg(priv, &priv->slaves[0],
+						   TS_CTL));
+			writel(ts_en, cpsw_slave_reg(priv, &priv->slaves[1],
+						   TS_CTL));
+
+			seq_id = (CPSW_SEQ_ID_OFS << CPSW_V1_SEQ_ID_OFS_SHIFT) |
+				CPSW_801_1Q_LTYPE;
+			writel(seq_id, cpsw_slave_reg(priv, &priv->slaves[0],
+						   TS_SEQ_LTYPE));
+			writel(seq_id, cpsw_slave_reg(priv, &priv->slaves[1],
+						   TS_SEQ_LTYPE));
+		} else {
+			/* Disable TS */
+			writel(0, cpsw_slave_reg(priv, &priv->slaves[0],
+						 TS_CTL));
+			writel(0, cpsw_slave_reg(priv, &priv->slaves[1],
+						 TS_CTL));
+		}
+	} else {
+		if (tx_state || rx_state) {
+			/* Enable TS */
+			if (tx_state)
+				ts_en = CPSW_V2_TS_TX_EN;
+			if (rx_state)
+				ts_en |= CPSW_V2_TS_RX_EN;
+			ts_en |= CPSW_V2_TS_EN;
+
+			writel(ts_en, cpsw_slave_reg(priv, &priv->slaves[0],
+						   PORT_CONTROL));
+			writel(ts_en, cpsw_slave_reg(priv, &priv->slaves[1],
+						   PORT_CONTROL));
+
+			seq_id = (CPSW_SEQ_ID_OFS << CPSW_V2_SEQ_ID_OFS_SHIFT) |
+				CPSW_EVT_MSG_TYPE_EN;
+			writel(seq_id, cpsw_slave_reg(priv, &priv->slaves[0],
+						   TS_SEQ_MTYPE));
+			writel(seq_id, cpsw_slave_reg(priv, &priv->slaves[1],
+						   TS_SEQ_MTYPE));
+
+			writel(CPSW_801_1Q_LTYPE, &priv->regs->ts_ltype);
+		} else {
+			/* Disable TS */
+			writel(0, cpsw_slave_reg(priv, &priv->slaves[0],
+						 PORT_CONTROL));
+			writel(0, cpsw_slave_reg(priv, &priv->slaves[1],
+						 PORT_CONTROL));
+
+			writel(0, cpsw_slave_reg(priv, &priv->slaves[0],
+						 TS_SEQ_MTYPE));
+			writel(0, cpsw_slave_reg(priv, &priv->slaves[1],
+						 TS_SEQ_MTYPE));
+		}
+	}
+
+	if (tx_state || rx_state)
+		pr_info("cpts: Enabling PTP Time stamping...\n");
+	else
+		pr_info("cpts: Disabling PTP Time stamping...\n");
+
+	return 0;
+}
+
+static int cpsw_hwtstamp_ioctl(struct net_device *ndev,
+		struct ifreq *ifr, int cmd)
+{
+	struct hwtstamp_config config;
+	struct cpsw_priv *priv = netdev_priv(ndev);
+
+	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+		return -EFAULT;
+
+	netdev_dbg(priv->ndev,
+		   "%s config flag:0x%x, tx_type:0x%x, rx_filter:0x%x\n",
+		   __func__, config.flags, config.tx_type, config.rx_filter);
+
+	/* reserved for future extensions */
+	if (config.flags)
+		return -EINVAL;
+
+	switch (config.tx_type) {
+	case HWTSTAMP_TX_OFF:
+		priv->cpts->enable_txts = false;
+		break;
+	case HWTSTAMP_TX_ON:
+		priv->cpts->enable_txts = true;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (config.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		/*
+		 * Don't allow any timestamping
+		 */
+		priv->cpts->enable_rxts = false;
+		break;
+
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+		netdev_err(priv->ndev,
+			   "PTP V1 L4 Timestamping is not supported!!!\n");
+		config.rx_filter = HWTSTAMP_FILTER_NONE;
+		config.tx_type = HWTSTAMP_TX_OFF;
+		break;
+
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+		if (priv->cpsw_version == CPSW_VERSION_1) {
+			netdev_err(priv->ndev,
+			       "PTP V1 L4 Timestamping is not supported!!!\n");
+			priv->cpts->enable_txts = false;
+			priv->cpts->enable_rxts = false;
+			break;
+		}
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+		if (priv->cpsw_version == CPSW_VERSION_1)
+			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+		else
+			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+		priv->cpts->enable_rxts = true;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	cpts_enable_ts(priv, priv->cpts->enable_txts, priv->cpts->enable_rxts);
+
+	return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+			-EFAULT : 0;
+}
+
+static inline void cpts_enable_hw_clock(struct cpsw_priv *priv)
+{
+	if (cpts_register(&priv->pdev->dev, priv->cpts) == 0)
+		/* Enable CPSW_SS Misc Interrupt */
+		writel(CPSW_MISC_INTR_EN, &priv->ss_regs->misc_en);
+}
+
+#else
+#define cpts_interrupt(priv)
+#define cpsw_hwtstamp_ioctl(ndev, ifr, cmd) (-EOPNOTSUPP)
+#define cpts_enable_hw_clock(priv)
+#endif
+
 static void cpsw_intr_enable(struct cpsw_priv *priv)
 {
 	__raw_writel(0xFF, &priv->ss_regs->tx_en);
@@ -323,6 +536,7 @@ void cpsw_tx_handler(void *token, int len, int status)
 
 	if (unlikely(netif_queue_stopped(ndev)))
 		netif_start_queue(ndev);
+	cpts_tx_timestamp(priv->cpts, skb);
 	priv->stats.tx_packets++;
 	priv->stats.tx_bytes += len;
 	dev_kfree_skb_any(skb);
@@ -343,6 +557,7 @@ void cpsw_rx_handler(void *token, int len, int status)
 	}
 	if (likely(status >= 0)) {
 		skb_put(skb, len);
+		cpts_rx_timestamp(priv->cpts, skb);
 		skb->protocol = eth_type_trans(skb, ndev);
 		netif_receive_skb(skb);
 		priv->stats.rx_bytes += len;
@@ -367,6 +582,16 @@ void cpsw_rx_handler(void *token, int len, int status)
 	WARN_ON(ret < 0);
 }
 
+static irqreturn_t cpsw_statistics_interrupt(int irq, void *dev_id)
+{
+	struct cpsw_priv *priv = dev_id;
+
+	cpts_interrupt(priv);
+
+	cpdma_ctlr_eoi_statistics(priv->dma);
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t cpsw_interrupt(int irq, void *dev_id)
 {
 	struct cpsw_priv *priv = dev_id;
@@ -618,6 +843,9 @@ static int cpsw_ndo_open(struct net_device *ndev)
 	/* continue even if we didn't manage to submit all receive descs */
 	cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i);
 
+	/* Enable CPTS clock */
+	cpts_enable_hw_clock(priv);
+
 	cpdma_ctlr_start(priv->dma);
 	cpsw_intr_enable(priv);
 	napi_enable(&priv->napi);
@@ -641,12 +869,14 @@ static int cpsw_ndo_stop(struct net_device *ndev)
 
 	cpsw_info(priv, ifdown, "shutting down cpsw device\n");
 	cpsw_intr_disable(priv);
+	disable_irq_nosync(priv->statistics_irq);
 	cpdma_ctlr_int_ctrl(priv->dma, false);
 	cpdma_ctlr_stop(priv->dma);
 	netif_stop_queue(priv->ndev);
 	napi_disable(&priv->napi);
 	netif_carrier_off(priv->ndev);
 	cpsw_ale_stop(priv->ale);
+	cpts_unregister(priv->cpts);
 	for_each_slave(priv, cpsw_slave_stop, priv);
 	pm_runtime_put_sync(&priv->pdev->dev);
 	return 0;
@@ -738,6 +968,23 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev)
 }
 #endif
 
+static int cpsw_ndo_do_ioctl(struct net_device *ndev, struct ifreq *ifrq,
+		int cmd)
+{
+	if (!(netif_running(ndev)))
+		return -EINVAL;
+
+	switch (cmd) {
+
+	case SIOCSHWTSTAMP:
+		return cpsw_hwtstamp_ioctl(ndev, ifrq, cmd);
+
+	default:
+		return -EOPNOTSUPP;
+	}
+	return 0;
+}
+
 static const struct net_device_ops cpsw_netdev_ops = {
 	.ndo_open		= cpsw_ndo_open,
 	.ndo_stop		= cpsw_ndo_stop,
@@ -748,6 +995,7 @@ static const struct net_device_ops cpsw_netdev_ops = {
 	.ndo_tx_timeout		= cpsw_ndo_tx_timeout,
 	.ndo_get_stats		= cpsw_ndo_get_stats,
 	.ndo_set_rx_mode	= cpsw_ndo_set_rx_mode,
+	.ndo_do_ioctl		= cpsw_ndo_do_ioctl,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= cpsw_ndo_poll_controller,
 #endif
@@ -874,6 +1122,13 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
 	}
 	data->hw_stats_reg_ofs = prop;
 
+	if (of_property_read_u32(node, "cpts_reg_ofs", &prop)) {
+		pr_err("Missing cpts_reg_ofs property in the DT.\n");
+		ret = -EINVAL;
+		goto error_ret;
+	}
+	data->cpts_reg_ofs = prop;
+
 	if (of_property_read_u32(node, "bd_ram_ofs", &prop)) {
 		pr_err("Missing bd_ram_ofs property in the DT.\n");
 		ret = -EINVAL;
@@ -952,7 +1207,6 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
 	struct cpdma_params		dma_params;
 	struct cpsw_ale_params		ale_params;
 	void __iomem			*regs;
-	struct resource			*res;
 	int ret = 0, i, k = 0;
 
 	ndev = alloc_etherdev(sizeof(struct cpsw_priv));
@@ -967,6 +1221,12 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
 	priv->pdev = pdev;
 	priv->ndev = ndev;
 	priv->dev  = &ndev->dev;
+	priv->cpts = devm_kzalloc(&pdev->dev, sizeof(struct cpts_priv),
+				  GFP_KERNEL);
+	if (!priv->cpts) {
+		ret = -EBUSY;
+		goto clean_ndev_ret;
+	}
 	priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
 	priv->rx_packet_max = max(rx_packet_max, 128);
 
@@ -1026,6 +1286,8 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
 	priv->regs = regs;
 	priv->host_port = data->host_port_num;
 	priv->host_port_regs = regs + data->host_port_reg_ofs;
+	/* Init CPTS Regs offsets */
+	priv->cpts->reg = regs + data->cpts_reg_ofs;
 
 	priv->cpsw_ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (!priv->cpsw_ss_res) {
@@ -1119,17 +1381,27 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
 		goto clean_ale_ret;
 	}
 
-	while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) {
-		for (i = res->start; i <= res->end; i++) {
-			if (request_irq(i, cpsw_interrupt, IRQF_DISABLED,
-					dev_name(&pdev->dev), priv)) {
-				dev_err(priv->dev, "error attaching irq\n");
-				goto clean_ale_ret;
-			}
-			priv->irqs_table[k] = i;
-			priv->num_irqs = k;
+	for (k = 0; (k < 3) ; k++) {
+		i = platform_get_irq(pdev, k);
+		if (i < 0)
+			continue;
+		if (request_irq(i, cpsw_interrupt, IRQF_DISABLED,
+				dev_name(&pdev->dev), priv)) {
+			dev_err(priv->dev, "error attaching irq\n");
+			goto clean_ale_ret;
+		}
+		priv->irqs_table[k] = i;
+		priv->num_irqs = k+1;
+	}
+
+	i = platform_get_irq(pdev, k);
+	if (i >= 0) {
+		if (request_irq(i, cpsw_statistics_interrupt, IRQF_DISABLED,
+				dev_name(&pdev->dev), priv)) {
+			dev_err(priv->dev, "error attaching irq\n");
+			goto clean_ale_ret;
 		}
-		k++;
+		priv->statistics_irq = i;
 	}
 
 	ndev->flags |= IFF_ALLMULTI;	/* see cpsw_ndo_change_rx_flags() */
@@ -1154,6 +1426,7 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
 
 clean_irq_ret:
 	free_irq(ndev->irq, priv);
+	free_irq(priv->statistics_irq, priv);
 clean_ale_ret:
 	cpsw_ale_destroy(priv->ale);
 clean_dma_ret:
@@ -1187,6 +1460,7 @@ static int __devexit cpsw_remove(struct platform_device *pdev)
 	platform_set_drvdata(pdev, NULL);
 
 	free_irq(ndev->irq, priv);
+	free_irq(priv->statistics_irq, priv);
 	cpsw_ale_destroy(priv->ale);
 	cpdma_chan_destroy(priv->txch);
 	cpdma_chan_destroy(priv->rxch);
diff --git a/include/linux/platform_data/cpsw.h b/include/linux/platform_data/cpsw.h
index c4e23d0..4b4b1b8 100644
--- a/include/linux/platform_data/cpsw.h
+++ b/include/linux/platform_data/cpsw.h
@@ -41,6 +41,7 @@ struct cpsw_platform_data {
 	u32     host_port_num; /* The port number for the host port */
 
 	u32	hw_stats_reg_ofs;  /* cpsw hardware statistics counters */
+	u32	cpts_reg_ofs;      /* cpts register offset */
 
 	u32	bd_ram_ofs;   /* embedded buffer descriptor RAM offset*/
 	u32	bd_ram_size;  /*buffer descriptor ram size */
-- 
1.7.0.4
^ permalink raw reply related	[flat|nested] 38+ messages in thread
* Re: [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb
  2012-10-16 22:45 ` [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb Mugunthan V N
@ 2012-10-16 23:10   ` Ben Hutchings
  2012-10-17 13:48     ` N, Mugunthan V
  2012-10-18  2:55   ` Richard Cochran
  1 sibling, 1 reply; 38+ messages in thread
From: Ben Hutchings @ 2012-10-16 23:10 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem, Richard Cochran
On Wed, 2012-10-17 at 04:15 +0530, Mugunthan V N wrote:
> Cc: Richard Cochran <richardcochran@gmail.com>
> Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
> ---
>  include/linux/ptp_classify.h |   42 ++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 42 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
> index 1dc420b..9b3b55b 100644
> --- a/include/linux/ptp_classify.h
> +++ b/include/linux/ptp_classify.h
> @@ -137,4 +137,46 @@ static inline int ptp_filter_init(struct sock_filter *f, int len)
>  	{OP_RETA,	0,   0, 0			}, /*              */ \
>  /*L6x*/	{OP_RETK,	0,   0, PTP_CLASS_NONE		},
>  
> +static inline int ptp_get_skb_event(struct sk_buff *skb, u32 ptp_class,
> +				    u16 *evt_seqid, u8 *evt_msgtype)
> +{
> +	u16 *seqid;
> +	unsigned int offset;
> +	u8 *msgtype, *data = skb->data;
> +
> +	switch (ptp_class) {
> +	case PTP_CLASS_V1_IPV4:
> +	case PTP_CLASS_V2_IPV4:
> +		offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
> +		break;
> +	case PTP_CLASS_V1_IPV6:
> +	case PTP_CLASS_V2_IPV6:
> +		offset = OFF_PTP6;
> +		break;
> +	case PTP_CLASS_V2_L2:
> +		offset = ETH_HLEN;
> +		break;
> +	case PTP_CLASS_V2_VLAN:
> +		offset = ETH_HLEN + VLAN_HLEN;
> +		break;
> +	default:
> +		return 0;
> +	}
> +
> +	if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid))
> +		return 0;
> +
> +	if (unlikely(ptp_class & PTP_CLASS_V1))
> +		msgtype = data + offset + OFF_PTP_CONTROL;
> +	else
> +		msgtype = data + offset;
> +
> +	seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
This assumes the skb is linear.  Use skb_header_pointer() to allow for
fragmented skbs.
Ben.
> +	*evt_seqid = ntohs(*seqid);
> +	*evt_msgtype = *msgtype & 0xf;
> +
> +	return 0;
> +}
> +
>  #endif
-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply	[flat|nested] 38+ messages in thread
* RE: [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb
  2012-10-16 23:10   ` Ben Hutchings
@ 2012-10-17 13:48     ` N, Mugunthan V
  0 siblings, 0 replies; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-17 13:48 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: netdev@vger.kernel.org, davem@davemloft.net, Richard Cochran
> -----Original Message-----
> From: Ben Hutchings [mailto:bhutchings@solarflare.com]
> Sent: Wednesday, October 17, 2012 4:41 AM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net; Richard Cochran
> Subject: Re: [PATCH 4/6] ptp: add api to get ptp seq id and event type
> from skb
> 
> On Wed, 2012-10-17 at 04:15 +0530, Mugunthan V N wrote:
> > Cc: Richard Cochran <richardcochran@gmail.com>
> > Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
> > ---
> >  include/linux/ptp_classify.h |   42
> ++++++++++++++++++++++++++++++++++++++++++
> >  1 files changed, 42 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/linux/ptp_classify.h
> b/include/linux/ptp_classify.h
> > index 1dc420b..9b3b55b 100644
> > --- a/include/linux/ptp_classify.h
> > +++ b/include/linux/ptp_classify.h
> > @@ -137,4 +137,46 @@ static inline int ptp_filter_init(struct
> sock_filter *f, int len)
> >  	{OP_RETA,	0,   0, 0			}, /*              */ \
> >  /*L6x*/	{OP_RETK,	0,   0, PTP_CLASS_NONE		},
> >
> > +static inline int ptp_get_skb_event(struct sk_buff *skb, u32
> ptp_class,
> > +				    u16 *evt_seqid, u8 *evt_msgtype)
> > +{
> > +	u16 *seqid;
> > +	unsigned int offset;
> > +	u8 *msgtype, *data = skb->data;
> > +
> > +	switch (ptp_class) {
> > +	case PTP_CLASS_V1_IPV4:
> > +	case PTP_CLASS_V2_IPV4:
> > +		offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
> > +		break;
> > +	case PTP_CLASS_V1_IPV6:
> > +	case PTP_CLASS_V2_IPV6:
> > +		offset = OFF_PTP6;
> > +		break;
> > +	case PTP_CLASS_V2_L2:
> > +		offset = ETH_HLEN;
> > +		break;
> > +	case PTP_CLASS_V2_VLAN:
> > +		offset = ETH_HLEN + VLAN_HLEN;
> > +		break;
> > +	default:
> > +		return 0;
> > +	}
> > +
> > +	if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID +
> sizeof(*seqid))
> > +		return 0;
> > +
> > +	if (unlikely(ptp_class & PTP_CLASS_V1))
> > +		msgtype = data + offset + OFF_PTP_CONTROL;
> > +	else
> > +		msgtype = data + offset;
> > +
> > +	seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
> 
> This assumes the skb is linear.  Use skb_header_pointer() to allow for
> fragmented skbs.
Will fix this in next version patch series
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version
  2012-10-16 22:45 ` [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version Mugunthan V N
@ 2012-10-18  2:45   ` Richard Cochran
  2012-10-22 10:39     ` N, Mugunthan V
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Cochran @ 2012-10-18  2:45 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem
On Wed, Oct 17, 2012 at 04:15:13AM +0530, Mugunthan V N wrote:
>  
> +#define CPSW_VERSION_1		0x19010a
> +#define CPSW_VERSION_2		0x19010c
Are you sure about these codes? What about 0x19010b?
I could not find them documented anywhere.
> +#define cpsw_slave_reg(priv, slave, reg)				\
> +	((slave)->regs + (priv)->slave_reg_ofs[(reg)])
> +
>  #define CPSW_MAJOR_VERSION(reg)		(reg >> 8 & 0x7)
>  #define CPSW_MINOR_VERSION(reg)		(reg & 0xff)
>  #define CPSW_RTL_VERSION(reg)		((reg >> 11) & 0x1f)
> @@ -117,6 +122,48 @@ do {								\
>  			disable_irq_nosync(priv->irqs_table[i]); \
>  	} while (0);
>  
> +enum CPSW_SLAVE_REG_OFS {
> +	MAX_BLKS,
> +	BLK_CNT,
> +	FLOW_THRESH,
> +	PORT_VLAN,
> +	TX_PRI_MAP,
> +	TS_CTL,
> +	TS_SEQ_LTYPE,
> +	TS_VLAN,
> +	SA_LO,
> +	SA_HI,
> +	PORT_CONTROL,
> +	TS_SEQ_MTYPE,
> +	TS_CONTROL,
> +};
> +
> +static const u32 slave_reg_map_ip_v1[] = {
> +	[MAX_BLKS]	= 0x00,
> +	[BLK_CNT]	= 0x04,
> +	[FLOW_THRESH]	= 0x08,
> +	[PORT_VLAN]	= 0x0c,
> +	[TX_PRI_MAP]	= 0x10,
> +	[TS_CTL]	= 0x14,
> +	[TS_SEQ_LTYPE]	= 0x18,
> +	[TS_VLAN]	= 0x1c,
> +	[SA_LO]		= 0x20,
> +	[SA_HI]		= 0x24,
> +};
> +
> +static const u32 slave_reg_map_ip_v2[] = {
> +	[PORT_CONTROL]	= 0x00,
> +	[TS_CONTROL]	= 0x04,
You don't make use of this register in your driver, so what is the
point?
> +	[MAX_BLKS]	= 0x08,
> +	[BLK_CNT]	= 0x0c,
> +	[FLOW_THRESH]	= 0x10,
> +	[PORT_VLAN]	= 0x14,
> +	[TX_PRI_MAP]	= 0x18,
> +	[TS_SEQ_MTYPE]	= 0x1c,
> +	[SA_LO]		= 0x20,
> +	[SA_HI]		= 0x24,
> +};
> +
This is wasting memory with unused static stables. There is a better
way to handle this issue.
>  static int debug_level;
>  module_param(debug_level, int, 0);
>  MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)");
> @@ -146,19 +193,13 @@ struct cpsw_regs {
>  	u32	soft_reset;
>  	u32	stat_port_en;
>  	u32	ptype;
> -};
> -
> -struct cpsw_slave_regs {
> -	u32	max_blks;
> -	u32	blk_cnt;
> -	u32	flow_thresh;
> -	u32	port_vlan;
> -	u32	tx_pri_map;
> -	u32	ts_ctl;
> -	u32	ts_seq_ltype;
> -	u32	ts_vlan;
> -	u32	sa_lo;
> -	u32	sa_hi;
> +	u32	soft_idle;
> +	u32	thru_rate;
> +	u32	gap_thresh;
> +	u32	tx_start_wds;
> +	u32	flow_control;
> +	u32	vlan_ltype;
> +	u32	ts_ltype;
>  };
>  
>  struct cpsw_host_regs {
> @@ -185,7 +226,7 @@ struct cpsw_sliver_regs {
>  };
>  
>  struct cpsw_slave {
> -	struct cpsw_slave_regs __iomem	*regs;
> +	void __iomem			*regs;
>  	struct cpsw_sliver_regs __iomem	*sliver;
>  	int				slave_num;
>  	u32				mac_control;
> @@ -215,6 +256,8 @@ struct cpsw_priv {
>  	struct cpdma_ctlr		*dma;
>  	struct cpdma_chan		*txch, *rxch;
>  	struct cpsw_ale			*ale;
> +	u32				cpsw_version;
> +	u32				*slave_reg_ofs;
>  	/* snapshot of IRQ numbers */
>  	u32 irqs_table[4];
>  	u32 num_irqs;
> @@ -359,8 +402,8 @@ static inline void soft_reset(const char *module, void __iomem *reg)
>  static void cpsw_set_slave_mac(struct cpsw_slave *slave,
>  			       struct cpsw_priv *priv)
>  {
> -	__raw_writel(mac_hi(priv->mac_addr), &slave->regs->sa_hi);
> -	__raw_writel(mac_lo(priv->mac_addr), &slave->regs->sa_lo);
> +	writel(mac_hi(priv->mac_addr), cpsw_slave_reg(priv, slave, SA_HI));
> +	writel(mac_lo(priv->mac_addr), cpsw_slave_reg(priv, slave, SA_LO));
>  }
>  
>  static void _cpsw_adjust_link(struct cpsw_slave *slave,
> @@ -445,8 +488,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
>  	soft_reset(name, &slave->sliver->soft_reset);
>  
>  	/* setup priority mapping */
> -	__raw_writel(RX_PRIORITY_MAPPING, &slave->sliver->rx_pri_map);
> -	__raw_writel(TX_PRIORITY_MAPPING, &slave->regs->tx_pri_map);
> +	writel(RX_PRIORITY_MAPPING, &slave->sliver->rx_pri_map);
> +	writel(TX_PRIORITY_MAPPING, cpsw_slave_reg(priv, slave, TX_PRI_MAP));
>  
>  	/* setup max packet size, and mac address */
>  	__raw_writel(priv->rx_packet_max, &slave->sliver->rx_maxlen);
> @@ -505,7 +548,12 @@ static int cpsw_ndo_open(struct net_device *ndev)
>  
>  	pm_runtime_get_sync(&priv->pdev->dev);
>  
> -	reg = __raw_readl(&priv->regs->id_ver);
> +	reg = readl(&priv->regs->id_ver);
> +	priv->cpsw_version = reg;
> +	if (reg == CPSW_VERSION_1)
> +		priv->slave_reg_ofs = (u32 *)slave_reg_map_ip_v1;
> +	else
> +		priv->slave_reg_ofs = (u32 *)slave_reg_map_ip_v2;
You didn't provide a way to even use this code, like a dts for a
non-am335x board with the older version.
I think it would be better to start off supporting one version and
have that fully working, and then add the older version, but *really*
add it so that it is actually working.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 2/6] drivers: net: ethernet: davinci_cpdma: add clear api for statistics interrupt
  2012-10-16 22:45 ` [PATCH 2/6] drivers: net: ethernet: davinci_cpdma: add clear api for statistics interrupt Mugunthan V N
@ 2012-10-18  2:48   ` Richard Cochran
  2012-10-22 10:42     ` N, Mugunthan V
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Cochran @ 2012-10-18  2:48 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem
On Wed, Oct 17, 2012 at 04:15:14AM +0530, Mugunthan V N wrote:
> Adding api to clear statistics interrupt which is generated by
> CPTS event pend, stat pend, mdio interrupts
As I said, we don't need or want the interrupt for the CPTS. If you
want to add this for the statistics function, go right ahead, but
please make a separate patch or series for that.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2012-10-16 22:45 ` [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Mugunthan V N
@ 2012-10-18  2:49   ` Richard Cochran
  2012-10-21 11:26   ` Richard Cochran
  1 sibling, 0 replies; 38+ messages in thread
From: Richard Cochran @ 2012-10-18  2:49 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem
On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
> Adding multicast address to ALE table via netdev ops to subscribe, transmit
> or receive multicast frames to and from the network
Is this somehow related to the time stamping function? If so, how?
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb
  2012-10-16 22:45 ` [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb Mugunthan V N
  2012-10-16 23:10   ` Ben Hutchings
@ 2012-10-18  2:55   ` Richard Cochran
  2012-10-22 10:46     ` N, Mugunthan V
  1 sibling, 1 reply; 38+ messages in thread
From: Richard Cochran @ 2012-10-18  2:55 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem
On Wed, Oct 17, 2012 at 04:15:16AM +0530, Mugunthan V N wrote:
> Cc: Richard Cochran <richardcochran@gmail.com>
> Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
> ---
>  include/linux/ptp_classify.h |   42 ++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 42 insertions(+), 0 deletions(-)
Sorry, but nak on this one. It is a bit way too long for a static
inline. Also, this driver-specific code, and it doesn't belong here.
Thanks,
Richard
 
> diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
> index 1dc420b..9b3b55b 100644
> --- a/include/linux/ptp_classify.h
> +++ b/include/linux/ptp_classify.h
> @@ -137,4 +137,46 @@ static inline int ptp_filter_init(struct sock_filter *f, int len)
>  	{OP_RETA,	0,   0, 0			}, /*              */ \
>  /*L6x*/	{OP_RETK,	0,   0, PTP_CLASS_NONE		},
>  
> +static inline int ptp_get_skb_event(struct sk_buff *skb, u32 ptp_class,
> +				    u16 *evt_seqid, u8 *evt_msgtype)
> +{
> +	u16 *seqid;
> +	unsigned int offset;
> +	u8 *msgtype, *data = skb->data;
> +
> +	switch (ptp_class) {
> +	case PTP_CLASS_V1_IPV4:
> +	case PTP_CLASS_V2_IPV4:
> +		offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
> +		break;
> +	case PTP_CLASS_V1_IPV6:
> +	case PTP_CLASS_V2_IPV6:
> +		offset = OFF_PTP6;
> +		break;
> +	case PTP_CLASS_V2_L2:
> +		offset = ETH_HLEN;
> +		break;
> +	case PTP_CLASS_V2_VLAN:
> +		offset = ETH_HLEN + VLAN_HLEN;
> +		break;
> +	default:
> +		return 0;
> +	}
> +
> +	if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid))
> +		return 0;
> +
> +	if (unlikely(ptp_class & PTP_CLASS_V1))
> +		msgtype = data + offset + OFF_PTP_CONTROL;
> +	else
> +		msgtype = data + offset;
> +
> +	seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
> +
> +	*evt_seqid = ntohs(*seqid);
> +	*evt_msgtype = *msgtype & 0xf;
> +
> +	return 0;
> +}
> +
>  #endif
> -- 
> 1.7.0.4
> 
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock
  2012-10-16 22:45 ` [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock Mugunthan V N
@ 2012-10-20 13:43   ` Richard Cochran
  2012-10-22 10:55     ` N, Mugunthan V
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Cochran @ 2012-10-20 13:43 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem
I did a careful read of this driver, and I found a number of issues,
but I am not giving a line by line review, for reasons explained
below. For the most part, your driver is very similar to mine, and
your driver would probably work fine too, when given a bit of review
and revision. However, in the end, it would end up looking nearly
identical to mine.
The issues about which you have voiced concern (counter roll over,
changing input clock frequency) are by no means unique to the CPTS.
The existing PHC drivers all handle these issues in a way consistent
with each other. New drivers should not invent their own solutions to
such problems.
If I had never written a CPTS driver and had seen your present
submission first, then I would be willing to help you get your driver
merged. But in my view, this work is already done, and so I am favoring
my own driver at this point.
Here is my suggestion for moving forward with support the CPTS:
- It is too early to support the CPTS v1 found on the DM81xx, since
  the CPSW support (including DT) is totally lacking. Judging from
  your present driver and the TRM, the differences are minimal and
  will be easy to add later on. For now, we can simply check the
  version register for v2.
- If you can get the patches needed to get the CPSW working merged
  during the present v3.7-rc interval, that would form a basis for
  getting the CPTS into v3.8. I tried to post the patches that I had
  collected, but I failed to get them all accepted. I really don't
  know the issues surrounding those patches at all, and so I would
  appreciate if you would take the lead and get this support merged.
- I will add a version check for CPTS v2 and integrate your CPSW
  multicast patch (and anything else you think is missing) into my own
  patch series. Once your background patches have appeared, I will
  post the CPTS series for net-next, in time for v3.8.
- Looking ahead, once you get a patch series to fully support the
  DM81xx CPSW, we can patch the CPTS too.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2012-10-16 22:45 ` [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Mugunthan V N
  2012-10-18  2:49   ` Richard Cochran
@ 2012-10-21 11:26   ` Richard Cochran
  2012-10-22 10:46     ` N, Mugunthan V
  1 sibling, 1 reply; 38+ messages in thread
From: Richard Cochran @ 2012-10-21 11:26 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem
On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
> @@ -271,6 +273,30 @@ struct cpsw_priv {
>  			(func)((priv)->slaves + idx, ##arg);	\
>  	} while (0)
>  
> +static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
> +{
> +	struct cpsw_priv *priv = netdev_priv(ndev);
> +
> +	if (ndev->flags & IFF_PROMISC) {
> +		/* Enable promiscuous mode */
> +		dev_err(priv->dev, "Ignoring Promiscuous mode\n");
> +		return;
Why can't we support promiscuous mode here?
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 6/6] drivers: net: ethernet: cpsw: implement timestamping capabilities in cpsw
  2012-10-16 22:45 ` [PATCH 6/6] drivers: net: ethernet: cpsw: implement timestamping capabilities in cpsw Mugunthan V N
@ 2012-10-21 18:11   ` Richard Cochran
  0 siblings, 0 replies; 38+ messages in thread
From: Richard Cochran @ 2012-10-21 18:11 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem
On Wed, Oct 17, 2012 at 04:15:18AM +0530, Mugunthan V N wrote:
> This patch implements timestamping capabilities in cpsw through IOCTL interface
> to enable and disable PTP time stamping and adds hardware time stamps to the
> packet's skb buffer using cpts api
Just out of curiosity, I compiled and booted this patch series, but it
does not work. The CPTS driver fails with
   [ 1.901459] Missing cpts_reg_ofs property in the DT.
   [ 1.906835] cpsw: platform data missing
so I think you forgot to patch the dts files.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 0/6] Add CPTS PTP driver support
  2012-10-16 22:45 [PATCH 0/6] Add CPTS PTP driver support Mugunthan V N
                   ` (5 preceding siblings ...)
  2012-10-16 22:45 ` [PATCH 6/6] drivers: net: ethernet: cpsw: implement timestamping capabilities in cpsw Mugunthan V N
@ 2012-10-21 18:46 ` Richard Cochran
  2012-10-22 10:51   ` N, Mugunthan V
  6 siblings, 1 reply; 38+ messages in thread
From: Richard Cochran @ 2012-10-21 18:46 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev, davem
On Wed, Oct 17, 2012 at 04:15:12AM +0530, Mugunthan V N wrote:
> This patch series contains driver implementation for TI Common Platform
> Time Sync (CPTS) driver for PTP packet timestamping.
> 
> CPTS is found in following TI SoC.
> * AM335X - http://www.ti.com/litv/pdf/spruh73c
> * DM814X - http://www.ti.com/litv/pdf/sprugz8
> 
> The Common Platform Time Sync (CPTS) module is used to facilitate host
> control of time sync operations. It enables compliance with the IEEE 1588-2008
> standard for a precision clock synchronization protocol
> 
> This patch series is tested over vanilla kernel with the below patches
> http://marc.info/?l=linux-arm-kernel&m=135032863723906&w=2
I tried v3.7-rc1 plus those patches, plus this patch series, plus the
small addition of this ...
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index f6bea04..e0e152b 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -222,6 +222,7 @@
 			ale_entries = <1024>;
 			host_port_reg_ofs = <0x108>;
 			hw_stats_reg_ofs = <0x900>;
+			cpts_reg_ofs = <0xc00>;
 			bd_ram_ofs = <0x2000>;
 			bd_ram_size = <0x2000>;
 			no_bd_ram = <0>;
... and it doesn't work. 
> Tested both L2 and L4 PTP packet timestamping
Really?
With your driver I could not get either L2 or L4 time stamps to
appear. At this point, my own driver is working a lot better, and so
this just adds another reason to favor my driver, in addtion to the
points I mentioned in my other post.
Thanks,
Richard
^ permalink raw reply related	[flat|nested] 38+ messages in thread
* RE: [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version
  2012-10-18  2:45   ` Richard Cochran
@ 2012-10-22 10:39     ` N, Mugunthan V
  2012-10-22 11:23       ` Richard Cochran
  0 siblings, 1 reply; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-22 10:39 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Thursday, October 18, 2012 8:15 AM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 1/6] drivers: net: ethernet: cpsw: add support for
> CPSW register offset changes in different IP version
> 
> On Wed, Oct 17, 2012 at 04:15:13AM +0530, Mugunthan V N wrote:
> >
> > +
> > +static const u32 slave_reg_map_ip_v2[] = {
> > +	[PORT_CONTROL]	= 0x00,
> > +	[TS_CONTROL]	= 0x04,
> 
> You don't make use of this register in your driver, so what is the
> point?
This register is used in next version of CPSW. Since I don't use it in
current version I will remove the same in next version patch series.
> 
> > +	[MAX_BLKS]	= 0x08,
> > +	[BLK_CNT]	= 0x0c,
> > +	[FLOW_THRESH]	= 0x10,
> > +	[PORT_VLAN]	= 0x14,
> > +	[TX_PRI_MAP]	= 0x18,
> > +	[TS_SEQ_MTYPE]	= 0x1c,
> > +	[SA_LO]		= 0x20,
> > +	[SA_HI]		= 0x24,
> > +};
> > +
> 
> This is wasting memory with unused static stables. There is a better
> way to handle this issue.
I have taken the code reference from the following driver.
drivers/i2c/busses/i2c-omap.c
Can you refer other better solution to handle this?
> 
> >  static int debug_level;
> >  module_param(debug_level, int, 0);
> >  MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)");
>  	pm_runtime_get_sync(&priv->pdev->dev);
> >
> > -	reg = __raw_readl(&priv->regs->id_ver);
> > +	reg = readl(&priv->regs->id_ver);
> > +	priv->cpsw_version = reg;
> > +	if (reg == CPSW_VERSION_1)
> > +		priv->slave_reg_ofs = (u32 *)slave_reg_map_ip_v1;
> > +	else
> > +		priv->slave_reg_ofs = (u32 *)slave_reg_map_ip_v2;
> 
> You didn't provide a way to even use this code, like a dts for a
> non-am335x board with the older version.
> 
> I think it would be better to start off supporting one version and
> have that fully working, and then add the older version, but *really*
> add it so that it is actually working.
> 
Since version info from hardware registers can be used to differentiate between
the CPSW versions so I don't think there is a need to provide the same through DT.
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 38+ messages in thread
* RE: [PATCH 2/6] drivers: net: ethernet: davinci_cpdma: add clear api for statistics interrupt
  2012-10-18  2:48   ` Richard Cochran
@ 2012-10-22 10:42     ` N, Mugunthan V
  2012-10-22 11:31       ` Richard Cochran
  0 siblings, 1 reply; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-22 10:42 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Thursday, October 18, 2012 8:18 AM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 2/6] drivers: net: ethernet: davinci_cpdma: add
> clear api for statistics interrupt
> 
> On Wed, Oct 17, 2012 at 04:15:14AM +0530, Mugunthan V N wrote:
> > Adding api to clear statistics interrupt which is generated by
> > CPTS event pend, stat pend, mdio interrupts
> 
> As I said, we don't need or want the interrupt for the CPTS. If you
> want to add this for the statistics function, go right ahead, but
> please make a separate patch or series for that.
> 
What happens when Hardware timestamps are used? It will be good to
notify the application immediately using the interrupts instead of
using workqueue which can delay the event in hardware for max about
HZ*8.
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 38+ messages in thread
* RE: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2012-10-21 11:26   ` Richard Cochran
@ 2012-10-22 10:46     ` N, Mugunthan V
  0 siblings, 0 replies; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-22 10:46 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Sunday, October 21, 2012 4:56 PM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast
> address to ALE table
> 
> On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
> > @@ -271,6 +273,30 @@ struct cpsw_priv {
> >  			(func)((priv)->slaves + idx, ##arg);	\
> >  	} while (0)
> >
> > +static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
> > +{
> > +	struct cpsw_priv *priv = netdev_priv(ndev);
> > +
> > +	if (ndev->flags & IFF_PROMISC) {
> > +		/* Enable promiscuous mode */
> > +		dev_err(priv->dev, "Ignoring Promiscuous mode\n");
> > +		return;
> 
> Why can't we support promiscuous mode here?
> 
To support promiscuous mode, ALE has to be disabled and but this will
lead to disabling Switch functionality in hardware. So this is not
implemented as of now, It is under development.
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 38+ messages in thread
* RE: [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb
  2012-10-18  2:55   ` Richard Cochran
@ 2012-10-22 10:46     ` N, Mugunthan V
  2012-10-22 11:36       ` Richard Cochran
  0 siblings, 1 reply; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-22 10:46 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Thursday, October 18, 2012 8:25 AM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 4/6] ptp: add api to get ptp seq id and event type
> from skb
> 
> On Wed, Oct 17, 2012 at 04:15:16AM +0530, Mugunthan V N wrote:
> > Cc: Richard Cochran <richardcochran@gmail.com>
> > Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
> > ---
> >  include/linux/ptp_classify.h |   42
> ++++++++++++++++++++++++++++++++++++++++++
> >  1 files changed, 42 insertions(+), 0 deletions(-)
> 
> Sorry, but nak on this one. It is a bit way too long for a static
> inline. Also, this driver-specific code, and it doesn't belong here.
> 
Yeah agreed on static function too long, but this can be kept inside PTP
frame work as every driver needs to use this API to parse the PTP events
from the skb.
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 38+ messages in thread
* RE: [PATCH 0/6] Add CPTS PTP driver support
  2012-10-21 18:46 ` [PATCH 0/6] Add CPTS PTP driver support Richard Cochran
@ 2012-10-22 10:51   ` N, Mugunthan V
  0 siblings, 0 replies; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-22 10:51 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Monday, October 22, 2012 12:16 AM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 0/6] Add CPTS PTP driver support
> 
> On Wed, Oct 17, 2012 at 04:15:12AM +0530, Mugunthan V N wrote:
> > This patch series contains driver implementation for TI Common
> Platform
> > Time Sync (CPTS) driver for PTP packet timestamping.
> >
> > CPTS is found in following TI SoC.
> > * AM335X - http://www.ti.com/litv/pdf/spruh73c
> > * DM814X - http://www.ti.com/litv/pdf/sprugz8
> >
> > The Common Platform Time Sync (CPTS) module is used to facilitate
> host
> > control of time sync operations. It enables compliance with the IEEE
> 1588-2008
> > standard for a precision clock synchronization protocol
> >
> > This patch series is tested over vanilla kernel with the below
> patches
> > http://marc.info/?l=linux-arm-kernel&m=135032863723906&w=2
> 
> I tried v3.7-rc1 plus those patches, plus this patch series, plus the
> small addition of this ...
> 
> diff --git a/arch/arm/boot/dts/am33xx.dtsi
> b/arch/arm/boot/dts/am33xx.dtsi
> index f6bea04..e0e152b 100644
> --- a/arch/arm/boot/dts/am33xx.dtsi
> +++ b/arch/arm/boot/dts/am33xx.dtsi
> @@ -222,6 +222,7 @@
>  			ale_entries = <1024>;
>  			host_port_reg_ofs = <0x108>;
>  			hw_stats_reg_ofs = <0x900>;
> +			cpts_reg_ofs = <0xc00>;
>  			bd_ram_ofs = <0x2000>;
>  			bd_ram_size = <0x2000>;
>  			no_bd_ram = <0>;
> 
> 
> ... and it doesn't work.
> 
> > Tested both L2 and L4 PTP packet timestamping
> 
> Really?
> 
> With your driver I could not get either L2 or L4 time stamps to
> appear. At this point, my own driver is working a lot better, and so
> this just adds another reason to favor my driver, in addtion to the
> points I mentioned in my other post.
> 
Richard
The following patch n eeds to be used to test the CPTS driver.
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index f6bea04..cd9b3b4 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -238,13 +238,13 @@
 			interrupts = <40 41 42 43>;
 			ranges;
 			cpsw_emac0: slave@0 {
-				slave_reg_ofs = <0x208>;
+				slave_reg_ofs = <0x200>;
 				sliver_reg_ofs = <0xd80>;
 				/* Filled in by U-Boot */
 				mac-address = [ 00 00 00 00 00 00 ];
 			};
 			cpsw_emac1: slave@1 {
-				slave_reg_ofs = <0x308>;
+				slave_reg_ofs = <0x300>;
 				sliver_reg_ofs = <0xdc0>;
 				/* Filled in by U-Boot */
 				mac-address = [ 00 00 00 00 00 00 ];
I have not added the above two patches in the patch series as the main
CPSW DT file patch is not accepted and not available in netdev git tree.
I have planned to post the patch series to DT mailing list soon after
the driver is accepted.
Sorry for not mentioning the same in the patch series
Regards
Mugunthan V N
^ permalink raw reply related	[flat|nested] 38+ messages in thread
* RE: [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock
  2012-10-20 13:43   ` Richard Cochran
@ 2012-10-22 10:55     ` N, Mugunthan V
  2012-10-22 11:41       ` Richard Cochran
                         ` (2 more replies)
  0 siblings, 3 replies; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-22 10:55 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Saturday, October 20, 2012 7:14 PM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts
> hardware clock
> 
> 
> I did a careful read of this driver, and I found a number of issues,
> but I am not giving a line by line review, for reasons explained
> below. For the most part, your driver is very similar to mine, and
> your driver would probably work fine too, when given a bit of review
> and revision. However, in the end, it would end up looking nearly
> identical to mine.
> 
> The issues about which you have voiced concern (counter roll over,
> changing input clock frequency) are by no means unique to the CPTS.
> The existing PHC drivers all handle these issues in a way consistent
> with each other. New drivers should not invent their own solutions to
> such problems.
> 
> If I had never written a CPTS driver and had seen your present
> submission first, then I would be willing to help you get your driver
> merged. But in my view, this work is already done, and so I am favoring
> my own driver at this point.
> 
> Here is my suggestion for moving forward with support the CPTS:
> 
> - It is too early to support the CPTS v1 found on the DM81xx, since
>   the CPSW support (including DT) is totally lacking. Judging from
>   your present driver and the TRM, the differences are minimal and
>   will be easy to add later on. For now, we can simply check the
>   version register for v2.
> 
> - If you can get the patches needed to get the CPSW working merged
>   during the present v3.7-rc interval, that would form a basis for
>   getting the CPTS into v3.8. I tried to post the patches that I had
>   collected, but I failed to get them all accepted. I really don't
>   know the issues surrounding those patches at all, and so I would
>   appreciate if you would take the lead and get this support merged.
> 
> - I will add a version check for CPTS v2 and integrate your CPSW
>   multicast patch (and anything else you think is missing) into my own
>   patch series. Once your background patches have appeared, I will
>   post the CPTS series for net-next, in time for v3.8.
The CPTS found in DM81XX and AM335X is of same version, only the CPSW version
is different in both SoCs.
Regards
Mugunthan V N
> 
> - Looking ahead, once you get a patch series to fully support the
>   DM81xx CPSW, we can patch the CPTS too.
> 
> Thanks,
> Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version
  2012-10-22 10:39     ` N, Mugunthan V
@ 2012-10-22 11:23       ` Richard Cochran
  2012-10-22 12:19         ` N, Mugunthan V
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Cochran @ 2012-10-22 11:23 UTC (permalink / raw)
  To: N, Mugunthan V; +Cc: netdev@vger.kernel.org, davem@davemloft.net
On Mon, Oct 22, 2012 at 10:39:51AM +0000, N, Mugunthan V wrote:
> > This is wasting memory with unused static stables. There is a better
> > way to handle this issue.
> 
> I have taken the code reference from the following driver.
> drivers/i2c/busses/i2c-omap.c
Can't speak for that driver.
BTW the ALE driver is also horribly wasting space with the "struct
ale_control_info ale_controls[ALE_NUM_CONTROLS]" thing.
 
> Can you refer other better solution to handle this?
Yes, I can think of two different ways. Maybe you can think of yet
other ways.
1. For those few registers that are not aligned the same way but have
   the same bit layout (and you actually use in the driver), keep a
   separate pointer in your driver's private struct.
2. Make two different declarations of structs corresponding to two
   register layouts and use a cast in the access function based on
   version.
I object to the tables of offsets because these take up twice the
memory of the registers themselves, even if you don't use all of the
registers.
> > You didn't provide a way to even use this code, like a dts for a
> > non-am335x board with the older version.
> > 
> > I think it would be better to start off supporting one version and
> > have that fully working, and then add the older version, but *really*
> > add it so that it is actually working.
> > 
> 
> Since version info from hardware registers can be used to differentiate between
> the CPSW versions so I don't think there is a need to provide the same through DT.
I did not say to put the versions into the DT.
What I meant was that there is no need to add code that tests the
version and acts differently, if there are no users of the special
cases.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 2/6] drivers: net: ethernet: davinci_cpdma: add clear api for statistics interrupt
  2012-10-22 10:42     ` N, Mugunthan V
@ 2012-10-22 11:31       ` Richard Cochran
  0 siblings, 0 replies; 38+ messages in thread
From: Richard Cochran @ 2012-10-22 11:31 UTC (permalink / raw)
  To: N, Mugunthan V; +Cc: netdev@vger.kernel.org, davem@davemloft.net
On Mon, Oct 22, 2012 at 10:42:26AM +0000, N, Mugunthan V wrote:
> 
> What happens when Hardware timestamps are used?
They are not being used.
> It will be good to
> notify the application immediately using the interrupts instead of
> using workqueue which can delay the event in hardware for max about
> HZ*8.
Yes, it would make sense to use the interrupt in that case, but I did
not see any code supporting external events. In any case, I still want
to handle the overflow in the same way as in the other PHC drivers,
for the sake of consistency, and to avoid wasting CPU time "in
interrupt" with silly counter overflow code.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb
  2012-10-22 10:46     ` N, Mugunthan V
@ 2012-10-22 11:36       ` Richard Cochran
  2012-10-22 12:32         ` N, Mugunthan V
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Cochran @ 2012-10-22 11:36 UTC (permalink / raw)
  To: N, Mugunthan V; +Cc: netdev@vger.kernel.org, davem@davemloft.net
On Mon, Oct 22, 2012 at 10:46:50AM +0000, N, Mugunthan V wrote:
> 
> Yeah agreed on static function too long, but this can be kept inside PTP
> frame work as every driver needs to use this API to parse the PTP events
> from the skb.
No, not every driver need this code. Otherwise it would already exist
in every driver.
Although some of the hardware does provide packet metadata for
matching time stamps to payloads, each hardware that I know of has its
own subtle differences in this regard.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock
  2012-10-22 10:55     ` N, Mugunthan V
@ 2012-10-22 11:41       ` Richard Cochran
  2012-10-22 11:44       ` Richard Cochran
  2012-10-22 11:46       ` Richard Cochran
  2 siblings, 0 replies; 38+ messages in thread
From: Richard Cochran @ 2012-10-22 11:41 UTC (permalink / raw)
  To: N, Mugunthan V; +Cc: netdev@vger.kernel.org, davem@davemloft.net
On Mon, Oct 22, 2012 at 10:55:55AM +0000, N, Mugunthan V wrote:
> > - I will add a version check for CPTS v2 and integrate your CPSW
> >   multicast patch (and anything else you think is missing) into my own
> >   patch series. Once your background patches have appeared, I will
> >   post the CPTS series for net-next, in time for v3.8.
> 
> The CPTS found in DM81XX and AM335X is of same version, only the CPSW version
> is different in both SoCs.
Okay, good, so we can keep the differences within the CPSW driver.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock
  2012-10-22 10:55     ` N, Mugunthan V
  2012-10-22 11:41       ` Richard Cochran
@ 2012-10-22 11:44       ` Richard Cochran
  2012-10-22 12:38         ` N, Mugunthan V
  2012-10-22 11:46       ` Richard Cochran
  2 siblings, 1 reply; 38+ messages in thread
From: Richard Cochran @ 2012-10-22 11:44 UTC (permalink / raw)
  To: N, Mugunthan V; +Cc: netdev@vger.kernel.org, davem@davemloft.net
On Mon, Oct 22, 2012 at 10:55:55AM +0000, N, Mugunthan V wrote:
> 
> The CPTS found in DM81XX and AM335X is of same version, only the CPSW version
> is different in both SoCs.
Actually, the CPTS appears to be different between DM81XX and AM335X.
The DM81XX has a CPTS_RFTCLK_SEL which is not found in the AM335X.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock
  2012-10-22 10:55     ` N, Mugunthan V
  2012-10-22 11:41       ` Richard Cochran
  2012-10-22 11:44       ` Richard Cochran
@ 2012-10-22 11:46       ` Richard Cochran
  2012-10-22 12:42         ` N, Mugunthan V
  2 siblings, 1 reply; 38+ messages in thread
From: Richard Cochran @ 2012-10-22 11:46 UTC (permalink / raw)
  To: N, Mugunthan V; +Cc: netdev@vger.kernel.org, davem@davemloft.net
On Mon, Oct 22, 2012 at 10:55:55AM +0000, N, Mugunthan V wrote:
> > -----Original Message-----
> > From: Richard Cochran [mailto:richardcochran@gmail.com]
> > - If you can get the patches needed to get the CPSW working merged
> >   during the present v3.7-rc interval, that would form a basis for
> >   getting the CPTS into v3.8. I tried to post the patches that I had
> >   collected, but I failed to get them all accepted. I really don't
> >   know the issues surrounding those patches at all, and so I would
> >   appreciate if you would take the lead and get this support merged.
What do you think about this?
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* RE: [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version
  2012-10-22 11:23       ` Richard Cochran
@ 2012-10-22 12:19         ` N, Mugunthan V
  2012-10-22 12:25           ` Richard Cochran
  0 siblings, 1 reply; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-22 12:19 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Monday, October 22, 2012 4:54 PM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 1/6] drivers: net: ethernet: cpsw: add support for
> CPSW register offset changes in different IP version
> 
> On Mon, Oct 22, 2012 at 10:39:51AM +0000, N, Mugunthan V wrote:
> > > This is wasting memory with unused static stables. There is a
> better
> > > way to handle this issue.
> >
> > I have taken the code reference from the following driver.
> > drivers/i2c/busses/i2c-omap.c
> 
> Can't speak for that driver.
> 
> BTW the ALE driver is also horribly wasting space with the "struct
> ale_control_info ale_controls[ALE_NUM_CONTROLS]" thing.
> 
> > Can you refer other better solution to handle this?
> 
> Yes, I can think of two different ways. Maybe you can think of yet
> other ways.
> 
> 1. For those few registers that are not aligned the same way but have
>    the same bit layout (and you actually use in the driver), keep a
>    separate pointer in your driver's private struct.
> 
> 2. Make two different declarations of structs corresponding to two
>    register layouts and use a cast in the access function based on
>    version.
> 
> I object to the tables of offsets because these take up twice the
> memory of the registers themselves, even if you don't use all of the
> registers.
> 
> > > You didn't provide a way to even use this code, like a dts for a
> > > non-am335x board with the older version.
> > >
> > > I think it would be better to start off supporting one version and
> > > have that fully working, and then add the older version, but
> *really*
> > > add it so that it is actually working.
> > >
> >
> > Since version info from hardware registers can be used to
> differentiate between
> > the CPSW versions so I don't think there is a need to provide the
> same through DT.
> 
> I did not say to put the versions into the DT.
> 
> What I meant was that there is no need to add code that tests the
> version and acts differently, if there are no users of the special
> cases.
> 
Only the slave register offsets are different, so once slave register
offset is taken care in CPSW driver, then we can directly use CPSW
when DM81XX base port patches are available for vanilla kernel.
No need to revisit the driver again when bringing up DM81XX.
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version
  2012-10-22 12:19         ` N, Mugunthan V
@ 2012-10-22 12:25           ` Richard Cochran
  0 siblings, 0 replies; 38+ messages in thread
From: Richard Cochran @ 2012-10-22 12:25 UTC (permalink / raw)
  To: N, Mugunthan V; +Cc: netdev@vger.kernel.org, davem@davemloft.net
On Mon, Oct 22, 2012 at 12:19:44PM +0000, N, Mugunthan V wrote:
> 
> Only the slave register offsets are different, so once slave register
> offset is taken care in CPSW driver, then we can directly use CPSW
> when DM81XX base port patches are available for vanilla kernel.
> No need to revisit the driver again when bringing up DM81XX.
Fine with me. It is really up to you how and when you want to get the
CPSW working, if ever.
But at this rate, it won't be working in v3.7, not even for am335x,
and v3.8 isn't looking too good either.
Oh well,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* RE: [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb
  2012-10-22 11:36       ` Richard Cochran
@ 2012-10-22 12:32         ` N, Mugunthan V
  2012-10-22 12:37           ` Richard Cochran
  0 siblings, 1 reply; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-22 12:32 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Monday, October 22, 2012 5:06 PM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 4/6] ptp: add api to get ptp seq id and event type
> from skb
> 
> On Mon, Oct 22, 2012 at 10:46:50AM +0000, N, Mugunthan V wrote:
> >
> > Yeah agreed on static function too long, but this can be kept inside
> PTP
> > frame work as every driver needs to use this API to parse the PTP
> events
> > from the skb.
> 
> No, not every driver need this code. Otherwise it would already exist
> in every driver.
> 
> Although some of the hardware does provide packet metadata for
> matching time stamps to payloads, each hardware that I know of has its
> own subtle differences in this regard.
> 
Ok, will move this code to CPTS driver itself.
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb
  2012-10-22 12:32         ` N, Mugunthan V
@ 2012-10-22 12:37           ` Richard Cochran
  0 siblings, 0 replies; 38+ messages in thread
From: Richard Cochran @ 2012-10-22 12:37 UTC (permalink / raw)
  To: N, Mugunthan V; +Cc: netdev@vger.kernel.org, davem@davemloft.net
On Mon, Oct 22, 2012 at 12:32:20PM +0000, N, Mugunthan V wrote:
> 
> Ok, will move this code to CPTS driver itself.
No need to fix this, since, as I already told you, I am going ahead
with my own CPTS driver.
BTW, maybe you could take a closer look at it and see what could be
improved?
Thanks,
Richard
^ permalink raw reply	[flat|nested] 38+ messages in thread
* RE: [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock
  2012-10-22 11:44       ` Richard Cochran
@ 2012-10-22 12:38         ` N, Mugunthan V
  0 siblings, 0 replies; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-22 12:38 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Monday, October 22, 2012 5:15 PM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts
> hardware clock
> 
> On Mon, Oct 22, 2012 at 10:55:55AM +0000, N, Mugunthan V wrote:
> >
> > The CPTS found in DM81XX and AM335X is of same version, only the CPSW
> version
> > is different in both SoCs.
> 
> Actually, the CPTS appears to be different between DM81XX and AM335X.
> 
> The DM81XX has a CPTS_RFTCLK_SEL which is not found in the AM335X.
> 
CPTS ref clock is not part of CPTS module, its external to CPTS module.
During IP integration, this ref clock can be connected to any clock
available. In AM335X this ref clock is tied to 250MHz clock, in DM81XX
the same is connected to a MUX where the CPTS ref clock can be programmed.
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 38+ messages in thread
* RE: [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock
  2012-10-22 11:46       ` Richard Cochran
@ 2012-10-22 12:42         ` N, Mugunthan V
  0 siblings, 0 replies; 38+ messages in thread
From: N, Mugunthan V @ 2012-10-22 12:42 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev@vger.kernel.org, davem@davemloft.net
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Monday, October 22, 2012 5:17 PM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; davem@davemloft.net
> Subject: Re: [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts
> hardware clock
> 
> On Mon, Oct 22, 2012 at 10:55:55AM +0000, N, Mugunthan V wrote:
> > > -----Original Message-----
> > > From: Richard Cochran [mailto:richardcochran@gmail.com]
> 
> > > - If you can get the patches needed to get the CPSW working merged
> > >   during the present v3.7-rc interval, that would form a basis for
> > >   getting the CPTS into v3.8. I tried to post the patches that I
> had
> > >   collected, but I failed to get them all accepted. I really don't
> > >   know the issues surrounding those patches at all, and so I would
> > >   appreciate if you would take the lead and get this support
> merged.
> 
> What do you think about this?
Vaibhav H will be submitting follow up patches which were removed when
you have submitted the patch series. He should be pushing patches in v3.7-rc
itself
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
@ 2014-09-02 18:22 Graeme Smecher
  2014-09-03  8:28 ` Mugunthan V N
  0 siblings, 1 reply; 38+ messages in thread
From: Graeme Smecher @ 2014-09-02 18:22 UTC (permalink / raw)
  To: netdev; +Cc: Mugunthan V N
Hi Mugunthan,
> On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
> > Adding multicast address to ALE table via netdev ops to subscribe, transmit
> > or receive multicast frames to and from the network
> 
> Is this somehow related to the time stamping function? If so, how?
> 
> Thanks,
> Richard
Can you give me a brief description of this (relatively ancient) patch? Your
original e-mail is visible here:
	http://marc.info/?l=linux-netdev&m=135042754927177&w=2
I'm wondering if this patch needs to be backported to older CPSW driver
snapshots (specifically, TI's 2.6.37 branch for dm81xx.) It appears to
fix a multicast bug I'm tracking down, but it's difficult to know for
sure without a good description of what problem the patch addresses. (I
don't want to commit code that fixes my hardware by accident.)
For a little more information, you can refer to my e2e.ti.com post:
	http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/365586.aspx
I'm slowly learning about ALE filtering, but a quick reply from a
domain expert would be very helpful.
best,
Graeme
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2014-09-02 18:22 [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Graeme Smecher
@ 2014-09-03  8:28 ` Mugunthan V N
  2014-09-03 19:01   ` Graeme Smecher
  0 siblings, 1 reply; 38+ messages in thread
From: Mugunthan V N @ 2014-09-03  8:28 UTC (permalink / raw)
  To: Graeme Smecher, netdev
Hi Graeme
There is already a support for add multicast in v2.6.37 cpsw driver, if
there is a bug and you found a fix, can go a head and fix that. The
patch you have mentioned is an upstream patch with was done on top of
am335x platform, so there might be bugs fixed and added into the patch
which are not in v2.6.37 cpsw driver.
Regards
Mugunthan V N
On Tuesday 02 September 2014 11:52 PM, Graeme Smecher wrote:
> Hi Mugunthan,
> 
>> On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
>>> Adding multicast address to ALE table via netdev ops to subscribe, transmit
>>> or receive multicast frames to and from the network
>>
>> Is this somehow related to the time stamping function? If so, how?
>>
>> Thanks,
>> Richard
> 
> Can you give me a brief description of this (relatively ancient) patch? Your
> original e-mail is visible here:
> 
> 	http://marc.info/?l=linux-netdev&m=135042754927177&w=2
> 
> I'm wondering if this patch needs to be backported to older CPSW driver
> snapshots (specifically, TI's 2.6.37 branch for dm81xx.) It appears to
> fix a multicast bug I'm tracking down, but it's difficult to know for
> sure without a good description of what problem the patch addresses. (I
> don't want to commit code that fixes my hardware by accident.)
> 
> For a little more information, you can refer to my e2e.ti.com post:
> 
> 	http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/365586.aspx
> 
> I'm slowly learning about ALE filtering, but a quick reply from a
> domain expert would be very helpful.
> 
> best,
> Graeme
> 
^ permalink raw reply	[flat|nested] 38+ messages in thread
* Re: [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table
  2014-09-03  8:28 ` Mugunthan V N
@ 2014-09-03 19:01   ` Graeme Smecher
  0 siblings, 0 replies; 38+ messages in thread
From: Graeme Smecher @ 2014-09-03 19:01 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: netdev
Hi Mungathan,
FYI, I think the multicast bug I'm working on also affects dual EMAC
mode in upstream cpsw.c. I will add a 2.6.37-specific patch on my e2e
forum post (link below), but this is a heads-up for code you maintain.
Symptoms: each port in dual EMAC mode trashes the other port's multicast
reception.
Cause: cpsw_ndo_set_rx_mode does the following:
cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port);
if (!netdev_mc_empty(ndev)) {
struct netdev_hw_addr *ha;
/* program multicast address list into ALE register */
netdev_for_each_mc_addr(ha, ndev) {
cpsw_add_mcast(priv, (u8 *)ha->addr);
}
}
This code can be invoked by eth0 or eth1, which have potentially
differing multicast lists. However, cpsw_ale_flush_multicast() trashes
ALL multicast entries in the ALE, affecting both ports. Only the entries
for the net_device that invoked cpsw_ndo_set_rx_mode() are restored.
To fix this, you will have to pass a correct port_mask to
cpsw_ale_flush_multicast(), and correct the free-entry check at the
bottom of cpsw_ale_flush_mcast().
best,
Graeme
On Wed, 2014-09-03 at 13:58 +0530, Mugunthan V N wrote: 
> Hi Graeme
> 
> There is already a support for add multicast in v2.6.37 cpsw driver, if
> there is a bug and you found a fix, can go a head and fix that. The
> patch you have mentioned is an upstream patch with was done on top of
> am335x platform, so there might be bugs fixed and added into the patch
> which are not in v2.6.37 cpsw driver.
> 
> Regards
> Mugunthan V N
> 
> On Tuesday 02 September 2014 11:52 PM, Graeme Smecher wrote:
> > Hi Mugunthan,
> > 
> >> On Wed, Oct 17, 2012 at 04:15:15AM +0530, Mugunthan V N wrote:
> >>> Adding multicast address to ALE table via netdev ops to subscribe, transmit
> >>> or receive multicast frames to and from the network
> >>
> >> Is this somehow related to the time stamping function? If so, how?
> >>
> >> Thanks,
> >> Richard
> > 
> > Can you give me a brief description of this (relatively ancient) patch? Your
> > original e-mail is visible here:
> > 
> > 	http://marc.info/?l=linux-netdev&m=135042754927177&w=2
> > 
> > I'm wondering if this patch needs to be backported to older CPSW driver
> > snapshots (specifically, TI's 2.6.37 branch for dm81xx.) It appears to
> > fix a multicast bug I'm tracking down, but it's difficult to know for
> > sure without a good description of what problem the patch addresses. (I
> > don't want to commit code that fixes my hardware by accident.)
> > 
> > For a little more information, you can refer to my e2e.ti.com post:
> > 
> > 	http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/365586.aspx
> > 
> > I'm slowly learning about ALE filtering, but a quick reply from a
> > domain expert would be very helpful.
> > 
> > best,
> > Graeme
> > 
> 
^ permalink raw reply	[flat|nested] 38+ messages in thread
end of thread, other threads:[~2014-09-03 19:01 UTC | newest]
Thread overview: 38+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-16 22:45 [PATCH 0/6] Add CPTS PTP driver support Mugunthan V N
2012-10-16 22:45 ` [PATCH 1/6] drivers: net: ethernet: cpsw: add support for CPSW register offset changes in different IP version Mugunthan V N
2012-10-18  2:45   ` Richard Cochran
2012-10-22 10:39     ` N, Mugunthan V
2012-10-22 11:23       ` Richard Cochran
2012-10-22 12:19         ` N, Mugunthan V
2012-10-22 12:25           ` Richard Cochran
2012-10-16 22:45 ` [PATCH 2/6] drivers: net: ethernet: davinci_cpdma: add clear api for statistics interrupt Mugunthan V N
2012-10-18  2:48   ` Richard Cochran
2012-10-22 10:42     ` N, Mugunthan V
2012-10-22 11:31       ` Richard Cochran
2012-10-16 22:45 ` [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Mugunthan V N
2012-10-18  2:49   ` Richard Cochran
2012-10-21 11:26   ` Richard Cochran
2012-10-22 10:46     ` N, Mugunthan V
2012-10-16 22:45 ` [PATCH 4/6] ptp: add api to get ptp seq id and event type from skb Mugunthan V N
2012-10-16 23:10   ` Ben Hutchings
2012-10-17 13:48     ` N, Mugunthan V
2012-10-18  2:55   ` Richard Cochran
2012-10-22 10:46     ` N, Mugunthan V
2012-10-22 11:36       ` Richard Cochran
2012-10-22 12:32         ` N, Mugunthan V
2012-10-22 12:37           ` Richard Cochran
2012-10-16 22:45 ` [PATCH 5/6] drivers: net: ethernet: cpts: implement cpts hardware clock Mugunthan V N
2012-10-20 13:43   ` Richard Cochran
2012-10-22 10:55     ` N, Mugunthan V
2012-10-22 11:41       ` Richard Cochran
2012-10-22 11:44       ` Richard Cochran
2012-10-22 12:38         ` N, Mugunthan V
2012-10-22 11:46       ` Richard Cochran
2012-10-22 12:42         ` N, Mugunthan V
2012-10-16 22:45 ` [PATCH 6/6] drivers: net: ethernet: cpsw: implement timestamping capabilities in cpsw Mugunthan V N
2012-10-21 18:11   ` Richard Cochran
2012-10-21 18:46 ` [PATCH 0/6] Add CPTS PTP driver support Richard Cochran
2012-10-22 10:51   ` N, Mugunthan V
  -- strict thread matches above, loose matches on Subject: below --
2014-09-02 18:22 [PATCH 3/6] drivers: net: ethernet: cpsw: add multicast address to ALE table Graeme Smecher
2014-09-03  8:28 ` Mugunthan V N
2014-09-03 19:01   ` Graeme Smecher
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).