All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junlong Wang <wang.junlong1@zte.com.cn>
To: stephen@networkplumber.org
Cc: dev@dpdk.org, Junlong Wang <wang.junlong1@zte.com.cn>
Subject: [PATCH v3 3/5] net/zxdh: add link speed set and autoneg get support
Date: Sat, 31 Jan 2026 14:22:06 +0800	[thread overview]
Message-ID: <20260131062208.2445121-4-wang.junlong1@zte.com.cn> (raw)
In-Reply-To: <20260131062208.2445121-1-wang.junlong1@zte.com.cn>


[-- Attachment #1.1.1: Type: text/plain, Size: 13505 bytes --]

add support ops to set link speed in usermode, and
get autoneg stats.

Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn>
---
 drivers/net/zxdh/zxdh_ethdev.c     |   6 ++
 drivers/net/zxdh/zxdh_ethdev.h     |   7 +-
 drivers/net/zxdh/zxdh_ethdev_ops.c | 116 ++++++++++++++++++++++++++---
 drivers/net/zxdh/zxdh_ethdev_ops.h |  15 ++++
 drivers/net/zxdh/zxdh_msg.c        |  49 ++++++++++++
 drivers/net/zxdh/zxdh_msg.h        |  24 +++++-
 6 files changed, 202 insertions(+), 15 deletions(-)

diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c
index 2fc2d78aff..823b1ffb5c 100644
--- a/drivers/net/zxdh/zxdh_ethdev.c
+++ b/drivers/net/zxdh/zxdh_ethdev.c
@@ -1432,6 +1432,10 @@ zxdh_dev_start(struct rte_eth_dev *dev)
 		zxdh_queue_notify(vq);
 	}
 
+	if (hw->is_pf)
+		zxdh_link_speed_set(dev);
+	zxdh_autoneg_stats_get(dev);
+
 	hw->admin_status = RTE_ETH_LINK_UP;
 	zxdh_dev_link_update(dev, 0);
 
@@ -1604,6 +1608,8 @@ zxdh_agent_comm(struct rte_eth_dev *eth_dev, struct zxdh_hw *hw)
 		return -1;
 	}
 
+	zxdh_speed_modes_get(eth_dev);
+
 	if (hw->switchoffload)
 		hw->phyport = 9;
 
diff --git a/drivers/net/zxdh/zxdh_ethdev.h b/drivers/net/zxdh/zxdh_ethdev.h
index 411d287f32..81b385ecb8 100644
--- a/drivers/net/zxdh/zxdh_ethdev.h
+++ b/drivers/net/zxdh/zxdh_ethdev.h
@@ -125,7 +125,7 @@ struct zxdh_hw {
 	uint64_t host_features;
 	uint64_t guest_features;
 	uint32_t speed;
-	uint32_t speed_mode;
+	int32_t speed_mode;
 	uint32_t notify_off_multiplier;
 	union zxdh_virport_num vport;
 	uint16_t max_queue_pairs;
@@ -173,9 +173,10 @@ struct zxdh_hw {
 	struct zxdh_vlan_offload_cfg vlan_offload_cfg;
 	uint16_t queue_pool_count;
 	uint16_t queue_pool_start;
-	uint8_t dl_net_hdr_len;
 	uint16_t vxlan_fd_num;
-	uint8_t rsv1[1];
+	uint32_t support_speed_modes;
+	uint8_t dl_net_hdr_len;
+	uint8_t autoneg;
 
 	struct dh_flow_list dh_flow_list;
 };
diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.c b/drivers/net/zxdh/zxdh_ethdev_ops.c
index cabf81107e..4b29cb7c82 100644
--- a/drivers/net/zxdh/zxdh_ethdev_ops.c
+++ b/drivers/net/zxdh/zxdh_ethdev_ops.c
@@ -307,7 +307,6 @@ zxdh_link_info_get(struct rte_eth_dev *dev, struct rte_eth_link *link)
 		}
 
 		link->link_speed = ZXDH_GET(link_info_msg, link_msg_addr, speed);
-		link->link_autoneg = ZXDH_GET(link_info_msg, link_msg_addr, autoneg);
 		hw->speed_mode = ZXDH_GET(link_info_msg, link_msg_addr, speed_modes);
 		if ((ZXDH_GET(link_info_msg, link_msg_addr, duplex) & RTE_ETH_LINK_FULL_DUPLEX) ==
 				RTE_ETH_LINK_FULL_DUPLEX)
@@ -322,6 +321,7 @@ zxdh_link_info_get(struct rte_eth_dev *dev, struct rte_eth_link *link)
 		link->link_autoneg = RTE_ETH_LINK_AUTONEG;
 		link->link_status = RTE_ETH_LINK_UP;
 	}
+	link->link_autoneg = hw->autoneg;
 	hw->speed = link->link_speed;
 
 	return 0;
@@ -368,6 +368,110 @@ int zxdh_dev_set_link_up(struct rte_eth_dev *dev)
 	return ret;
 }
 
+static int32_t zxdh_speed_mode_to_spm(uint32_t link_speed_modes)
+{
+	switch (link_speed_modes) {
+	case RTE_ETH_LINK_SPEED_1G:   return ZXDH_SPM_SPEED_1X_1G;
+	case RTE_ETH_LINK_SPEED_10G:  return ZXDH_SPM_SPEED_1X_10G;
+	case RTE_ETH_LINK_SPEED_25G:  return ZXDH_SPM_SPEED_1X_25G;
+	case RTE_ETH_LINK_SPEED_50G:  return ZXDH_SPM_SPEED_1X_50G;
+	case RTE_ETH_LINK_SPEED_100G: return ZXDH_SPM_SPEED_4X_100G;
+	case RTE_ETH_LINK_SPEED_200G: return ZXDH_SPM_SPEED_4X_200G;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported speed!");
+		return -1;
+	}
+}
+
+int32_t zxdh_link_speed_set(struct rte_eth_dev *dev)
+{
+	struct zxdh_hw *hw = dev->data->dev_private;
+	struct zxdh_msg_info msg;
+	uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)];
+	void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
+	int32_t spm_speed_modes;
+	int32_t ret;
+
+	spm_speed_modes =
+		zxdh_speed_mode_to_spm(dev->data->dev_conf.link_speeds & ~RTE_ETH_LINK_SPEED_FIXED);
+	if (spm_speed_modes == -1 || spm_speed_modes == hw->speed_mode) {
+		PMD_DRV_LOG(DEBUG, "not need update speed");
+		return 0;
+	}
+	if ((spm_speed_modes & hw->support_speed_modes) == 0)  {
+		PMD_DRV_LOG(ERR, "not support configure this speed");
+		return 0;
+	}
+
+	zxdh_agent_msg_build(hw, ZXDH_MAC_SPEED_SET, &msg);
+	msg.data.link_msg.autoneg = 0;
+	msg.data.link_msg.speed_modes = spm_speed_modes & hw->support_speed_modes;
+
+	ret = zxdh_send_msg_to_riscv(dev, &msg, sizeof(struct zxdh_msg_info),
+				zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),
+				ZXDH_BAR_MODULE_MAC);
+	uint8_t flag = ZXDH_GET(msg_reply_body, reply_body_addr, flag);
+	if (flag != ZXDH_REPS_SUCC || ret) {
+		PMD_DRV_LOG(ERR, "failed to set link speed!");
+		return -1;
+	}
+
+	return 0;
+}
+
+void
+zxdh_speed_modes_get(struct rte_eth_dev *dev)
+{
+	struct zxdh_hw *hw = dev->data->dev_private;
+	struct zxdh_msg_info msg;
+	uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)];
+	int32_t ret;
+
+	if (!hw->is_pf)
+		return;
+
+	msg.agent_msg_head.msg_type = ZXDH_MAC_PHYPORT_INIT;
+	msg.agent_msg_head.init = 1;
+
+	ret = zxdh_send_msg_to_riscv(dev, &msg, sizeof(struct zxdh_msg_info),
+				zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),
+				ZXDH_BAR_MODULE_MAC);
+	if (ret)
+		PMD_DRV_LOG(ERR, "Failed to get speed mode info");
+
+	void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
+	void *link_msg_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, link_msg);
+	uint32_t speed_modes = ZXDH_GET(link_info_msg, link_msg_addr, speed_modes);
+
+	hw->support_speed_modes = speed_modes;
+}
+
+int32_t zxdh_autoneg_stats_get(struct rte_eth_dev *dev)
+{
+	struct zxdh_hw *hw = dev->data->dev_private;
+	struct zxdh_msg_info msg;
+	uint8_t zxdh_msg_reply_info[ZXDH_ST_SZ_BYTES(msg_reply_info)];
+	int32_t ret;
+
+	zxdh_agent_msg_build(hw, ZXDH_MAC_AUTONEG_GET, &msg);
+
+	ret = zxdh_send_msg_to_riscv(dev, &msg, sizeof(struct zxdh_msg_info),
+				zxdh_msg_reply_info, ZXDH_ST_SZ_BYTES(msg_reply_info),
+				ZXDH_BAR_MODULE_MAC);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to get link autoneg stats!");
+		return -1;
+	}
+	void *reply_body_addr = ZXDH_ADDR_OF(msg_reply_info, zxdh_msg_reply_info, reply_body);
+	void *link_addr = ZXDH_ADDR_OF(msg_reply_body, reply_body_addr, link_msg);
+	void *link_autoeng_addr = ZXDH_ADDR_OF(link_info_msg, link_addr, autoneg);
+
+	hw->autoneg = *(uint8_t *)link_autoeng_addr;
+	PMD_DRV_LOG(DEBUG, "autoneg stats is: %d", hw->autoneg);
+
+	return 0;
+}
+
 int32_t zxdh_dev_link_update(struct rte_eth_dev *dev, int32_t wait_to_complete __rte_unused)
 {
 	struct rte_eth_link link;
@@ -384,17 +488,7 @@ int32_t zxdh_dev_link_update(struct rte_eth_dev *dev, int32_t wait_to_complete _
 		PMD_DRV_LOG(ERR, "Failed to get link status from hw");
 		return ret;
 	}
-	link.link_status &= hw->admin_status;
-	if (link.link_status == RTE_ETH_LINK_DOWN) {
-		PMD_DRV_LOG(DEBUG, "dev link status is down.");
-		goto link_down;
-	}
-	goto out;
 
-link_down:
-	link.link_status = RTE_ETH_LINK_DOWN;
-	link.link_speed  = RTE_ETH_SPEED_NUM_UNKNOWN;
-out:
 	if (link.link_status != dev->data->dev_link.link_status) {
 		ret = zxdh_config_port_status(dev, link.link_status);
 		if (ret != 0) {
diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.h b/drivers/net/zxdh/zxdh_ethdev_ops.h
index 85e926887b..6dfe4be473 100644
--- a/drivers/net/zxdh/zxdh_ethdev_ops.h
+++ b/drivers/net/zxdh/zxdh_ethdev_ops.h
@@ -27,6 +27,18 @@
 #define ZXDH_RSS_HF  ((ZXDH_HF_MAC_VLAN_ETH | ZXDH_HF_F3_ETH | ZXDH_HF_F5_ETH))
 
 #define ZXDH_ETHER_MIN_MTU      68
+#define ZXDH_SPM_SPEED_1X_10M          RTE_BIT32(0)
+#define ZXDH_SPM_SPEED_1X_100M         RTE_BIT32(1)
+#define ZXDH_SPM_SPEED_1X_1G           RTE_BIT32(2)
+#define ZXDH_SPM_SPEED_1X_2DOT5G       RTE_BIT32(3)
+#define ZXDH_SPM_SPEED_1X_5G           RTE_BIT32(4)
+#define ZXDH_SPM_SPEED_1X_10G          RTE_BIT32(5)
+#define ZXDH_SPM_SPEED_1X_25G          RTE_BIT32(6)
+#define ZXDH_SPM_SPEED_1X_50G          RTE_BIT32(7)
+#define ZXDH_SPM_SPEED_2X_100G         RTE_BIT32(8)
+#define ZXDH_SPM_SPEED_4X_40G          RTE_BIT32(9)
+#define ZXDH_SPM_SPEED_4X_100G         RTE_BIT32(10)
+#define ZXDH_SPM_SPEED_4X_200G         RTE_BIT32(11)
 
 struct zxdh_np_stats_data {
 	uint64_t n_pkts_dropped;
@@ -144,5 +156,8 @@ int zxdh_dev_get_module_info(struct rte_eth_dev *dev, struct rte_eth_dev_module_
 int zxdh_dev_get_module_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *info);
 int zxdh_meter_ops_get(struct rte_eth_dev *dev, void *arg);
 uint16_t zxdh_hw_qid_to_logic_qid(struct rte_eth_dev *dev, uint16_t qid);
+int32_t zxdh_link_speed_set(struct rte_eth_dev *dev);
+void zxdh_speed_modes_get(struct rte_eth_dev *dev);
+int32_t zxdh_autoneg_stats_get(struct rte_eth_dev *dev);
 
 #endif /* ZXDH_ETHDEV_OPS_H */
diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c
index 196e27f91c..e20f4b503a 100644
--- a/drivers/net/zxdh/zxdh_msg.c
+++ b/drivers/net/zxdh/zxdh_msg.c
@@ -2450,9 +2450,58 @@ pf_recv_bar_msg(void *pay_load, uint16_t len, void *reps_buffer,
 	return ret;
 }
 
+static int vf_recv_link_state_msg(struct rte_eth_dev *dev, void *payload,
+		void *reply_body __rte_unused, uint16_t *reps_len)
+{
+	struct zxdh_hw *hw = dev->data->dev_private;
+	void *link_autoneg_addr = ZXDH_ADDR_OF(zxdh_link_state_msg, payload, autoneg_enable);
+
+	hw->autoneg = *(uint8_t *)link_autoneg_addr;
+	dev->data->dev_link.link_autoneg = hw->autoneg;
+	*reps_len = ZXDH_ST_SZ_BYTES(zxdh_link_state_msg);
+
+	return 0;
+}
+
+static int
+vf_recv_bar_msg(void *payload, uint16_t len, void *reps_buffer,
+	uint16_t *reps_len, void *eth_dev)
+{
+	struct zxdh_msg_info *msg_payload = (struct zxdh_msg_info *)payload;
+	uint16_t pcieid = msg_payload->msg_to_vf.pcieid;
+	uint16_t opcode = msg_payload->msg_to_vf.opcode;
+	struct rte_eth_dev *dev = (struct rte_eth_dev *)eth_dev;
+	struct zxdh_ifc_msg_reply_body_bits *reply_body;
+	reply_body = (struct zxdh_ifc_msg_reply_body_bits *)
+		ZXDH_ADDR_OF(msg_reply_body, reps_buffer, flag);
+	int32_t ret = 0;
+
+	if (dev == NULL && sizeof(msg_payload) <= len) {
+		PMD_DRV_LOG(ERR, "param invalid, dev is NULL or msg_payload too long");
+		ret = -2;
+		return ret;
+	}
+
+	switch (opcode) {
+	case ZXDH_SET_VF_LINK_STATE:
+		PMD_DRV_LOG(DEBUG, "PF(pcieid:%d ) set VF's link state", pcieid);
+		vf_recv_link_state_msg(dev, &msg_payload->data, reps_buffer, reps_len);
+		reply_body->flag[0] = ZXDH_REPS_SUCC;
+		break;
+	default:
+		ZXDH_SET(msg_reply_body, reps_buffer, flag, ZXDH_REPS_INVALID);
+		PMD_DRV_LOG(ERR, "[VF GET MSG FROM PF]--unknown msg opcode:%d", opcode);
+		ret = -1;
+		break;
+	}
+	return ret;
+}
+
 void
 zxdh_msg_cb_reg(struct zxdh_hw *hw)
 {
 	if (hw->is_pf)
 		zxdh_bar_chan_msg_recv_register(ZXDH_MODULE_BAR_MSG_TO_PF, pf_recv_bar_msg);
+	else
+		zxdh_bar_chan_msg_recv_register(ZXDH_MODULE_BAR_MSG_TO_VF, vf_recv_bar_msg);
 }
diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h
index 61a3da878e..0fc9bff75d 100644
--- a/drivers/net/zxdh/zxdh_msg.h
+++ b/drivers/net/zxdh/zxdh_msg.h
@@ -205,6 +205,8 @@ enum zxdh_module_id {
 enum zxdh_agent_msg_type {
 	ZXDH_MAC_STATS_GET = 10,
 	ZXDH_MAC_STATS_RESET,
+	ZXDH_MAC_PHYPORT_INIT,
+	ZXDH_MAC_SPEED_SET,
 	ZXDH_MAC_LINK_GET = 14,
 	ZXDH_MAC_MODULE_EEPROM_READ = 20,
 	ZXDH_VQM_DEV_STATS_GET = 21,
@@ -212,6 +214,7 @@ enum zxdh_agent_msg_type {
 	ZXDH_FLASH_FIR_VERSION_GET = 23,
 	ZXDH_VQM_QUEUE_STATS_GET = 24,
 	ZXDH_VQM_QUEUE_STATS_RESET,
+	ZXDH_MAC_AUTONEG_GET = 44,
 };
 
 enum zxdh_msg_type {
@@ -233,6 +236,7 @@ enum zxdh_msg_type {
 
 	ZXDH_PORT_ATTRS_SET = 25,
 	ZXDH_PORT_PROMISC_SET = 26,
+	ZXDH_SET_VF_LINK_STATE = 28,
 
 	ZXDH_GET_NP_STATS = 31,
 	ZXDH_PLCR_CAR_PROFILE_ID_ADD = 36,
@@ -408,6 +412,17 @@ struct zxdh_ifc_agent_mac_module_eeprom_msg_bits {
 	uint8_t data[ZXDH_MODULE_EEPROM_DATA_LEN * 8];
 };
 
+struct zxdh_ifc_zxdh_link_state_msg_bits {
+	uint8_t is_link_force_set[0x8];
+	uint8_t link_forced[0x8];
+	uint8_t link_up[0x8];
+	uint8_t speed[0x20];
+	uint8_t autoneg_enable[0x20];
+	uint8_t supported_speed_modes[0x20];
+	uint8_t advertising_speed_modes[0x20];
+	uint8_t duplex[0x8];
+};
+
 struct zxdh_flash_msg {
 	uint8_t firmware_version[ZXDH_FWVERS_LEN];
 };
@@ -454,6 +469,7 @@ struct zxdh_ifc_msg_reply_body_bits {
 		struct zxdh_ifc_mtr_profile_info_bits  mtr_profile_info;
 		struct zxdh_ifc_mtr_stats_bits hw_mtr_stats;
 		struct zxdh_flow_op_rsp  flow_rsp;
+		struct zxdh_ifc_zxdh_link_state_msg_bits link_state_msg;
 	};
 };
 
@@ -482,6 +498,11 @@ struct __rte_packed_begin zxdh_msg_head {
 	uint16_t pcieid;
 } __rte_packed_end;
 
+struct __rte_packed_begin zxdh_msg_head_to_vf {
+	uint8_t opcode;
+	uint16_t pcieid;
+} __rte_packed_end;
+
 struct zxdh_port_attr_set_msg {
 	uint32_t mode;
 	uint32_t value;
@@ -521,7 +542,7 @@ struct zxdh_agent_msg_head {
 	uint8_t msg_type;
 	uint8_t panel_id;
 	uint8_t phyport;
-	uint8_t rsv;
+	uint8_t init;
 	uint16_t vf_id;
 	uint16_t pcie_id;
 };
@@ -570,6 +591,7 @@ struct zxdh_msg_info {
 		uint8_t head_len[ZXDH_MSG_HEAD_LEN];
 		struct zxdh_msg_head msg_head;
 		struct zxdh_agent_msg_head agent_msg_head;
+		struct zxdh_msg_head_to_vf msg_to_vf;
 	};
 	union {
 		uint8_t datainfo[ZXDH_MSG_REQ_BODY_MAX_LEN];
-- 
2.27.0

[-- Attachment #1.1.2: Type: text/html , Size: 27490 bytes --]

  parent reply	other threads:[~2026-01-31  6:46 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-20  6:15 [PATCH v1 0/5] net/zxdh: add support some new features Junlong Wang
2025-12-20  6:15 ` [PATCH v1 1/5] net/zxdh: add support for modifying queue depth Junlong Wang
2025-12-31 19:15   ` Stephen Hemminger
2025-12-20  6:15 ` [PATCH v1 2/5] net/zxdh: optimize alloc queue resources Junlong Wang
2025-12-20  6:15 ` [PATCH v1 3/5] net/zxdh: add support set link speed get autoneg stats Junlong Wang
2025-12-21 16:57   ` Stephen Hemminger
2025-12-31 19:23   ` Stephen Hemminger
2025-12-31 19:24   ` Stephen Hemminger
2025-12-31 19:27   ` Stephen Hemminger
2025-12-20  6:15 ` [PATCH v1 4/5] net/zxdh: add support primary/secondary process Junlong Wang
2025-12-21 17:00   ` Stephen Hemminger
2025-12-23 10:55   ` Junlong Wang
2025-12-23 17:54   ` Stephen Hemminger
2025-12-20  6:15 ` [PATCH v1 5/5] net/zxdh: add support GENEVE TSO and Rx outer UDP chksum Junlong Wang
2026-01-05  7:16 ` [PATCH v2 0/5] net/zxdh: add support some new features Junlong Wang
2026-01-05  7:16   ` [PATCH v2 1/5] net/zxdh: add support for modifying queue depth Junlong Wang
2026-01-05  7:16   ` [PATCH v2 2/5] net/zxdh: optimize alloc queue resources Junlong Wang
2026-01-05  7:16   ` [PATCH v2 3/5] net/zxdh: add support set link speed get autoneg stats Junlong Wang
2026-01-05  7:16   ` [PATCH v2 4/5] net/zxdh: add support primary/secondary process Junlong Wang
2026-01-05  7:16   ` [PATCH v2 5/5] net/zxdh: add support GENEVE TSO and Rx outer chksum Junlong Wang
2026-01-12  0:32   ` [PATCH v2 0/5] net/zxdh: add support some new features Stephen Hemminger
2026-01-31  6:22   ` [PATCH v3 " Junlong Wang
2026-01-31  6:22     ` [PATCH v3 1/5] net/zxdh: add support for modifying queue depth Junlong Wang
2026-01-31  6:22     ` [PATCH v3 2/5] net/zxdh: optimize alloc queue resources Junlong Wang
2026-01-31  6:22     ` Junlong Wang [this message]
2026-01-31  6:22     ` [PATCH v3 4/5] net/zxdh: add support for primary/secondary process Junlong Wang
2026-01-31  6:22     ` [PATCH v3 5/5] net/zxdh: add support for GENEVE TSO and Rx outer checksum Junlong Wang
2026-03-18  2:21       ` [v3, " Junlong Wang
2026-03-18 10:16         ` Thomas Monjalon
2026-03-18 10:54           ` Thomas Monjalon
2026-03-19  5:53       ` Junlong Wang
2026-03-19  9:27         ` Thomas Monjalon
2026-01-31 18:11     ` [PATCH v3 0/5] net/zxdh: add support some new features Stephen Hemminger
2026-02-02 19:45     ` Stephen Hemminger
2026-02-03  1:43     ` [v3,0/5] " Junlong Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260131062208.2445121-4-wang.junlong1@zte.com.cn \
    --to=wang.junlong1@zte.com.cn \
    --cc=dev@dpdk.org \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.