linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [net-next] enetc: add support time specific departure base on the qos etf
@ 2019-12-23  3:42 Po Liu
  2019-12-26 23:09 ` David Miller
  2019-12-27  3:12 ` [v2,net-next] " Po Liu
  0 siblings, 2 replies; 8+ messages in thread
From: Po Liu @ 2019-12-23  3:42 UTC (permalink / raw)
  To: davem, linux-kernel, netdev
  Cc: vinicius.gomes, Po Liu, Claudiu Manoil, Vladimir Oltean,
	Alexandru Marginean, Xiaoliang Yang, Roy Zang, Mingkai Hu,
	Jerry Huang, Leo Li, ivan.khoronzhuk, Po Liu

ENETC implement time specific departure capability, which enables
the user to specify when a frame can be transmitted. When this
capability is enabled, the device will delay the transmission of
the frame so that it can be transmitted at the precisely specified time.
The delay departure time up to 0.5 seconds in the future. If the
departure time in the transmit BD has not yet been reached, based
on the current time, the packet will not be transmitted.

This driver was loaded by Qos driver ETF. User could load it by tc
commands. Here are the example commands:

tc qdisc add dev eth0 root handle 1: mqprio \
	   num_tc 8 map 0 1 2 3 4 5 6 7 hw 1
tc qdisc replace dev eth0 parent 1:8 etf \
	   clockid CLOCK_TAI delta 30000  offload

These example try to set queue mapping first and then set queue 7
with 30us ahead dequeue time.

Then user send test frame should set SO_TXTIME feature for socket.

There are also some limitations for this feature in hardware:
- Transmit checksum offloads and time specific departure operation
are mutually exclusive.
- Time Aware Shaper feature (Qbv) offload and time specific departure
operation are mutually exclusive.

Signed-off-by: Po Liu <Po.Liu@nxp.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/ethernet/freescale/enetc/enetc.c  | 12 +++++++
 drivers/net/ethernet/freescale/enetc/enetc.h  |  3 ++
 .../net/ethernet/freescale/enetc/enetc_hw.h   | 10 +++++-
 .../net/ethernet/freescale/enetc/enetc_qos.c  | 31 +++++++++++++++++++
 4 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 2ee4a2cd4780..1f79e36116a3 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -149,11 +149,21 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb,
 
 	if (enetc_tx_csum(skb, &temp_bd))
 		flags |= ENETC_TXBD_FLAGS_CSUM | ENETC_TXBD_FLAGS_L4CS;
+	else if (tx_ring->tsd_enable)
+		flags |= ENETC_TXBD_FLAGS_TSE | ENETC_TXBD_FLAGS_TXSTART;
 
 	/* first BD needs frm_len and offload flags set */
 	temp_bd.frm_len = cpu_to_le16(skb->len);
 	temp_bd.flags = flags;
 
+	if (flags & ENETC_TXBD_FLAGS_TSE) {
+		u32 temp;
+
+		temp = (skb->skb_mstamp_ns >> 5 & ENETC_TXBD_TXSTART_MASK)
+			| (flags << ENETC_TXBD_FLAGS_OFFSET);
+		temp_bd.txstart = cpu_to_le32(temp);
+	}
+
 	if (flags & ENETC_TXBD_FLAGS_EX) {
 		u8 e_flags = 0;
 		*txbd = temp_bd;
@@ -1505,6 +1515,8 @@ int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
 		return enetc_setup_tc_taprio(ndev, type_data);
 	case TC_SETUP_QDISC_CBS:
 		return enetc_setup_tc_cbs(ndev, type_data);
+	case TC_SETUP_QDISC_ETF:
+		return enetc_setup_tc_txtime(ndev, type_data);
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index 7ee0da6d0015..dd4a227ffc7a 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -72,6 +72,7 @@ struct enetc_bdr {
 	struct enetc_ring_stats stats;
 
 	dma_addr_t bd_dma_base;
+	u8 tsd_enable; /* Time specific departure */
 } ____cacheline_aligned_in_smp;
 
 static inline void enetc_bdr_idx_inc(struct enetc_bdr *bdr, int *i)
@@ -256,8 +257,10 @@ int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd);
 int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data);
 void enetc_sched_speed_set(struct net_device *ndev);
 int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data);
+int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data);
 #else
 #define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP
 #define enetc_sched_speed_set(ndev) (void)0
 #define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP
+#define enetc_setup_tc_txtime(ndev, type_data) -EOPNOTSUPP
 #endif
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index 51f543ef37a8..8375cd886dba 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -358,6 +358,7 @@ union enetc_tx_bd {
 				u8 l4_csoff;
 				u8 flags;
 			}; /* default layout */
+			__le32 txstart;
 			__le32 lstatus;
 		};
 	};
@@ -378,11 +379,14 @@ union enetc_tx_bd {
 };
 
 #define ENETC_TXBD_FLAGS_L4CS	BIT(0)
+#define ENETC_TXBD_FLAGS_TSE	BIT(1)
 #define ENETC_TXBD_FLAGS_W	BIT(2)
 #define ENETC_TXBD_FLAGS_CSUM	BIT(3)
+#define ENETC_TXBD_FLAGS_TXSTART BIT(4)
 #define ENETC_TXBD_FLAGS_EX	BIT(6)
 #define ENETC_TXBD_FLAGS_F	BIT(7)
-
+#define ENETC_TXBD_TXSTART_MASK GENMASK(24, 0)
+#define ENETC_TXBD_FLAGS_OFFSET 24
 static inline void enetc_clear_tx_bd(union enetc_tx_bd *txbd)
 {
 	memset(txbd, 0, sizeof(*txbd));
@@ -615,3 +619,7 @@ struct enetc_cbd {
 /* Port time gating capability register */
 #define ENETC_QBV_PTGCAPR_OFFSET	0x11a08
 #define ENETC_QBV_MAX_GCL_LEN_MASK	GENMASK(15, 0)
+
+/* Port time specific departure */
+#define ENETC_PTCTSDR(n)	(0x1210 + 4 * (n))
+#define ENETC_TSDE		BIT(31)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
index 9190ffc9f6b2..049f0fb40ac7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
@@ -156,6 +156,11 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
 	int err;
 	int i;
 
+	/* TSD and Qbv are mutually exclusive in hardware */
+	for (i = 0; i < priv->num_tx_rings; i++)
+		if (priv->tx_ring[i]->tsd_enable)
+			return -EBUSY;
+
 	for (i = 0; i < priv->num_tx_rings; i++)
 		enetc_set_bdr_prio(&priv->si->hw,
 				   priv->tx_ring[i]->index,
@@ -297,3 +302,29 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
 
 	return 0;
 }
+
+int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+{
+	struct enetc_ndev_priv *priv = netdev_priv(ndev);
+	struct tc_etf_qopt_offload *qopt = type_data;
+	u8 tc_nums = netdev_get_num_tc(ndev);
+	int tc;
+
+	if (!tc_nums)
+		return -EOPNOTSUPP;
+
+	tc = qopt->queue;
+
+	if (tc < 0 || tc > priv->num_tx_rings)
+		return -EINVAL;
+
+	/* TSD and Qbv are mutually exclusive in hardware */
+	if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
+		return -EBUSY;
+
+	priv->tx_ring[tc]->tsd_enable = qopt->enable;
+	enetc_port_wr(&priv->si->hw, ENETC_PTCTSDR(tc),
+		      qopt->enable ? ENETC_TSDE : 0);
+
+	return 0;
+}
-- 
2.17.1


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

* Re: [net-next] enetc: add support time specific departure base on the qos etf
  2019-12-23  3:42 [net-next] enetc: add support time specific departure base on the qos etf Po Liu
@ 2019-12-26 23:09 ` David Miller
  2019-12-27  2:11   ` [EXT] " Po Liu
  2019-12-27  3:12 ` [v2,net-next] " Po Liu
  1 sibling, 1 reply; 8+ messages in thread
From: David Miller @ 2019-12-26 23:09 UTC (permalink / raw)
  To: po.liu
  Cc: linux-kernel, netdev, vinicius.gomes, claudiu.manoil,
	vladimir.oltean, alexandru.marginean, xiaoliang.yang_1, roy.zang,
	mingkai.hu, jerry.huang, leoyang.li, ivan.khoronzhuk

From: Po Liu <po.liu@nxp.com>
Date: Mon, 23 Dec 2019 03:42:39 +0000

> - Transmit checksum offloads and time specific departure operation
> are mutually exclusive.

I do not see anything which enforces this conflict.

It looks to me like if the user configures time specific departure,
and TX SKBs will be checksum offloaded, the time specific departure
will simply not be performed.

If true, this behavior will be very surprising for the user.

Instead, the configuration operation that creates the conflict should
throw and error and fail.

Thank you.

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

* RE: [EXT] Re: [net-next] enetc: add support time specific departure base on the qos etf
  2019-12-26 23:09 ` David Miller
@ 2019-12-27  2:11   ` Po Liu
  0 siblings, 0 replies; 8+ messages in thread
From: Po Liu @ 2019-12-27  2:11 UTC (permalink / raw)
  To: David Miller
  Cc: linux-kernel, netdev, vinicius.gomes, Claudiu Manoil,
	Vladimir Oltean, Alexandru Marginean, Xiaoliang Yang, Roy Zang,
	Mingkai Hu, Jerry Huang, Leo Li, ivan.khoronzhuk




Br,
Po Liu

> -----Original Message-----
> From: David Miller <davem@davemloft.net>
> Sent: 2019年12月27日 7:10
> To: Po Liu <po.liu@nxp.com>
> Cc: linux-kernel@vger.kernel.org; netdev@vger.kernel.org;
> vinicius.gomes@intel.com; Claudiu Manoil <claudiu.manoil@nxp.com>;
> Vladimir Oltean <vladimir.oltean@nxp.com>; Alexandru Marginean
> <alexandru.marginean@nxp.com>; Xiaoliang Yang
> <xiaoliang.yang_1@nxp.com>; Roy Zang <roy.zang@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; Jerry Huang <jerry.huang@nxp.com>; Leo Li
> <leoyang.li@nxp.com>; ivan.khoronzhuk@linaro.org
> Subject: [EXT] Re: [net-next] enetc: add support time specific departure base on
> the qos etf
> 
> Caution: EXT Email
> 
> From: Po Liu <po.liu@nxp.com>
> Date: Mon, 23 Dec 2019 03:42:39 +0000
> 
> > - Transmit checksum offloads and time specific departure operation are
> > mutually exclusive.
> 
> I do not see anything which enforces this conflict.
> 
> It looks to me like if the user configures time specific departure, and TX SKBs will
> be checksum offloaded, the time specific departure will simply not be performed.
> 
> If true, this behavior will be very surprising for the user.
> 
> Instead, the configuration operation that creates the conflict should throw and
> error and fail.

I would fix it.

> 
> Thank you.

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

* [v2,net-next] enetc: add support time specific departure base on the qos etf
  2019-12-23  3:42 [net-next] enetc: add support time specific departure base on the qos etf Po Liu
  2019-12-26 23:09 ` David Miller
@ 2019-12-27  3:12 ` Po Liu
  2019-12-31  4:26   ` David Miller
  2020-01-02  4:59   ` [v3,net-next] " Po Liu
  1 sibling, 2 replies; 8+ messages in thread
From: Po Liu @ 2019-12-27  3:12 UTC (permalink / raw)
  To: davem, linux-kernel, netdev
  Cc: vinicius.gomes, Po Liu, Claudiu Manoil, Vladimir Oltean,
	Alexandru Marginean, Xiaoliang Yang, Roy Zang, Mingkai Hu,
	Jerry Huang, Leo Li, ivan.khoronzhuk, Po Liu

ENETC implement time specific departure capability, which enables
the user to specify when a frame can be transmitted. When this
capability is enabled, the device will delay the transmission of
the frame so that it can be transmitted at the precisely specified time.
The delay departure time up to 0.5 seconds in the future. If the
departure time in the transmit BD has not yet been reached, based
on the current time, the packet will not be transmitted.

This driver was loaded by Qos driver ETF. User could load it by tc
commands. Here are the example commands:

tc qdisc add dev eth0 root handle 1: mqprio \
	   num_tc 8 map 0 1 2 3 4 5 6 7 hw 1
tc qdisc replace dev eth0 parent 1:8 etf \
	   clockid CLOCK_TAI delta 30000  offload

These example try to set queue mapping first and then set queue 7
with 30us ahead dequeue time.

Then user send test frame should set SO_TXTIME feature for socket.

There are also some limitations for this feature in hardware:
- Transmit checksum offloads and time specific departure operation
are mutually exclusive.
- Time Aware Shaper feature (Qbv) offload and time specific departure
operation are mutually exclusive.

Signed-off-by: Po Liu <Po.Liu@nxp.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
changes log:
v2:
- fix the csum and time specific deaprture return directly if both
offloading enabled

 drivers/net/ethernet/freescale/enetc/enetc.c  | 18 +++++++++++
 drivers/net/ethernet/freescale/enetc/enetc.h  |  3 ++
 .../net/ethernet/freescale/enetc/enetc_hw.h   | 10 +++++-
 .../net/ethernet/freescale/enetc/enetc_qos.c  | 31 +++++++++++++++++++
 4 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 2ee4a2cd4780..8e4dfaf07f0e 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -149,11 +149,27 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb,
 
 	if (enetc_tx_csum(skb, &temp_bd))
 		flags |= ENETC_TXBD_FLAGS_CSUM | ENETC_TXBD_FLAGS_L4CS;
+	if (tx_ring->tsd_enable)
+		flags |= ENETC_TXBD_FLAGS_TSE | ENETC_TXBD_FLAGS_TXSTART;
+
+	if (flags & ENETC_TXBD_FLAGS_TSE && flags & ENETC_TXBD_FLAGS_CSUM) {
+		dev_err(tx_ring->dev,
+			"Both TXSTART and CSUM enabled not support!");
+		return 0;
+	}
 
 	/* first BD needs frm_len and offload flags set */
 	temp_bd.frm_len = cpu_to_le16(skb->len);
 	temp_bd.flags = flags;
 
+	if (flags & ENETC_TXBD_FLAGS_TSE) {
+		u32 temp;
+
+		temp = (skb->skb_mstamp_ns >> 5 & ENETC_TXBD_TXSTART_MASK)
+			| (flags << ENETC_TXBD_FLAGS_OFFSET);
+		temp_bd.txstart = cpu_to_le32(temp);
+	}
+
 	if (flags & ENETC_TXBD_FLAGS_EX) {
 		u8 e_flags = 0;
 		*txbd = temp_bd;
@@ -1505,6 +1521,8 @@ int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
 		return enetc_setup_tc_taprio(ndev, type_data);
 	case TC_SETUP_QDISC_CBS:
 		return enetc_setup_tc_cbs(ndev, type_data);
+	case TC_SETUP_QDISC_ETF:
+		return enetc_setup_tc_txtime(ndev, type_data);
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index 7ee0da6d0015..dd4a227ffc7a 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -72,6 +72,7 @@ struct enetc_bdr {
 	struct enetc_ring_stats stats;
 
 	dma_addr_t bd_dma_base;
+	u8 tsd_enable; /* Time specific departure */
 } ____cacheline_aligned_in_smp;
 
 static inline void enetc_bdr_idx_inc(struct enetc_bdr *bdr, int *i)
@@ -256,8 +257,10 @@ int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd);
 int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data);
 void enetc_sched_speed_set(struct net_device *ndev);
 int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data);
+int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data);
 #else
 #define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP
 #define enetc_sched_speed_set(ndev) (void)0
 #define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP
+#define enetc_setup_tc_txtime(ndev, type_data) -EOPNOTSUPP
 #endif
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index 51f543ef37a8..8375cd886dba 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -358,6 +358,7 @@ union enetc_tx_bd {
 				u8 l4_csoff;
 				u8 flags;
 			}; /* default layout */
+			__le32 txstart;
 			__le32 lstatus;
 		};
 	};
@@ -378,11 +379,14 @@ union enetc_tx_bd {
 };
 
 #define ENETC_TXBD_FLAGS_L4CS	BIT(0)
+#define ENETC_TXBD_FLAGS_TSE	BIT(1)
 #define ENETC_TXBD_FLAGS_W	BIT(2)
 #define ENETC_TXBD_FLAGS_CSUM	BIT(3)
+#define ENETC_TXBD_FLAGS_TXSTART BIT(4)
 #define ENETC_TXBD_FLAGS_EX	BIT(6)
 #define ENETC_TXBD_FLAGS_F	BIT(7)
-
+#define ENETC_TXBD_TXSTART_MASK GENMASK(24, 0)
+#define ENETC_TXBD_FLAGS_OFFSET 24
 static inline void enetc_clear_tx_bd(union enetc_tx_bd *txbd)
 {
 	memset(txbd, 0, sizeof(*txbd));
@@ -615,3 +619,7 @@ struct enetc_cbd {
 /* Port time gating capability register */
 #define ENETC_QBV_PTGCAPR_OFFSET	0x11a08
 #define ENETC_QBV_MAX_GCL_LEN_MASK	GENMASK(15, 0)
+
+/* Port time specific departure */
+#define ENETC_PTCTSDR(n)	(0x1210 + 4 * (n))
+#define ENETC_TSDE		BIT(31)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
index 9190ffc9f6b2..049f0fb40ac7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
@@ -156,6 +156,11 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
 	int err;
 	int i;
 
+	/* TSD and Qbv are mutually exclusive in hardware */
+	for (i = 0; i < priv->num_tx_rings; i++)
+		if (priv->tx_ring[i]->tsd_enable)
+			return -EBUSY;
+
 	for (i = 0; i < priv->num_tx_rings; i++)
 		enetc_set_bdr_prio(&priv->si->hw,
 				   priv->tx_ring[i]->index,
@@ -297,3 +302,29 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
 
 	return 0;
 }
+
+int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+{
+	struct enetc_ndev_priv *priv = netdev_priv(ndev);
+	struct tc_etf_qopt_offload *qopt = type_data;
+	u8 tc_nums = netdev_get_num_tc(ndev);
+	int tc;
+
+	if (!tc_nums)
+		return -EOPNOTSUPP;
+
+	tc = qopt->queue;
+
+	if (tc < 0 || tc > priv->num_tx_rings)
+		return -EINVAL;
+
+	/* TSD and Qbv are mutually exclusive in hardware */
+	if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
+		return -EBUSY;
+
+	priv->tx_ring[tc]->tsd_enable = qopt->enable;
+	enetc_port_wr(&priv->si->hw, ENETC_PTCTSDR(tc),
+		      qopt->enable ? ENETC_TSDE : 0);
+
+	return 0;
+}
-- 
2.17.1


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

* Re: [v2,net-next] enetc: add support time specific departure base on the qos etf
  2019-12-27  3:12 ` [v2,net-next] " Po Liu
@ 2019-12-31  4:26   ` David Miller
  2020-01-02  2:16     ` [EXT] " Po Liu
  2020-01-02  4:59   ` [v3,net-next] " Po Liu
  1 sibling, 1 reply; 8+ messages in thread
From: David Miller @ 2019-12-31  4:26 UTC (permalink / raw)
  To: po.liu
  Cc: linux-kernel, netdev, vinicius.gomes, claudiu.manoil,
	vladimir.oltean, alexandru.marginean, xiaoliang.yang_1, roy.zang,
	mingkai.hu, jerry.huang, leoyang.li, ivan.khoronzhuk

From: Po Liu <po.liu@nxp.com>
Date: Fri, 27 Dec 2019 03:12:18 +0000

> v2:
> - fix the csum and time specific deaprture return directly if both
> offloading enabled

The test is in the wrong location.

You are testing at run time when packets are being transmitted.

Instead, you should test when the configuration change is made
which creates the conflict, and disallow the configuration change
in such a conflicting case.

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

* RE: [EXT] Re: [v2,net-next] enetc: add support time specific departure base on the qos etf
  2019-12-31  4:26   ` David Miller
@ 2020-01-02  2:16     ` Po Liu
  0 siblings, 0 replies; 8+ messages in thread
From: Po Liu @ 2020-01-02  2:16 UTC (permalink / raw)
  To: David Miller
  Cc: linux-kernel, netdev, vinicius.gomes, Claudiu Manoil,
	Vladimir Oltean, Alexandru Marginean, Xiaoliang Yang, Roy Zang,
	Mingkai Hu, Jerry Huang, Leo Li, ivan.khoronzhuk


> -----Original Message-----
> From: David Miller <davem@davemloft.net>
> Sent: 2019年12月31日 12:27
> To: Po Liu <po.liu@nxp.com>
> Cc: linux-kernel@vger.kernel.org; netdev@vger.kernel.org;
> vinicius.gomes@intel.com; Claudiu Manoil <claudiu.manoil@nxp.com>;
> Vladimir Oltean <vladimir.oltean@nxp.com>; Alexandru Marginean
> <alexandru.marginean@nxp.com>; Xiaoliang Yang
> <xiaoliang.yang_1@nxp.com>; Roy Zang <roy.zang@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; Jerry Huang <jerry.huang@nxp.com>; Leo Li
> <leoyang.li@nxp.com>; ivan.khoronzhuk@linaro.org
> Subject: [EXT] Re: [v2,net-next] enetc: add support time specific departure base
> on the qos etf
> 
> Caution: EXT Email
> 
> From: Po Liu <po.liu@nxp.com>
> Date: Fri, 27 Dec 2019 03:12:18 +0000
> 
> > v2:
> > - fix the csum and time specific deaprture return directly if both
> > offloading enabled
> 
> The test is in the wrong location.
> 
> You are testing at run time when packets are being transmitted.
> 
> Instead, you should test when the configuration change is made which creates
> the conflict, and disallow the configuration change in such a conflicting case.

Ok, thanks!

Br,
Po Liu

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

* [v3,net-next] enetc: add support time specific departure base on the qos etf
  2019-12-27  3:12 ` [v2,net-next] " Po Liu
  2019-12-31  4:26   ` David Miller
@ 2020-01-02  4:59   ` Po Liu
  2020-01-03  0:33     ` David Miller
  1 sibling, 1 reply; 8+ messages in thread
From: Po Liu @ 2020-01-02  4:59 UTC (permalink / raw)
  To: davem, linux-kernel, netdev
  Cc: vinicius.gomes, Po Liu, Claudiu Manoil, Vladimir Oltean,
	Alexandru Marginean, Xiaoliang Yang, Roy Zang, Mingkai Hu,
	Jerry Huang, Leo Li, ivan.khoronzhuk, Po Liu

ENETC implement time specific departure capability, which enables
the user to specify when a frame can be transmitted. When this
capability is enabled, the device will delay the transmission of
the frame so that it can be transmitted at the precisely specified time.
The delay departure time up to 0.5 seconds in the future. If the
departure time in the transmit BD has not yet been reached, based
on the current time, the packet will not be transmitted.

This driver was loaded by Qos driver ETF. User could load it by tc
commands. Here are the example commands:

tc qdisc add dev eth0 root handle 1: mqprio \
	   num_tc 8 map 0 1 2 3 4 5 6 7 hw 1
tc qdisc replace dev eth0 parent 1:8 etf \
	   clockid CLOCK_TAI delta 30000  offload

These example try to set queue mapping first and then set queue 7
with 30us ahead dequeue time.

Then user send test frame should set SO_TXTIME feature for socket.

There are also some limitations for this feature in hardware:
- Transmit checksum offloads and time specific departure operation
are mutually exclusive.
- Time Aware Shaper feature (Qbv) offload and time specific departure
operation are mutually exclusive.

Signed-off-by: Po Liu <Po.Liu@nxp.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes v2-v3:
- Avoid tx checking sum offload when setting TXTIME offload. This is
not support in hardware.

 drivers/net/ethernet/freescale/enetc/enetc.c  | 12 +++++++
 drivers/net/ethernet/freescale/enetc/enetc.h  |  3 ++
 .../net/ethernet/freescale/enetc/enetc_hw.h   | 10 +++++-
 .../net/ethernet/freescale/enetc/enetc_qos.c  | 35 +++++++++++++++++++
 4 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 2ee4a2cd4780..1f79e36116a3 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -149,11 +149,21 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb,
 
 	if (enetc_tx_csum(skb, &temp_bd))
 		flags |= ENETC_TXBD_FLAGS_CSUM | ENETC_TXBD_FLAGS_L4CS;
+	else if (tx_ring->tsd_enable)
+		flags |= ENETC_TXBD_FLAGS_TSE | ENETC_TXBD_FLAGS_TXSTART;
 
 	/* first BD needs frm_len and offload flags set */
 	temp_bd.frm_len = cpu_to_le16(skb->len);
 	temp_bd.flags = flags;
 
+	if (flags & ENETC_TXBD_FLAGS_TSE) {
+		u32 temp;
+
+		temp = (skb->skb_mstamp_ns >> 5 & ENETC_TXBD_TXSTART_MASK)
+			| (flags << ENETC_TXBD_FLAGS_OFFSET);
+		temp_bd.txstart = cpu_to_le32(temp);
+	}
+
 	if (flags & ENETC_TXBD_FLAGS_EX) {
 		u8 e_flags = 0;
 		*txbd = temp_bd;
@@ -1505,6 +1515,8 @@ int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
 		return enetc_setup_tc_taprio(ndev, type_data);
 	case TC_SETUP_QDISC_CBS:
 		return enetc_setup_tc_cbs(ndev, type_data);
+	case TC_SETUP_QDISC_ETF:
+		return enetc_setup_tc_txtime(ndev, type_data);
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index 7ee0da6d0015..dd4a227ffc7a 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -72,6 +72,7 @@ struct enetc_bdr {
 	struct enetc_ring_stats stats;
 
 	dma_addr_t bd_dma_base;
+	u8 tsd_enable; /* Time specific departure */
 } ____cacheline_aligned_in_smp;
 
 static inline void enetc_bdr_idx_inc(struct enetc_bdr *bdr, int *i)
@@ -256,8 +257,10 @@ int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd);
 int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data);
 void enetc_sched_speed_set(struct net_device *ndev);
 int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data);
+int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data);
 #else
 #define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP
 #define enetc_sched_speed_set(ndev) (void)0
 #define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP
+#define enetc_setup_tc_txtime(ndev, type_data) -EOPNOTSUPP
 #endif
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index 51f543ef37a8..8375cd886dba 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -358,6 +358,7 @@ union enetc_tx_bd {
 				u8 l4_csoff;
 				u8 flags;
 			}; /* default layout */
+			__le32 txstart;
 			__le32 lstatus;
 		};
 	};
@@ -378,11 +379,14 @@ union enetc_tx_bd {
 };
 
 #define ENETC_TXBD_FLAGS_L4CS	BIT(0)
+#define ENETC_TXBD_FLAGS_TSE	BIT(1)
 #define ENETC_TXBD_FLAGS_W	BIT(2)
 #define ENETC_TXBD_FLAGS_CSUM	BIT(3)
+#define ENETC_TXBD_FLAGS_TXSTART BIT(4)
 #define ENETC_TXBD_FLAGS_EX	BIT(6)
 #define ENETC_TXBD_FLAGS_F	BIT(7)
-
+#define ENETC_TXBD_TXSTART_MASK GENMASK(24, 0)
+#define ENETC_TXBD_FLAGS_OFFSET 24
 static inline void enetc_clear_tx_bd(union enetc_tx_bd *txbd)
 {
 	memset(txbd, 0, sizeof(*txbd));
@@ -615,3 +619,7 @@ struct enetc_cbd {
 /* Port time gating capability register */
 #define ENETC_QBV_PTGCAPR_OFFSET	0x11a08
 #define ENETC_QBV_MAX_GCL_LEN_MASK	GENMASK(15, 0)
+
+/* Port time specific departure */
+#define ENETC_PTCTSDR(n)	(0x1210 + 4 * (n))
+#define ENETC_TSDE		BIT(31)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
index 9190ffc9f6b2..e910aaf0f5ec 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
@@ -156,6 +156,11 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
 	int err;
 	int i;
 
+	/* TSD and Qbv are mutually exclusive in hardware */
+	for (i = 0; i < priv->num_tx_rings; i++)
+		if (priv->tx_ring[i]->tsd_enable)
+			return -EBUSY;
+
 	for (i = 0; i < priv->num_tx_rings; i++)
 		enetc_set_bdr_prio(&priv->si->hw,
 				   priv->tx_ring[i]->index,
@@ -297,3 +302,33 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
 
 	return 0;
 }
+
+int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+{
+	struct enetc_ndev_priv *priv = netdev_priv(ndev);
+	struct tc_etf_qopt_offload *qopt = type_data;
+	u8 tc_nums = netdev_get_num_tc(ndev);
+	int tc;
+
+	if (!tc_nums)
+		return -EOPNOTSUPP;
+
+	tc = qopt->queue;
+
+	if (tc < 0 || tc > priv->num_tx_rings)
+		return -EINVAL;
+
+	/* Do not support TXSTART and TX CSUM offload simutaniously */
+	if (ndev->features & NETIF_F_CSUM_MASK)
+		return -EBUSY;
+
+	/* TSD and Qbv are mutually exclusive in hardware */
+	if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
+		return -EBUSY;
+
+	priv->tx_ring[tc]->tsd_enable = qopt->enable;
+	enetc_port_wr(&priv->si->hw, ENETC_PTCTSDR(tc),
+		      qopt->enable ? ENETC_TSDE : 0);
+
+	return 0;
+}
-- 
2.17.1


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

* Re: [v3,net-next] enetc: add support time specific departure base on the qos etf
  2020-01-02  4:59   ` [v3,net-next] " Po Liu
@ 2020-01-03  0:33     ` David Miller
  0 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2020-01-03  0:33 UTC (permalink / raw)
  To: po.liu
  Cc: linux-kernel, netdev, vinicius.gomes, claudiu.manoil,
	vladimir.oltean, alexandru.marginean, xiaoliang.yang_1, roy.zang,
	mingkai.hu, jerry.huang, leoyang.li, ivan.khoronzhuk

From: Po Liu <po.liu@nxp.com>
Date: Thu, 2 Jan 2020 04:59:24 +0000

> ENETC implement time specific departure capability, which enables
> the user to specify when a frame can be transmitted. When this
> capability is enabled, the device will delay the transmission of
> the frame so that it can be transmitted at the precisely specified time.
> The delay departure time up to 0.5 seconds in the future. If the
> departure time in the transmit BD has not yet been reached, based
> on the current time, the packet will not be transmitted.
> 
> This driver was loaded by Qos driver ETF. User could load it by tc
> commands. Here are the example commands:
> 
> tc qdisc add dev eth0 root handle 1: mqprio \
> 	   num_tc 8 map 0 1 2 3 4 5 6 7 hw 1
> tc qdisc replace dev eth0 parent 1:8 etf \
> 	   clockid CLOCK_TAI delta 30000  offload
> 
> These example try to set queue mapping first and then set queue 7
> with 30us ahead dequeue time.
> 
> Then user send test frame should set SO_TXTIME feature for socket.
> 
> There are also some limitations for this feature in hardware:
> - Transmit checksum offloads and time specific departure operation
> are mutually exclusive.
> - Time Aware Shaper feature (Qbv) offload and time specific departure
> operation are mutually exclusive.
> 
> Signed-off-by: Po Liu <Po.Liu@nxp.com>
> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> ---
> Changes v2-v3:
> - Avoid tx checking sum offload when setting TXTIME offload. This is
> not support in hardware.

This looks a lot better, applied, thank you.

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

end of thread, other threads:[~2020-01-03  0:33 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-23  3:42 [net-next] enetc: add support time specific departure base on the qos etf Po Liu
2019-12-26 23:09 ` David Miller
2019-12-27  2:11   ` [EXT] " Po Liu
2019-12-27  3:12 ` [v2,net-next] " Po Liu
2019-12-31  4:26   ` David Miller
2020-01-02  2:16     ` [EXT] " Po Liu
2020-01-02  4:59   ` [v3,net-next] " Po Liu
2020-01-03  0:33     ` David Miller

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