DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH 0/2] net/igc: support Tx timestamp offload
@ 2022-12-20  3:47 Simei Su
  2022-12-20  3:47 ` [PATCH 1/2] net/igc/base: " Simei Su
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Simei Su @ 2022-12-20  3:47 UTC (permalink / raw)
  To: qi.z.zhang, junfeng.guo; +Cc: dev, wenjun1.wu, Simei Su

[PATCH 1/2] add related definitions to support Tx timestamp offload.
[PATCH 2/2] enable Tx timestamp offload by "Launch Time".

Simei Su (2):
  net/igc/base: support Tx timestamp offload
  net/igc: enable Tx timestamp offload

 drivers/net/igc/base/igc_defines.h |  9 +++++
 drivers/net/igc/base/igc_regs.h    |  8 +++++
 drivers/net/igc/igc_ethdev.c       | 70 ++++++++++++++++++++++++++++++++++++++
 drivers/net/igc/igc_ethdev.h       |  6 +++-
 drivers/net/igc/igc_txrx.c         | 58 ++++++++++++++++++++++++++-----
 drivers/net/igc/igc_txrx.h         |  3 ++
 6 files changed, 145 insertions(+), 9 deletions(-)

-- 
2.9.5


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

* [PATCH 1/2] net/igc/base: support Tx timestamp offload
  2022-12-20  3:47 [PATCH 0/2] net/igc: support Tx timestamp offload Simei Su
@ 2022-12-20  3:47 ` Simei Su
  2022-12-20  3:47 ` [PATCH 2/2] net/igc: enable " Simei Su
  2023-02-01  7:30 ` [PATCH v2 0/2] net/igc: support launch time offloading Simei Su
  2 siblings, 0 replies; 14+ messages in thread
From: Simei Su @ 2022-12-20  3:47 UTC (permalink / raw)
  To: qi.z.zhang, junfeng.guo; +Cc: dev, wenjun1.wu, Simei Su

Add definitions for Tx timestamp offload
"RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP".

Signed-off-by: Simei Su <simei.su@intel.com>
---
 drivers/net/igc/base/igc_defines.h | 9 +++++++++
 drivers/net/igc/base/igc_regs.h    | 8 ++++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/net/igc/base/igc_defines.h b/drivers/net/igc/base/igc_defines.h
index dd7330a..280570b 100644
--- a/drivers/net/igc/base/igc_defines.h
+++ b/drivers/net/igc/base/igc_defines.h
@@ -188,6 +188,15 @@
 #define IGC_RCTL_BSEX		0x02000000 /* Buffer size extension */
 #define IGC_RCTL_SECRC	0x04000000 /* Strip Ethernet CRC */
 
+#define IGC_DTXMXPKTSZ_TSN     0x19 /* 1600 bytes of max TX DMA packet size */
+#define IGC_TXPBSIZE_TSN       0x04145145 /* 5k bytes buffer for each queue */
+
+/* Transmit Scheduling */
+#define IGC_TQAVCTRL_TRANSMIT_MODE_TSN 0x00000001
+#define IGC_TQAVCTRL_ENHANCED_QAV      0x00000008
+
+#define IGC_TXQCTL_QUEUE_MODE_LAUNCHT  0x00000001
+
 /* Use byte values for the following shift parameters
  * Usage:
  *     psrctl |= (((ROUNDUP(value0, 128) >> IGC_PSRCTL_BSIZE0_SHIFT) &
diff --git a/drivers/net/igc/base/igc_regs.h b/drivers/net/igc/base/igc_regs.h
index d424387..e423814 100644
--- a/drivers/net/igc/base/igc_regs.h
+++ b/drivers/net/igc/base/igc_regs.h
@@ -602,6 +602,14 @@
 #define IGC_RXMTRL	0x0B634 /* Time sync Rx EtherType and Msg Type - RW */
 #define IGC_RXUDP	0x0B638 /* Time Sync Rx UDP Port - RW */
 
+#define IGC_QBVCYCLET	0x331C
+#define IGC_QBVCYCLET_S 0x3320
+#define IGC_STQT(_n)	(0x3324 + 0x4 * (_n))
+#define IGC_ENDQT(_n)	(0x3334 + 0x4 * (_n))
+#define IGC_TXQCTL(_n)	(0x3344 + 0x4 * (_n))
+#define IGC_BASET_L	0x3314
+#define IGC_BASET_H	0x3318
+
 /* Filtering Registers */
 #define IGC_SAQF(_n)	(0x05980 + (4 * (_n))) /* Source Address Queue Fltr */
 #define IGC_DAQF(_n)	(0x059A0 + (4 * (_n))) /* Dest Address Queue Fltr */
-- 
2.9.5


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

* [PATCH 2/2] net/igc: enable Tx timestamp offload
  2022-12-20  3:47 [PATCH 0/2] net/igc: support Tx timestamp offload Simei Su
  2022-12-20  3:47 ` [PATCH 1/2] net/igc/base: " Simei Su
@ 2022-12-20  3:47 ` Simei Su
  2023-02-01  7:30 ` [PATCH v2 0/2] net/igc: support launch time offloading Simei Su
  2 siblings, 0 replies; 14+ messages in thread
From: Simei Su @ 2022-12-20  3:47 UTC (permalink / raw)
  To: qi.z.zhang, junfeng.guo; +Cc: dev, wenjun1.wu, Simei Su

This patch supports Tx timestamp offload by leveraging NIC's
"Launch Time" for "RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP".

Signed-off-by: Simei Su <simei.su@intel.com>
---
 drivers/net/igc/igc_ethdev.c | 70 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/igc/igc_ethdev.h |  6 +++-
 drivers/net/igc/igc_txrx.c   | 58 +++++++++++++++++++++++++++++++-----
 drivers/net/igc/igc_txrx.h   |  3 ++
 4 files changed, 128 insertions(+), 9 deletions(-)

diff --git a/drivers/net/igc/igc_ethdev.c b/drivers/net/igc/igc_ethdev.c
index ef3346b..28f6cd5 100644
--- a/drivers/net/igc/igc_ethdev.c
+++ b/drivers/net/igc/igc_ethdev.c
@@ -88,6 +88,9 @@
 #define IGC_I225_RX_LATENCY_1000	300
 #define IGC_I225_RX_LATENCY_2500	1485
 
+uint64_t igc_timestamp_dynflag;
+int igc_timestamp_dynfield_offset = -1;
+
 static const struct rte_eth_desc_lim rx_desc_lim = {
 	.nb_max = IGC_MAX_RXD,
 	.nb_min = IGC_MIN_RXD,
@@ -267,6 +270,7 @@ static int eth_igc_timesync_read_time(struct rte_eth_dev *dev,
 				  struct timespec *timestamp);
 static int eth_igc_timesync_write_time(struct rte_eth_dev *dev,
 				   const struct timespec *timestamp);
+static int eth_igc_read_clock(struct rte_eth_dev *dev, uint64_t *clock);
 
 static const struct eth_dev_ops eth_igc_ops = {
 	.dev_configure		= eth_igc_configure,
@@ -327,6 +331,7 @@ static const struct eth_dev_ops eth_igc_ops = {
 	.timesync_adjust_time	= eth_igc_timesync_adjust_time,
 	.timesync_read_time	= eth_igc_timesync_read_time,
 	.timesync_write_time	= eth_igc_timesync_write_time,
+	.read_clock             = eth_igc_read_clock,
 };
 
 /*
@@ -949,7 +954,12 @@ eth_igc_start(struct rte_eth_dev *dev)
 	struct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+	uint32_t nsec, sec, baset_l, baset_h, tqavctrl;
+	struct timespec system_time;
+	int64_t n, systime;
+	uint32_t txqctl = 0;
 	uint32_t *speeds;
+	uint16_t i;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -1009,6 +1019,55 @@ eth_igc_start(struct rte_eth_dev *dev)
 		return ret;
 	}
 
+	if (igc_timestamp_dynflag > 0) {
+		adapter->base_time = 0;
+		adapter->cycle_time = NSEC_PER_SEC;
+
+		IGC_WRITE_REG(hw, IGC_TSSDP, 0);
+		IGC_WRITE_REG(hw, IGC_TSIM, TSINTR_TXTS);
+		IGC_WRITE_REG(hw, IGC_IMS, IGC_ICR_TS);
+
+		IGC_WRITE_REG(hw, IGC_TSAUXC, 0);
+		IGC_WRITE_REG(hw, IGC_I350_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
+		IGC_WRITE_REG(hw, IGC_TXPBS, IGC_TXPBSIZE_TSN);
+
+		tqavctrl = IGC_READ_REG(hw, IGC_I210_TQAVCTRL);
+		tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
+			    IGC_TQAVCTRL_ENHANCED_QAV;
+		IGC_WRITE_REG(hw, IGC_I210_TQAVCTRL, tqavctrl);
+
+		IGC_WRITE_REG(hw, IGC_QBVCYCLET_S, adapter->cycle_time);
+		IGC_WRITE_REG(hw, IGC_QBVCYCLET, adapter->cycle_time);
+
+		for (i = 0; i < dev->data->nb_tx_queues; i++) {
+			IGC_WRITE_REG(hw, IGC_STQT(i), 0);
+			IGC_WRITE_REG(hw, IGC_ENDQT(i), NSEC_PER_SEC);
+
+			txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
+			IGC_WRITE_REG(hw, IGC_TXQCTL(i), txqctl);
+		}
+
+		clock_gettime(CLOCK_REALTIME, &system_time);
+		IGC_WRITE_REG(hw, IGC_SYSTIML, system_time.tv_nsec);
+		IGC_WRITE_REG(hw, IGC_SYSTIMH, system_time.tv_sec);
+
+		nsec = IGC_READ_REG(hw, IGC_SYSTIML);
+		sec = IGC_READ_REG(hw, IGC_SYSTIMH);
+		systime = (int64_t)sec * NSEC_PER_SEC + (int64_t)nsec;
+
+		if (systime > adapter->base_time) {
+			n = (systime - adapter->base_time) /
+			     adapter->cycle_time;
+			adapter->base_time = adapter->base_time +
+				(n + 1) * adapter->cycle_time;
+		}
+
+		baset_h = adapter->base_time / NSEC_PER_SEC;
+		baset_l = adapter->base_time % NSEC_PER_SEC;
+		IGC_WRITE_REG(hw, IGC_BASET_H, baset_h);
+		IGC_WRITE_REG(hw, IGC_BASET_L, baset_l);
+	}
+
 	igc_clear_hw_cntrs_base_generic(hw);
 
 	/* VLAN Offload Settings */
@@ -2804,6 +2863,17 @@ eth_igc_timesync_disable(struct rte_eth_dev *dev)
 }
 
 static int
+eth_igc_read_clock(__rte_unused struct rte_eth_dev *dev, uint64_t *clock)
+{
+	struct timespec system_time;
+
+	clock_gettime(CLOCK_REALTIME, &system_time);
+	*clock = system_time.tv_sec * NSEC_PER_SEC + system_time.tv_nsec;
+
+	return 0;
+}
+
+static int
 eth_igc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
diff --git a/drivers/net/igc/igc_ethdev.h b/drivers/net/igc/igc_ethdev.h
index 237d3c1..8d7eb54 100644
--- a/drivers/net/igc/igc_ethdev.h
+++ b/drivers/net/igc/igc_ethdev.h
@@ -87,7 +87,8 @@ extern "C" {
 	RTE_ETH_TX_OFFLOAD_SCTP_CKSUM  | \
 	RTE_ETH_TX_OFFLOAD_TCP_TSO     | \
 	RTE_ETH_TX_OFFLOAD_UDP_TSO	   | \
-	RTE_ETH_TX_OFFLOAD_MULTI_SEGS)
+	RTE_ETH_TX_OFFLOAD_MULTI_SEGS  | \
+	RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP)
 
 #define IGC_RSS_OFFLOAD_ALL	(    \
 	RTE_ETH_RSS_IPV4               | \
@@ -240,6 +241,9 @@ struct igc_adapter {
 	struct igc_syn_filter syn_filter;
 	struct igc_rss_filter rss_filter;
 	struct igc_flow_list flow_list;
+
+	int64_t base_time;
+	uint32_t cycle_time;
 };
 
 #define IGC_DEV_PRIVATE(_dev)	((_dev)->data->dev_private)
diff --git a/drivers/net/igc/igc_txrx.c b/drivers/net/igc/igc_txrx.c
index 0236c7f..dd48655 100644
--- a/drivers/net/igc/igc_txrx.c
+++ b/drivers/net/igc/igc_txrx.c
@@ -1411,6 +1411,19 @@ what_advctx_update(struct igc_tx_queue *txq, uint64_t flags,
 	return IGC_CTX_NUM;
 }
 
+static uint32_t igc_tx_launchtime(uint64_t txtime, uint16_t port_id)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	struct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);
+	uint64_t base_time = adapter->base_time;
+	uint64_t cycle_time = adapter->cycle_time;
+	uint32_t launchtime;
+
+	launchtime = (txtime - base_time) % cycle_time;
+
+	return rte_cpu_to_le_32(launchtime);
+}
+
 /*
  * This is a separate function, looking for optimization opportunity here
  * Rework required to go with the pre-defined values.
@@ -1418,7 +1431,8 @@ what_advctx_update(struct igc_tx_queue *txq, uint64_t flags,
 static inline void
 igc_set_xmit_ctx(struct igc_tx_queue *txq,
 		volatile struct igc_adv_tx_context_desc *ctx_txd,
-		uint64_t ol_flags, union igc_tx_offload tx_offload)
+		uint64_t ol_flags, union igc_tx_offload tx_offload,
+		uint64_t txtime)
 {
 	uint32_t type_tucmd_mlhl;
 	uint32_t mss_l4len_idx;
@@ -1492,16 +1506,23 @@ igc_set_xmit_ctx(struct igc_tx_queue *txq,
 		}
 	}
 
-	txq->ctx_cache[ctx_curr].flags = ol_flags;
-	txq->ctx_cache[ctx_curr].tx_offload.data =
-		tx_offload_mask.data & tx_offload.data;
-	txq->ctx_cache[ctx_curr].tx_offload_mask = tx_offload_mask;
+	if (!txtime) {
+		txq->ctx_cache[ctx_curr].flags = ol_flags;
+		txq->ctx_cache[ctx_curr].tx_offload.data =
+			tx_offload_mask.data & tx_offload.data;
+		txq->ctx_cache[ctx_curr].tx_offload_mask = tx_offload_mask;
+	}
 
 	ctx_txd->type_tucmd_mlhl = rte_cpu_to_le_32(type_tucmd_mlhl);
 	vlan_macip_lens = (uint32_t)tx_offload.data;
 	ctx_txd->vlan_macip_lens = rte_cpu_to_le_32(vlan_macip_lens);
 	ctx_txd->mss_l4len_idx = rte_cpu_to_le_32(mss_l4len_idx);
-	ctx_txd->u.launch_time = 0;
+
+	if (txtime)
+		ctx_txd->u.launch_time = igc_tx_launchtime(txtime,
+							   txq->port_id);
+	else
+		ctx_txd->u.launch_time = 0;
 }
 
 static inline uint32_t
@@ -1551,6 +1572,7 @@ igc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	uint64_t tx_ol_req;
 	uint32_t new_ctx = 0;
 	union igc_tx_offload tx_offload = {0};
+	uint64_t ts;
 
 	tx_id = txq->tx_tail;
 	txe = &sw_ring[tx_id];
@@ -1698,8 +1720,16 @@ igc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 					txe->mbuf = NULL;
 				}
 
-				igc_set_xmit_ctx(txq, ctx_txd, tx_ol_req,
-						tx_offload);
+				if (igc_timestamp_dynflag > 0) {
+					ts = *RTE_MBUF_DYNFIELD(tx_pkt,
+						igc_timestamp_dynfield_offset,
+						uint64_t *);
+					igc_set_xmit_ctx(txq, ctx_txd,
+						tx_ol_req, tx_offload, ts);
+				} else {
+					igc_set_xmit_ctx(txq, ctx_txd,
+						tx_ol_req, tx_offload, 0);
+				}
 
 				txe->last_id = tx_last;
 				tx_id = txe->next_id;
@@ -2081,9 +2111,11 @@ void
 igc_tx_init(struct rte_eth_dev *dev)
 {
 	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+	uint64_t offloads = dev->data->dev_conf.txmode.offloads;
 	uint32_t tctl;
 	uint32_t txdctl;
 	uint16_t i;
+	int err;
 
 	/* Setup the Base and Length of the Tx Descriptor Rings. */
 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
@@ -2113,6 +2145,16 @@ igc_tx_init(struct rte_eth_dev *dev)
 		IGC_WRITE_REG(hw, IGC_TXDCTL(txq->reg_idx), txdctl);
 	}
 
+	if (offloads & RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP) {
+		err = rte_mbuf_dyn_tx_timestamp_register(
+			&igc_timestamp_dynfield_offset,
+			&igc_timestamp_dynflag);
+		if (err) {
+			PMD_DRV_LOG(ERR,
+				"Cannot register mbuf field/flag for timestamp");
+		}
+	}
+
 	igc_config_collision_dist(hw);
 
 	/* Program the Transmit Control Register. */
diff --git a/drivers/net/igc/igc_txrx.h b/drivers/net/igc/igc_txrx.h
index e7272f8..73757d2 100644
--- a/drivers/net/igc/igc_txrx.h
+++ b/drivers/net/igc/igc_txrx.h
@@ -11,6 +11,9 @@
 extern "C" {
 #endif
 
+extern uint64_t igc_timestamp_dynflag;
+extern int igc_timestamp_dynfield_offset;
+
 struct igc_rx_entry {
 	struct rte_mbuf *mbuf; /**< mbuf associated with RX descriptor. */
 };
-- 
2.9.5


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

* [PATCH v2 0/2] net/igc: support launch time offloading
  2022-12-20  3:47 [PATCH 0/2] net/igc: support Tx timestamp offload Simei Su
  2022-12-20  3:47 ` [PATCH 1/2] net/igc/base: " Simei Su
  2022-12-20  3:47 ` [PATCH 2/2] net/igc: enable " Simei Su
@ 2023-02-01  7:30 ` Simei Su
  2023-02-01  7:30   ` [PATCH v2 1/2] net/igc/base: expose packet pacing registers Simei Su
                     ` (3 more replies)
  2 siblings, 4 replies; 14+ messages in thread
From: Simei Su @ 2023-02-01  7:30 UTC (permalink / raw)
  To: qi.z.zhang, junfeng.guo; +Cc: dev, wenjun1.wu, Simei Su

[PATCH v2 1/2] expose packet pacing registers
[PATCH v2 2/2] enable launch time offloading

v2:
* Refine title and commit log.
* Add release notes.
* Rename variable name.

Simei Su (2):
  net/igc/base: expose packet pacing registers
  net/igc: enable launch time offloading

 doc/guides/rel_notes/release_23_03.rst |  2 +-
 drivers/net/igc/base/igc_defines.h     |  9 +++++
 drivers/net/igc/base/igc_regs.h        |  8 ++++
 drivers/net/igc/igc_ethdev.c           | 70 ++++++++++++++++++++++++++++++++++
 drivers/net/igc/igc_ethdev.h           |  6 ++-
 drivers/net/igc/igc_txrx.c             | 58 ++++++++++++++++++++++++----
 drivers/net/igc/igc_txrx.h             |  3 ++
 7 files changed, 146 insertions(+), 10 deletions(-)

-- 
2.9.5


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

* [PATCH v2 1/2] net/igc/base: expose packet pacing registers
  2023-02-01  7:30 ` [PATCH v2 0/2] net/igc: support launch time offloading Simei Su
@ 2023-02-01  7:30   ` Simei Su
  2023-02-01  7:30   ` [PATCH v2 2/2] net/igc: enable launch time offloading Simei Su
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Simei Su @ 2023-02-01  7:30 UTC (permalink / raw)
  To: qi.z.zhang, junfeng.guo; +Cc: dev, wenjun1.wu, Simei Su

Add definitions for packet pacing(launch time offloading) related
registers.

Signed-off-by: Simei Su <simei.su@intel.com>
---
 drivers/net/igc/base/igc_defines.h | 9 +++++++++
 drivers/net/igc/base/igc_regs.h    | 8 ++++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/net/igc/base/igc_defines.h b/drivers/net/igc/base/igc_defines.h
index dd7330a..280570b 100644
--- a/drivers/net/igc/base/igc_defines.h
+++ b/drivers/net/igc/base/igc_defines.h
@@ -188,6 +188,15 @@
 #define IGC_RCTL_BSEX		0x02000000 /* Buffer size extension */
 #define IGC_RCTL_SECRC	0x04000000 /* Strip Ethernet CRC */
 
+#define IGC_DTXMXPKTSZ_TSN     0x19 /* 1600 bytes of max TX DMA packet size */
+#define IGC_TXPBSIZE_TSN       0x04145145 /* 5k bytes buffer for each queue */
+
+/* Transmit Scheduling */
+#define IGC_TQAVCTRL_TRANSMIT_MODE_TSN 0x00000001
+#define IGC_TQAVCTRL_ENHANCED_QAV      0x00000008
+
+#define IGC_TXQCTL_QUEUE_MODE_LAUNCHT  0x00000001
+
 /* Use byte values for the following shift parameters
  * Usage:
  *     psrctl |= (((ROUNDUP(value0, 128) >> IGC_PSRCTL_BSIZE0_SHIFT) &
diff --git a/drivers/net/igc/base/igc_regs.h b/drivers/net/igc/base/igc_regs.h
index d424387..e423814 100644
--- a/drivers/net/igc/base/igc_regs.h
+++ b/drivers/net/igc/base/igc_regs.h
@@ -602,6 +602,14 @@
 #define IGC_RXMTRL	0x0B634 /* Time sync Rx EtherType and Msg Type - RW */
 #define IGC_RXUDP	0x0B638 /* Time Sync Rx UDP Port - RW */
 
+#define IGC_QBVCYCLET	0x331C
+#define IGC_QBVCYCLET_S 0x3320
+#define IGC_STQT(_n)	(0x3324 + 0x4 * (_n))
+#define IGC_ENDQT(_n)	(0x3334 + 0x4 * (_n))
+#define IGC_TXQCTL(_n)	(0x3344 + 0x4 * (_n))
+#define IGC_BASET_L	0x3314
+#define IGC_BASET_H	0x3318
+
 /* Filtering Registers */
 #define IGC_SAQF(_n)	(0x05980 + (4 * (_n))) /* Source Address Queue Fltr */
 #define IGC_DAQF(_n)	(0x059A0 + (4 * (_n))) /* Dest Address Queue Fltr */
-- 
2.9.5


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

* [PATCH v2 2/2] net/igc: enable launch time offloading
  2023-02-01  7:30 ` [PATCH v2 0/2] net/igc: support launch time offloading Simei Su
  2023-02-01  7:30   ` [PATCH v2 1/2] net/igc/base: expose packet pacing registers Simei Su
@ 2023-02-01  7:30   ` Simei Su
  2023-02-01  8:34     ` Zhang, Qi Z
  2023-02-01  8:46   ` [PATCH v2 0/2] net/igc: support " Morten Brørup
  2023-02-02  7:17   ` [PATCH v3 " Simei Su
  3 siblings, 1 reply; 14+ messages in thread
From: Simei Su @ 2023-02-01  7:30 UTC (permalink / raw)
  To: qi.z.zhang, junfeng.guo; +Cc: dev, wenjun1.wu, Simei Su

The LaunchTime defines the scheduling time of the packet from
the packet buffer to the MAC. The launchtime of each packet is
specified as an offset applied to the BaseT registers while BaseT
is automatically incremented each cycle.

This patch supports Tx timestamp based packet pacing by leveraging
offload flag "RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP". We should set
the expected launchtime to the advanced transmit descriptor.

Signed-off-by: Simei Su <simei.su@intel.com>
---
 doc/guides/rel_notes/release_23_03.rst |  2 +-
 drivers/net/igc/igc_ethdev.c           | 70 ++++++++++++++++++++++++++++++++++
 drivers/net/igc/igc_ethdev.h           |  6 ++-
 drivers/net/igc/igc_txrx.c             | 58 ++++++++++++++++++++++++----
 drivers/net/igc/igc_txrx.h             |  3 ++
 5 files changed, 129 insertions(+), 10 deletions(-)

diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index d175f8e..5bca6af 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -79,7 +79,7 @@ New Features
 * **Updated Intel igc driver.**
 
   * Added timesync API support.
-
+  * Added packet pacing(launch time offloading) support.
 
 Removed Items
 -------------
diff --git a/drivers/net/igc/igc_ethdev.c b/drivers/net/igc/igc_ethdev.c
index ef3346b..fab2ab6 100644
--- a/drivers/net/igc/igc_ethdev.c
+++ b/drivers/net/igc/igc_ethdev.c
@@ -88,6 +88,9 @@
 #define IGC_I225_RX_LATENCY_1000	300
 #define IGC_I225_RX_LATENCY_2500	1485
 
+uint64_t igc_tx_timestamp_dynflag;
+int igc_tx_timestamp_dynfield_offset = -1;
+
 static const struct rte_eth_desc_lim rx_desc_lim = {
 	.nb_max = IGC_MAX_RXD,
 	.nb_min = IGC_MIN_RXD,
@@ -267,6 +270,7 @@ static int eth_igc_timesync_read_time(struct rte_eth_dev *dev,
 				  struct timespec *timestamp);
 static int eth_igc_timesync_write_time(struct rte_eth_dev *dev,
 				   const struct timespec *timestamp);
+static int eth_igc_read_clock(struct rte_eth_dev *dev, uint64_t *clock);
 
 static const struct eth_dev_ops eth_igc_ops = {
 	.dev_configure		= eth_igc_configure,
@@ -327,6 +331,7 @@ static const struct eth_dev_ops eth_igc_ops = {
 	.timesync_adjust_time	= eth_igc_timesync_adjust_time,
 	.timesync_read_time	= eth_igc_timesync_read_time,
 	.timesync_write_time	= eth_igc_timesync_write_time,
+	.read_clock             = eth_igc_read_clock,
 };
 
 /*
@@ -949,7 +954,12 @@ eth_igc_start(struct rte_eth_dev *dev)
 	struct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+	uint32_t nsec, sec, baset_l, baset_h, tqavctrl;
+	struct timespec system_time;
+	int64_t n, systime;
+	uint32_t txqctl = 0;
 	uint32_t *speeds;
+	uint16_t i;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -1009,6 +1019,55 @@ eth_igc_start(struct rte_eth_dev *dev)
 		return ret;
 	}
 
+	if (igc_tx_timestamp_dynflag > 0) {
+		adapter->base_time = 0;
+		adapter->cycle_time = NSEC_PER_SEC;
+
+		IGC_WRITE_REG(hw, IGC_TSSDP, 0);
+		IGC_WRITE_REG(hw, IGC_TSIM, TSINTR_TXTS);
+		IGC_WRITE_REG(hw, IGC_IMS, IGC_ICR_TS);
+
+		IGC_WRITE_REG(hw, IGC_TSAUXC, 0);
+		IGC_WRITE_REG(hw, IGC_I350_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
+		IGC_WRITE_REG(hw, IGC_TXPBS, IGC_TXPBSIZE_TSN);
+
+		tqavctrl = IGC_READ_REG(hw, IGC_I210_TQAVCTRL);
+		tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
+			    IGC_TQAVCTRL_ENHANCED_QAV;
+		IGC_WRITE_REG(hw, IGC_I210_TQAVCTRL, tqavctrl);
+
+		IGC_WRITE_REG(hw, IGC_QBVCYCLET_S, adapter->cycle_time);
+		IGC_WRITE_REG(hw, IGC_QBVCYCLET, adapter->cycle_time);
+
+		for (i = 0; i < dev->data->nb_tx_queues; i++) {
+			IGC_WRITE_REG(hw, IGC_STQT(i), 0);
+			IGC_WRITE_REG(hw, IGC_ENDQT(i), NSEC_PER_SEC);
+
+			txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
+			IGC_WRITE_REG(hw, IGC_TXQCTL(i), txqctl);
+		}
+
+		clock_gettime(CLOCK_REALTIME, &system_time);
+		IGC_WRITE_REG(hw, IGC_SYSTIML, system_time.tv_nsec);
+		IGC_WRITE_REG(hw, IGC_SYSTIMH, system_time.tv_sec);
+
+		nsec = IGC_READ_REG(hw, IGC_SYSTIML);
+		sec = IGC_READ_REG(hw, IGC_SYSTIMH);
+		systime = (int64_t)sec * NSEC_PER_SEC + (int64_t)nsec;
+
+		if (systime > adapter->base_time) {
+			n = (systime - adapter->base_time) /
+			     adapter->cycle_time;
+			adapter->base_time = adapter->base_time +
+				(n + 1) * adapter->cycle_time;
+		}
+
+		baset_h = adapter->base_time / NSEC_PER_SEC;
+		baset_l = adapter->base_time % NSEC_PER_SEC;
+		IGC_WRITE_REG(hw, IGC_BASET_H, baset_h);
+		IGC_WRITE_REG(hw, IGC_BASET_L, baset_l);
+	}
+
 	igc_clear_hw_cntrs_base_generic(hw);
 
 	/* VLAN Offload Settings */
@@ -2804,6 +2863,17 @@ eth_igc_timesync_disable(struct rte_eth_dev *dev)
 }
 
 static int
+eth_igc_read_clock(__rte_unused struct rte_eth_dev *dev, uint64_t *clock)
+{
+	struct timespec system_time;
+
+	clock_gettime(CLOCK_REALTIME, &system_time);
+	*clock = system_time.tv_sec * NSEC_PER_SEC + system_time.tv_nsec;
+
+	return 0;
+}
+
+static int
 eth_igc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
diff --git a/drivers/net/igc/igc_ethdev.h b/drivers/net/igc/igc_ethdev.h
index 237d3c1..8d7eb54 100644
--- a/drivers/net/igc/igc_ethdev.h
+++ b/drivers/net/igc/igc_ethdev.h
@@ -87,7 +87,8 @@ extern "C" {
 	RTE_ETH_TX_OFFLOAD_SCTP_CKSUM  | \
 	RTE_ETH_TX_OFFLOAD_TCP_TSO     | \
 	RTE_ETH_TX_OFFLOAD_UDP_TSO	   | \
-	RTE_ETH_TX_OFFLOAD_MULTI_SEGS)
+	RTE_ETH_TX_OFFLOAD_MULTI_SEGS  | \
+	RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP)
 
 #define IGC_RSS_OFFLOAD_ALL	(    \
 	RTE_ETH_RSS_IPV4               | \
@@ -240,6 +241,9 @@ struct igc_adapter {
 	struct igc_syn_filter syn_filter;
 	struct igc_rss_filter rss_filter;
 	struct igc_flow_list flow_list;
+
+	int64_t base_time;
+	uint32_t cycle_time;
 };
 
 #define IGC_DEV_PRIVATE(_dev)	((_dev)->data->dev_private)
diff --git a/drivers/net/igc/igc_txrx.c b/drivers/net/igc/igc_txrx.c
index 0236c7f..d8b00f7 100644
--- a/drivers/net/igc/igc_txrx.c
+++ b/drivers/net/igc/igc_txrx.c
@@ -1411,6 +1411,19 @@ what_advctx_update(struct igc_tx_queue *txq, uint64_t flags,
 	return IGC_CTX_NUM;
 }
 
+static uint32_t igc_tx_launchtime(uint64_t txtime, uint16_t port_id)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	struct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);
+	uint64_t base_time = adapter->base_time;
+	uint64_t cycle_time = adapter->cycle_time;
+	uint32_t launchtime;
+
+	launchtime = (txtime - base_time) % cycle_time;
+
+	return rte_cpu_to_le_32(launchtime);
+}
+
 /*
  * This is a separate function, looking for optimization opportunity here
  * Rework required to go with the pre-defined values.
@@ -1418,7 +1431,8 @@ what_advctx_update(struct igc_tx_queue *txq, uint64_t flags,
 static inline void
 igc_set_xmit_ctx(struct igc_tx_queue *txq,
 		volatile struct igc_adv_tx_context_desc *ctx_txd,
-		uint64_t ol_flags, union igc_tx_offload tx_offload)
+		uint64_t ol_flags, union igc_tx_offload tx_offload,
+		uint64_t txtime)
 {
 	uint32_t type_tucmd_mlhl;
 	uint32_t mss_l4len_idx;
@@ -1492,16 +1506,23 @@ igc_set_xmit_ctx(struct igc_tx_queue *txq,
 		}
 	}
 
-	txq->ctx_cache[ctx_curr].flags = ol_flags;
-	txq->ctx_cache[ctx_curr].tx_offload.data =
-		tx_offload_mask.data & tx_offload.data;
-	txq->ctx_cache[ctx_curr].tx_offload_mask = tx_offload_mask;
+	if (!txtime) {
+		txq->ctx_cache[ctx_curr].flags = ol_flags;
+		txq->ctx_cache[ctx_curr].tx_offload.data =
+			tx_offload_mask.data & tx_offload.data;
+		txq->ctx_cache[ctx_curr].tx_offload_mask = tx_offload_mask;
+	}
 
 	ctx_txd->type_tucmd_mlhl = rte_cpu_to_le_32(type_tucmd_mlhl);
 	vlan_macip_lens = (uint32_t)tx_offload.data;
 	ctx_txd->vlan_macip_lens = rte_cpu_to_le_32(vlan_macip_lens);
 	ctx_txd->mss_l4len_idx = rte_cpu_to_le_32(mss_l4len_idx);
-	ctx_txd->u.launch_time = 0;
+
+	if (txtime)
+		ctx_txd->u.launch_time = igc_tx_launchtime(txtime,
+							   txq->port_id);
+	else
+		ctx_txd->u.launch_time = 0;
 }
 
 static inline uint32_t
@@ -1551,6 +1572,7 @@ igc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	uint64_t tx_ol_req;
 	uint32_t new_ctx = 0;
 	union igc_tx_offload tx_offload = {0};
+	uint64_t ts;
 
 	tx_id = txq->tx_tail;
 	txe = &sw_ring[tx_id];
@@ -1698,8 +1720,16 @@ igc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 					txe->mbuf = NULL;
 				}
 
-				igc_set_xmit_ctx(txq, ctx_txd, tx_ol_req,
-						tx_offload);
+				if (igc_tx_timestamp_dynflag > 0) {
+					ts = *RTE_MBUF_DYNFIELD(tx_pkt,
+						igc_tx_timestamp_dynfield_offset,
+						uint64_t *);
+					igc_set_xmit_ctx(txq, ctx_txd,
+						tx_ol_req, tx_offload, ts);
+				} else {
+					igc_set_xmit_ctx(txq, ctx_txd,
+						tx_ol_req, tx_offload, 0);
+				}
 
 				txe->last_id = tx_last;
 				tx_id = txe->next_id;
@@ -2081,9 +2111,11 @@ void
 igc_tx_init(struct rte_eth_dev *dev)
 {
 	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+	uint64_t offloads = dev->data->dev_conf.txmode.offloads;
 	uint32_t tctl;
 	uint32_t txdctl;
 	uint16_t i;
+	int err;
 
 	/* Setup the Base and Length of the Tx Descriptor Rings. */
 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
@@ -2113,6 +2145,16 @@ igc_tx_init(struct rte_eth_dev *dev)
 		IGC_WRITE_REG(hw, IGC_TXDCTL(txq->reg_idx), txdctl);
 	}
 
+	if (offloads & RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP) {
+		err = rte_mbuf_dyn_tx_timestamp_register(
+			&igc_tx_timestamp_dynfield_offset,
+			&igc_tx_timestamp_dynflag);
+		if (err) {
+			PMD_DRV_LOG(ERR,
+				"Cannot register mbuf field/flag for timestamp");
+		}
+	}
+
 	igc_config_collision_dist(hw);
 
 	/* Program the Transmit Control Register. */
diff --git a/drivers/net/igc/igc_txrx.h b/drivers/net/igc/igc_txrx.h
index e7272f8..ad7d3b4 100644
--- a/drivers/net/igc/igc_txrx.h
+++ b/drivers/net/igc/igc_txrx.h
@@ -11,6 +11,9 @@
 extern "C" {
 #endif
 
+extern uint64_t igc_tx_timestamp_dynflag;
+extern int igc_tx_timestamp_dynfield_offset;
+
 struct igc_rx_entry {
 	struct rte_mbuf *mbuf; /**< mbuf associated with RX descriptor. */
 };
-- 
2.9.5


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

* RE: [PATCH v2 2/2] net/igc: enable launch time offloading
  2023-02-01  7:30   ` [PATCH v2 2/2] net/igc: enable launch time offloading Simei Su
@ 2023-02-01  8:34     ` Zhang, Qi Z
  0 siblings, 0 replies; 14+ messages in thread
From: Zhang, Qi Z @ 2023-02-01  8:34 UTC (permalink / raw)
  To: Su, Simei, Guo, Junfeng; +Cc: dev, Wu, Wenjun1



> -----Original Message-----
> From: Su, Simei <simei.su@intel.com>
> Sent: Wednesday, February 1, 2023 3:30 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Guo, Junfeng
> <junfeng.guo@intel.com>
> Cc: dev@dpdk.org; Wu, Wenjun1 <wenjun1.wu@intel.com>; Su, Simei
> <simei.su@intel.com>
> Subject: [PATCH v2 2/2] net/igc: enable launch time offloading
> 
> The LaunchTime defines the scheduling time of the packet from the packet
> buffer to the MAC. The launchtime of each packet is specified as an offset
> applied to the BaseT registers while BaseT is automatically incremented each
> cycle.
> 
> This patch supports Tx timestamp based packet pacing by leveraging offload
> flag "RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP". We should set the
> expected launchtime to the advanced transmit descriptor.
> 
> Signed-off-by: Simei Su <simei.su@intel.com>

There is a coding style warning need to fix.

You can use devtools/checkpatches.sh to check the coding style before submit.

Otherwise, the patchset looks good.



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

* RE: [PATCH v2 0/2] net/igc: support launch time offloading
  2023-02-01  7:30 ` [PATCH v2 0/2] net/igc: support launch time offloading Simei Su
  2023-02-01  7:30   ` [PATCH v2 1/2] net/igc/base: expose packet pacing registers Simei Su
  2023-02-01  7:30   ` [PATCH v2 2/2] net/igc: enable launch time offloading Simei Su
@ 2023-02-01  8:46   ` Morten Brørup
  2023-02-02  7:17   ` [PATCH v3 " Simei Su
  3 siblings, 0 replies; 14+ messages in thread
From: Morten Brørup @ 2023-02-01  8:46 UTC (permalink / raw)
  To: Simei Su, qi.z.zhang, junfeng.guo, Matan Azrad,
	Viacheslav Ovsiienko, Ferruh Yigit
  Cc: dev, wenjun1.wu

+To: Ferruh, Matan and Viacheslav, regarding feature documentation

> From: Simei Su [mailto:simei.su@intel.com]
> Sent: Wednesday, 1 February 2023 08.30
> 
> [PATCH v2 1/2] expose packet pacing registers
> [PATCH v2 2/2] enable launch time offloading
> 
> v2:
> * Refine title and commit log.
> * Add release notes.
> * Rename variable name.
> 
> Simei Su (2):
>   net/igc/base: expose packet pacing registers
>   net/igc: enable launch time offloading
> 
>  doc/guides/rel_notes/release_23_03.rst |  2 +-
>  drivers/net/igc/base/igc_defines.h     |  9 +++++
>  drivers/net/igc/base/igc_regs.h        |  8 ++++
>  drivers/net/igc/igc_ethdev.c           | 70
> ++++++++++++++++++++++++++++++++++
>  drivers/net/igc/igc_ethdev.h           |  6 ++-
>  drivers/net/igc/igc_txrx.c             | 58 ++++++++++++++++++++++++--
> --
>  drivers/net/igc/igc_txrx.h             |  3 ++
>  7 files changed, 146 insertions(+), 10 deletions(-)
> 
> --
> 2.9.5
> 

Series-acked-by: Morten Brørup <mb@smartsharesystems.com>

Please also note:

This RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP feature should be added to the documentation of NIC features [1] and [2].

[1]: https://doc.dpdk.org/guides/nics/overview.html
[2]: https://doc.dpdk.org/guides/nics/features.html

This should have been done when the feature was introduced by the mlx5 PMD. But apparently, no one thought about it back then. And late is better than never.

Also, adding the feature to the documentation might help deciding on a common name for it.


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

* [PATCH v3 0/2] net/igc: support launch time offloading
  2023-02-01  7:30 ` [PATCH v2 0/2] net/igc: support launch time offloading Simei Su
                     ` (2 preceding siblings ...)
  2023-02-01  8:46   ` [PATCH v2 0/2] net/igc: support " Morten Brørup
@ 2023-02-02  7:17   ` Simei Su
  2023-02-02  7:18     ` [PATCH v3 1/2] net/igc/base: expose packet pacing registers Simei Su
                       ` (2 more replies)
  3 siblings, 3 replies; 14+ messages in thread
From: Simei Su @ 2023-02-02  7:17 UTC (permalink / raw)
  To: qi.z.zhang, junfeng.guo; +Cc: dev, wenjun1.wu, Simei Su

[PATCH v3 1/2] expose packet pacing registers
[PATCH v3 2/2] enable launch time offloading

v3:
* Fix coding style issue.

v2:
* Refine title and commit log.
* Add release notes.
* Rename variable name.

Simei Su (2):
  net/igc/base: expose packet pacing registers
  net/igc: enable launch time offloading

 doc/guides/rel_notes/release_23_03.rst |  2 +-
 drivers/net/igc/base/igc_defines.h     |  9 +++++
 drivers/net/igc/base/igc_regs.h        |  8 ++++
 drivers/net/igc/igc_ethdev.c           | 70 ++++++++++++++++++++++++++++++++++
 drivers/net/igc/igc_ethdev.h           |  6 ++-
 drivers/net/igc/igc_txrx.c             | 58 ++++++++++++++++++++++++----
 drivers/net/igc/igc_txrx.h             |  3 ++
 7 files changed, 146 insertions(+), 10 deletions(-)

-- 
2.9.5


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

* [PATCH v3 1/2] net/igc/base: expose packet pacing registers
  2023-02-02  7:17   ` [PATCH v3 " Simei Su
@ 2023-02-02  7:18     ` Simei Su
  2023-02-02  7:18     ` [PATCH v3 2/2] net/igc: enable launch time offloading Simei Su
  2023-02-02  8:46     ` [PATCH v3 0/2] net/igc: support " Zhang, Qi Z
  2 siblings, 0 replies; 14+ messages in thread
From: Simei Su @ 2023-02-02  7:18 UTC (permalink / raw)
  To: qi.z.zhang, junfeng.guo; +Cc: dev, wenjun1.wu, Simei Su

Add definitions for packet pacing(launch time offloading) related
registers.

Signed-off-by: Simei Su <simei.su@intel.com>
---
 drivers/net/igc/base/igc_defines.h | 9 +++++++++
 drivers/net/igc/base/igc_regs.h    | 8 ++++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/net/igc/base/igc_defines.h b/drivers/net/igc/base/igc_defines.h
index dd7330a..280570b 100644
--- a/drivers/net/igc/base/igc_defines.h
+++ b/drivers/net/igc/base/igc_defines.h
@@ -188,6 +188,15 @@
 #define IGC_RCTL_BSEX		0x02000000 /* Buffer size extension */
 #define IGC_RCTL_SECRC	0x04000000 /* Strip Ethernet CRC */
 
+#define IGC_DTXMXPKTSZ_TSN     0x19 /* 1600 bytes of max TX DMA packet size */
+#define IGC_TXPBSIZE_TSN       0x04145145 /* 5k bytes buffer for each queue */
+
+/* Transmit Scheduling */
+#define IGC_TQAVCTRL_TRANSMIT_MODE_TSN 0x00000001
+#define IGC_TQAVCTRL_ENHANCED_QAV      0x00000008
+
+#define IGC_TXQCTL_QUEUE_MODE_LAUNCHT  0x00000001
+
 /* Use byte values for the following shift parameters
  * Usage:
  *     psrctl |= (((ROUNDUP(value0, 128) >> IGC_PSRCTL_BSIZE0_SHIFT) &
diff --git a/drivers/net/igc/base/igc_regs.h b/drivers/net/igc/base/igc_regs.h
index d424387..e423814 100644
--- a/drivers/net/igc/base/igc_regs.h
+++ b/drivers/net/igc/base/igc_regs.h
@@ -602,6 +602,14 @@
 #define IGC_RXMTRL	0x0B634 /* Time sync Rx EtherType and Msg Type - RW */
 #define IGC_RXUDP	0x0B638 /* Time Sync Rx UDP Port - RW */
 
+#define IGC_QBVCYCLET	0x331C
+#define IGC_QBVCYCLET_S 0x3320
+#define IGC_STQT(_n)	(0x3324 + 0x4 * (_n))
+#define IGC_ENDQT(_n)	(0x3334 + 0x4 * (_n))
+#define IGC_TXQCTL(_n)	(0x3344 + 0x4 * (_n))
+#define IGC_BASET_L	0x3314
+#define IGC_BASET_H	0x3318
+
 /* Filtering Registers */
 #define IGC_SAQF(_n)	(0x05980 + (4 * (_n))) /* Source Address Queue Fltr */
 #define IGC_DAQF(_n)	(0x059A0 + (4 * (_n))) /* Dest Address Queue Fltr */
-- 
2.9.5


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

* [PATCH v3 2/2] net/igc: enable launch time offloading
  2023-02-02  7:17   ` [PATCH v3 " Simei Su
  2023-02-02  7:18     ` [PATCH v3 1/2] net/igc/base: expose packet pacing registers Simei Su
@ 2023-02-02  7:18     ` Simei Su
  2023-02-03  0:30       ` Stephen Hemminger
  2023-02-02  8:46     ` [PATCH v3 0/2] net/igc: support " Zhang, Qi Z
  2 siblings, 1 reply; 14+ messages in thread
From: Simei Su @ 2023-02-02  7:18 UTC (permalink / raw)
  To: qi.z.zhang, junfeng.guo; +Cc: dev, wenjun1.wu, Simei Su

The LaunchTime defines the scheduling time of the packet from
the packet buffer to the MAC. The launchtime of each packet is
specified as an offset applied to the BaseT registers while BaseT
is automatically incremented each cycle.

This patch supports Tx timestamp based packet pacing by leveraging
offload flag "RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP". We should set
the expected launchtime to the advanced transmit descriptor.

Signed-off-by: Simei Su <simei.su@intel.com>
---
 doc/guides/rel_notes/release_23_03.rst |  2 +-
 drivers/net/igc/igc_ethdev.c           | 70 ++++++++++++++++++++++++++++++++++
 drivers/net/igc/igc_ethdev.h           |  6 ++-
 drivers/net/igc/igc_txrx.c             | 58 ++++++++++++++++++++++++----
 drivers/net/igc/igc_txrx.h             |  3 ++
 5 files changed, 129 insertions(+), 10 deletions(-)

diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index d175f8e..5bca6af 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -79,7 +79,7 @@ New Features
 * **Updated Intel igc driver.**
 
   * Added timesync API support.
-
+  * Added packet pacing(launch time offloading) support.
 
 Removed Items
 -------------
diff --git a/drivers/net/igc/igc_ethdev.c b/drivers/net/igc/igc_ethdev.c
index ef3346b..fab2ab6 100644
--- a/drivers/net/igc/igc_ethdev.c
+++ b/drivers/net/igc/igc_ethdev.c
@@ -88,6 +88,9 @@
 #define IGC_I225_RX_LATENCY_1000	300
 #define IGC_I225_RX_LATENCY_2500	1485
 
+uint64_t igc_tx_timestamp_dynflag;
+int igc_tx_timestamp_dynfield_offset = -1;
+
 static const struct rte_eth_desc_lim rx_desc_lim = {
 	.nb_max = IGC_MAX_RXD,
 	.nb_min = IGC_MIN_RXD,
@@ -267,6 +270,7 @@ static int eth_igc_timesync_read_time(struct rte_eth_dev *dev,
 				  struct timespec *timestamp);
 static int eth_igc_timesync_write_time(struct rte_eth_dev *dev,
 				   const struct timespec *timestamp);
+static int eth_igc_read_clock(struct rte_eth_dev *dev, uint64_t *clock);
 
 static const struct eth_dev_ops eth_igc_ops = {
 	.dev_configure		= eth_igc_configure,
@@ -327,6 +331,7 @@ static const struct eth_dev_ops eth_igc_ops = {
 	.timesync_adjust_time	= eth_igc_timesync_adjust_time,
 	.timesync_read_time	= eth_igc_timesync_read_time,
 	.timesync_write_time	= eth_igc_timesync_write_time,
+	.read_clock             = eth_igc_read_clock,
 };
 
 /*
@@ -949,7 +954,12 @@ eth_igc_start(struct rte_eth_dev *dev)
 	struct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+	uint32_t nsec, sec, baset_l, baset_h, tqavctrl;
+	struct timespec system_time;
+	int64_t n, systime;
+	uint32_t txqctl = 0;
 	uint32_t *speeds;
+	uint16_t i;
 	int ret;
 
 	PMD_INIT_FUNC_TRACE();
@@ -1009,6 +1019,55 @@ eth_igc_start(struct rte_eth_dev *dev)
 		return ret;
 	}
 
+	if (igc_tx_timestamp_dynflag > 0) {
+		adapter->base_time = 0;
+		adapter->cycle_time = NSEC_PER_SEC;
+
+		IGC_WRITE_REG(hw, IGC_TSSDP, 0);
+		IGC_WRITE_REG(hw, IGC_TSIM, TSINTR_TXTS);
+		IGC_WRITE_REG(hw, IGC_IMS, IGC_ICR_TS);
+
+		IGC_WRITE_REG(hw, IGC_TSAUXC, 0);
+		IGC_WRITE_REG(hw, IGC_I350_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
+		IGC_WRITE_REG(hw, IGC_TXPBS, IGC_TXPBSIZE_TSN);
+
+		tqavctrl = IGC_READ_REG(hw, IGC_I210_TQAVCTRL);
+		tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
+			    IGC_TQAVCTRL_ENHANCED_QAV;
+		IGC_WRITE_REG(hw, IGC_I210_TQAVCTRL, tqavctrl);
+
+		IGC_WRITE_REG(hw, IGC_QBVCYCLET_S, adapter->cycle_time);
+		IGC_WRITE_REG(hw, IGC_QBVCYCLET, adapter->cycle_time);
+
+		for (i = 0; i < dev->data->nb_tx_queues; i++) {
+			IGC_WRITE_REG(hw, IGC_STQT(i), 0);
+			IGC_WRITE_REG(hw, IGC_ENDQT(i), NSEC_PER_SEC);
+
+			txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
+			IGC_WRITE_REG(hw, IGC_TXQCTL(i), txqctl);
+		}
+
+		clock_gettime(CLOCK_REALTIME, &system_time);
+		IGC_WRITE_REG(hw, IGC_SYSTIML, system_time.tv_nsec);
+		IGC_WRITE_REG(hw, IGC_SYSTIMH, system_time.tv_sec);
+
+		nsec = IGC_READ_REG(hw, IGC_SYSTIML);
+		sec = IGC_READ_REG(hw, IGC_SYSTIMH);
+		systime = (int64_t)sec * NSEC_PER_SEC + (int64_t)nsec;
+
+		if (systime > adapter->base_time) {
+			n = (systime - adapter->base_time) /
+			     adapter->cycle_time;
+			adapter->base_time = adapter->base_time +
+				(n + 1) * adapter->cycle_time;
+		}
+
+		baset_h = adapter->base_time / NSEC_PER_SEC;
+		baset_l = adapter->base_time % NSEC_PER_SEC;
+		IGC_WRITE_REG(hw, IGC_BASET_H, baset_h);
+		IGC_WRITE_REG(hw, IGC_BASET_L, baset_l);
+	}
+
 	igc_clear_hw_cntrs_base_generic(hw);
 
 	/* VLAN Offload Settings */
@@ -2804,6 +2863,17 @@ eth_igc_timesync_disable(struct rte_eth_dev *dev)
 }
 
 static int
+eth_igc_read_clock(__rte_unused struct rte_eth_dev *dev, uint64_t *clock)
+{
+	struct timespec system_time;
+
+	clock_gettime(CLOCK_REALTIME, &system_time);
+	*clock = system_time.tv_sec * NSEC_PER_SEC + system_time.tv_nsec;
+
+	return 0;
+}
+
+static int
 eth_igc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
diff --git a/drivers/net/igc/igc_ethdev.h b/drivers/net/igc/igc_ethdev.h
index 237d3c1..8d7eb54 100644
--- a/drivers/net/igc/igc_ethdev.h
+++ b/drivers/net/igc/igc_ethdev.h
@@ -87,7 +87,8 @@ extern "C" {
 	RTE_ETH_TX_OFFLOAD_SCTP_CKSUM  | \
 	RTE_ETH_TX_OFFLOAD_TCP_TSO     | \
 	RTE_ETH_TX_OFFLOAD_UDP_TSO	   | \
-	RTE_ETH_TX_OFFLOAD_MULTI_SEGS)
+	RTE_ETH_TX_OFFLOAD_MULTI_SEGS  | \
+	RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP)
 
 #define IGC_RSS_OFFLOAD_ALL	(    \
 	RTE_ETH_RSS_IPV4               | \
@@ -240,6 +241,9 @@ struct igc_adapter {
 	struct igc_syn_filter syn_filter;
 	struct igc_rss_filter rss_filter;
 	struct igc_flow_list flow_list;
+
+	int64_t base_time;
+	uint32_t cycle_time;
 };
 
 #define IGC_DEV_PRIVATE(_dev)	((_dev)->data->dev_private)
diff --git a/drivers/net/igc/igc_txrx.c b/drivers/net/igc/igc_txrx.c
index 0236c7f..c11b6f7 100644
--- a/drivers/net/igc/igc_txrx.c
+++ b/drivers/net/igc/igc_txrx.c
@@ -1411,6 +1411,19 @@ what_advctx_update(struct igc_tx_queue *txq, uint64_t flags,
 	return IGC_CTX_NUM;
 }
 
+static uint32_t igc_tx_launchtime(uint64_t txtime, uint16_t port_id)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	struct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);
+	uint64_t base_time = adapter->base_time;
+	uint64_t cycle_time = adapter->cycle_time;
+	uint32_t launchtime;
+
+	launchtime = (txtime - base_time) % cycle_time;
+
+	return rte_cpu_to_le_32(launchtime);
+}
+
 /*
  * This is a separate function, looking for optimization opportunity here
  * Rework required to go with the pre-defined values.
@@ -1418,7 +1431,8 @@ what_advctx_update(struct igc_tx_queue *txq, uint64_t flags,
 static inline void
 igc_set_xmit_ctx(struct igc_tx_queue *txq,
 		volatile struct igc_adv_tx_context_desc *ctx_txd,
-		uint64_t ol_flags, union igc_tx_offload tx_offload)
+		uint64_t ol_flags, union igc_tx_offload tx_offload,
+		uint64_t txtime)
 {
 	uint32_t type_tucmd_mlhl;
 	uint32_t mss_l4len_idx;
@@ -1492,16 +1506,23 @@ igc_set_xmit_ctx(struct igc_tx_queue *txq,
 		}
 	}
 
-	txq->ctx_cache[ctx_curr].flags = ol_flags;
-	txq->ctx_cache[ctx_curr].tx_offload.data =
-		tx_offload_mask.data & tx_offload.data;
-	txq->ctx_cache[ctx_curr].tx_offload_mask = tx_offload_mask;
+	if (!txtime) {
+		txq->ctx_cache[ctx_curr].flags = ol_flags;
+		txq->ctx_cache[ctx_curr].tx_offload.data =
+			tx_offload_mask.data & tx_offload.data;
+		txq->ctx_cache[ctx_curr].tx_offload_mask = tx_offload_mask;
+	}
 
 	ctx_txd->type_tucmd_mlhl = rte_cpu_to_le_32(type_tucmd_mlhl);
 	vlan_macip_lens = (uint32_t)tx_offload.data;
 	ctx_txd->vlan_macip_lens = rte_cpu_to_le_32(vlan_macip_lens);
 	ctx_txd->mss_l4len_idx = rte_cpu_to_le_32(mss_l4len_idx);
-	ctx_txd->u.launch_time = 0;
+
+	if (txtime)
+		ctx_txd->u.launch_time = igc_tx_launchtime(txtime,
+							   txq->port_id);
+	else
+		ctx_txd->u.launch_time = 0;
 }
 
 static inline uint32_t
@@ -1551,6 +1572,7 @@ igc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	uint64_t tx_ol_req;
 	uint32_t new_ctx = 0;
 	union igc_tx_offload tx_offload = {0};
+	uint64_t ts;
 
 	tx_id = txq->tx_tail;
 	txe = &sw_ring[tx_id];
@@ -1698,8 +1720,16 @@ igc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 					txe->mbuf = NULL;
 				}
 
-				igc_set_xmit_ctx(txq, ctx_txd, tx_ol_req,
-						tx_offload);
+				if (igc_tx_timestamp_dynflag > 0) {
+					ts = *RTE_MBUF_DYNFIELD(tx_pkt,
+						igc_tx_timestamp_dynfield_offset,
+						uint64_t *);
+					igc_set_xmit_ctx(txq, ctx_txd,
+						tx_ol_req, tx_offload, ts);
+				} else {
+					igc_set_xmit_ctx(txq, ctx_txd,
+						tx_ol_req, tx_offload, 0);
+				}
 
 				txe->last_id = tx_last;
 				tx_id = txe->next_id;
@@ -2081,9 +2111,11 @@ void
 igc_tx_init(struct rte_eth_dev *dev)
 {
 	struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+	uint64_t offloads = dev->data->dev_conf.txmode.offloads;
 	uint32_t tctl;
 	uint32_t txdctl;
 	uint16_t i;
+	int err;
 
 	/* Setup the Base and Length of the Tx Descriptor Rings. */
 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
@@ -2113,6 +2145,16 @@ igc_tx_init(struct rte_eth_dev *dev)
 		IGC_WRITE_REG(hw, IGC_TXDCTL(txq->reg_idx), txdctl);
 	}
 
+	if (offloads & RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP) {
+		err = rte_mbuf_dyn_tx_timestamp_register
+			(&igc_tx_timestamp_dynfield_offset,
+			 &igc_tx_timestamp_dynflag);
+		if (err) {
+			PMD_DRV_LOG(ERR,
+				"Cannot register mbuf field/flag for timestamp");
+		}
+	}
+
 	igc_config_collision_dist(hw);
 
 	/* Program the Transmit Control Register. */
diff --git a/drivers/net/igc/igc_txrx.h b/drivers/net/igc/igc_txrx.h
index e7272f8..ad7d3b4 100644
--- a/drivers/net/igc/igc_txrx.h
+++ b/drivers/net/igc/igc_txrx.h
@@ -11,6 +11,9 @@
 extern "C" {
 #endif
 
+extern uint64_t igc_tx_timestamp_dynflag;
+extern int igc_tx_timestamp_dynfield_offset;
+
 struct igc_rx_entry {
 	struct rte_mbuf *mbuf; /**< mbuf associated with RX descriptor. */
 };
-- 
2.9.5


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

* RE: [PATCH v3 0/2] net/igc: support launch time offloading
  2023-02-02  7:17   ` [PATCH v3 " Simei Su
  2023-02-02  7:18     ` [PATCH v3 1/2] net/igc/base: expose packet pacing registers Simei Su
  2023-02-02  7:18     ` [PATCH v3 2/2] net/igc: enable launch time offloading Simei Su
@ 2023-02-02  8:46     ` Zhang, Qi Z
  2 siblings, 0 replies; 14+ messages in thread
From: Zhang, Qi Z @ 2023-02-02  8:46 UTC (permalink / raw)
  To: Su, Simei, Guo, Junfeng; +Cc: dev, Wu, Wenjun1



> -----Original Message-----
> From: Su, Simei <simei.su@intel.com>
> Sent: Thursday, February 2, 2023 3:18 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>; Guo, Junfeng
> <junfeng.guo@intel.com>
> Cc: dev@dpdk.org; Wu, Wenjun1 <wenjun1.wu@intel.com>; Su, Simei
> <simei.su@intel.com>
> Subject: [PATCH v3 0/2] net/igc: support launch time offloading
> 
> [PATCH v3 1/2] expose packet pacing registers [PATCH v3 2/2] enable launch
> time offloading
> 
> v3:
> * Fix coding style issue.
> 
> v2:
> * Refine title and commit log.
> * Add release notes.
> * Rename variable name.
> 
> Simei Su (2):
>   net/igc/base: expose packet pacing registers
>   net/igc: enable launch time offloading
> 
>  doc/guides/rel_notes/release_23_03.rst |  2 +-
>  drivers/net/igc/base/igc_defines.h     |  9 +++++
>  drivers/net/igc/base/igc_regs.h        |  8 ++++
>  drivers/net/igc/igc_ethdev.c           | 70
> ++++++++++++++++++++++++++++++++++
>  drivers/net/igc/igc_ethdev.h           |  6 ++-
>  drivers/net/igc/igc_txrx.c             | 58 ++++++++++++++++++++++++----
>  drivers/net/igc/igc_txrx.h             |  3 ++
>  7 files changed, 146 insertions(+), 10 deletions(-)
> 
> --
> 2.9.5

Acked-by: Qi Zhang <qi.z.zhang@intel.com>

Applied to dpdk-next-net-intel.

Thanks
Qi


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

* Re: [PATCH v3 2/2] net/igc: enable launch time offloading
  2023-02-02  7:18     ` [PATCH v3 2/2] net/igc: enable launch time offloading Simei Su
@ 2023-02-03  0:30       ` Stephen Hemminger
  2023-02-03  3:22         ` Su, Simei
  0 siblings, 1 reply; 14+ messages in thread
From: Stephen Hemminger @ 2023-02-03  0:30 UTC (permalink / raw)
  To: Simei Su; +Cc: qi.z.zhang, junfeng.guo, dev, wenjun1.wu

On Thu,  2 Feb 2023 15:18:01 +0800
Simei Su <simei.su@intel.com> wrote:

>  
> +static uint32_t igc_tx_launchtime(uint64_t txtime, uint16_t port_id)
> +{
> +	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
> +	struct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);
> +	uint64_t base_time = adapter->base_time;
> +	uint64_t cycle_time = adapter->cycle_time;
> +	uint32_t launchtime;
> +
> +	launchtime = (txtime - base_time) % cycle_time;
> +
> +	return rte_cpu_to_le_32(launchtime);
> +}


Divide in transmit path will slow things down.
Better to use something like rte_reciprocal_divide_64() to avoid slow 64 bit divide.

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

* RE: [PATCH v3 2/2] net/igc: enable launch time offloading
  2023-02-03  0:30       ` Stephen Hemminger
@ 2023-02-03  3:22         ` Su, Simei
  0 siblings, 0 replies; 14+ messages in thread
From: Su, Simei @ 2023-02-03  3:22 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Zhang, Qi Z, Guo, Junfeng, dev, Wu, Wenjun1

Hi Stephen,

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Friday, February 3, 2023 8:31 AM
> To: Su, Simei <simei.su@intel.com>
> Cc: Zhang, Qi Z <qi.z.zhang@intel.com>; Guo, Junfeng
> <junfeng.guo@intel.com>; dev@dpdk.org; Wu, Wenjun1
> <wenjun1.wu@intel.com>
> Subject: Re: [PATCH v3 2/2] net/igc: enable launch time offloading
> 
> On Thu,  2 Feb 2023 15:18:01 +0800
> Simei Su <simei.su@intel.com> wrote:
> 
> >
> > +static uint32_t igc_tx_launchtime(uint64_t txtime, uint16_t port_id)
> > +{
> > +	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
> > +	struct igc_adapter *adapter = IGC_DEV_PRIVATE(dev);
> > +	uint64_t base_time = adapter->base_time;
> > +	uint64_t cycle_time = adapter->cycle_time;
> > +	uint32_t launchtime;
> > +
> > +	launchtime = (txtime - base_time) % cycle_time;
> > +
> > +	return rte_cpu_to_le_32(launchtime); }
> 
> 
> Divide in transmit path will slow things down.
> Better to use something like rte_reciprocal_divide_64() to avoid slow 64 bit
> divide.

Thanks for your comments.
The performance won't be affected if the launchtime function is turned off.
If the function is turned on, it indeed doesn't need high performance based on the function.

Thanks,
Simei

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

end of thread, other threads:[~2023-02-03  3:23 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-20  3:47 [PATCH 0/2] net/igc: support Tx timestamp offload Simei Su
2022-12-20  3:47 ` [PATCH 1/2] net/igc/base: " Simei Su
2022-12-20  3:47 ` [PATCH 2/2] net/igc: enable " Simei Su
2023-02-01  7:30 ` [PATCH v2 0/2] net/igc: support launch time offloading Simei Su
2023-02-01  7:30   ` [PATCH v2 1/2] net/igc/base: expose packet pacing registers Simei Su
2023-02-01  7:30   ` [PATCH v2 2/2] net/igc: enable launch time offloading Simei Su
2023-02-01  8:34     ` Zhang, Qi Z
2023-02-01  8:46   ` [PATCH v2 0/2] net/igc: support " Morten Brørup
2023-02-02  7:17   ` [PATCH v3 " Simei Su
2023-02-02  7:18     ` [PATCH v3 1/2] net/igc/base: expose packet pacing registers Simei Su
2023-02-02  7:18     ` [PATCH v3 2/2] net/igc: enable launch time offloading Simei Su
2023-02-03  0:30       ` Stephen Hemminger
2023-02-03  3:22         ` Su, Simei
2023-02-02  8:46     ` [PATCH v3 0/2] net/igc: support " Zhang, Qi Z

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