DPDK patches and discussions
 help / color / mirror / Atom feed
From: Wenzhuo Lu <wenzhuo.lu@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH 08/17] ixgbe/base: add KR mode support
Date: Fri, 20 Nov 2015 15:17:49 +0800	[thread overview]
Message-ID: <1448003879-29960-9-git-send-email-wenzhuo.lu@intel.com> (raw)
In-Reply-To: <1448003879-29960-1-git-send-email-wenzhuo.lu@intel.com>

KR auto-neg mode is what we will be using going forward. The SW
interface for this mode is different than what was used for iXFI.

While debugging, it was determined that the ucode diagnostic was
no longer needed. This code has been removed to simplify the init
flow.

A subtle semaphore error in the CS4227 reset flow was fixed.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 drivers/net/ixgbe/base/ixgbe_phy.h  |  11 +-
 drivers/net/ixgbe/base/ixgbe_x550.c | 295 +++++++++++++++---------------------
 2 files changed, 133 insertions(+), 173 deletions(-)

diff --git a/drivers/net/ixgbe/base/ixgbe_phy.h b/drivers/net/ixgbe/base/ixgbe_phy.h
index 1f07c1e..afed7bd 100644
--- a/drivers/net/ixgbe/base/ixgbe_phy.h
+++ b/drivers/net/ixgbe/base/ixgbe_phy.h
@@ -91,18 +91,23 @@ POSSIBILITY OF SUCH DAMAGE.
 #define IXGBE_CS4227_GLOBAL_ID_LSB	0
 #define IXGBE_CS4227_SCRATCH		2
 #define IXGBE_CS4227_GLOBAL_ID_VALUE	0x03E5
-#define IXGBE_CS4227_SCRATCH_VALUE	0x5aa5
-#define IXGBE_CS4227_RETRIES		5
+#define IXGBE_CS4227_RESET_PENDING	0x1357
+#define IXGBE_CS4227_RESET_COMPLETE	0x5AA5
+#define IXGBE_CS4227_RETRIES		15
+#define IXGBE_CS4227_EFUSE_STATUS	0x0181
 #define IXGBE_CS4227_LINE_SPARE22_MSB	0x12AD	/* Reg to program speed */
 #define IXGBE_CS4227_LINE_SPARE24_LSB	0x12B0	/* Reg to program EDC */
 #define IXGBE_CS4227_HOST_SPARE22_MSB	0x1AAD	/* Reg to program speed */
 #define IXGBE_CS4227_HOST_SPARE24_LSB	0x1AB0	/* Reg to program EDC */
+#define IXGBE_CS4227_EEPROM_STATUS	0x5001
+#define IXGBE_CS4227_EEPROM_LOAD_OK	0x0001
 #define IXGBE_CS4227_SPEED_1G		0x8000
 #define IXGBE_CS4227_SPEED_10G		0
 #define IXGBE_CS4227_EDC_MODE_CX1	0x0002
 #define IXGBE_CS4227_EDC_MODE_SR	0x0004
+#define IXGBE_CS4227_EDC_MODE_DIAG	0x0008
 #define IXGBE_CS4227_RESET_HOLD		500	/* microseconds */
-#define IXGBE_CS4227_RESET_DELAY	500	/* milliseconds */
+#define IXGBE_CS4227_RESET_DELAY	450	/* milliseconds */
 #define IXGBE_CS4227_CHECK_DELAY	30	/* milliseconds */
 #define IXGBE_PE			0xE0	/* Port expander address */
 #define IXGBE_PE_OUTPUT			1	/* Output register offset */
diff --git a/drivers/net/ixgbe/base/ixgbe_x550.c b/drivers/net/ixgbe/base/ixgbe_x550.c
index f6139df..d6630f9 100644
--- a/drivers/net/ixgbe/base/ixgbe_x550.c
+++ b/drivers/net/ixgbe/base/ixgbe_x550.c
@@ -114,132 +114,6 @@ STATIC s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
 }
 
 /**
- * ixgbe_get_cs4227_status - Return CS4227 status
- * @hw: pointer to hardware structure
- *
- * Performs a diagnostic on the CS4227 chip. Returns an error if it is
- * not operating correctly.
- * This function assumes that the caller has acquired the proper semaphore.
- **/
-STATIC s32 ixgbe_get_cs4227_status(struct ixgbe_hw *hw)
-{
-	s32 status;
-	u16 value = 0;
-	u16 reg_slice, reg_val;
-	u8 retry;
-
-	/* Check register reads. */
-	for (retry = 0; retry < IXGBE_CS4227_RETRIES; ++retry) {
-		status = ixgbe_read_cs4227(hw, IXGBE_CS4227_GLOBAL_ID_LSB,
-					   &value);
-		if (status != IXGBE_SUCCESS)
-			return status;
-		if (value == IXGBE_CS4227_GLOBAL_ID_VALUE)
-			break;
-		msec_delay(IXGBE_CS4227_CHECK_DELAY);
-	}
-	if (value != IXGBE_CS4227_GLOBAL_ID_VALUE)
-		return IXGBE_ERR_PHY;
-
-	status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
-	if (status != IXGBE_SUCCESS)
-		return status;
-
-	/* If this is the first time after power-on, check the ucode.
-	 * Otherwise, this will disrupt link on all ports. Because we
-	 * can only do this the first time, we must check all ports,
-	 * not just our own.
-	 * While we are at it, set the LINE side to 10G SR, which is
-	 * what it needs to be regardless of the actual link.
-	 */
-	if (value != IXGBE_CS4227_SCRATCH_VALUE) {
-		reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB;
-		reg_val = IXGBE_CS4227_SPEED_10G;
-		status = ixgbe_write_cs4227(hw, reg_slice, reg_val);
-		if (status != IXGBE_SUCCESS)
-			return status;
-
-		reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB;
-		reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
-		status = ixgbe_write_cs4227(hw, reg_slice, reg_val);
-		if (status != IXGBE_SUCCESS)
-			return status;
-
-		reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB;
-		reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
-		status = ixgbe_write_cs4227(hw, reg_slice, reg_val);
-		if (status != IXGBE_SUCCESS)
-			return status;
-
-		reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB + (1 << 12);
-		reg_val = IXGBE_CS4227_SPEED_10G;
-		status = ixgbe_write_cs4227(hw, reg_slice, reg_val);
-		if (status != IXGBE_SUCCESS)
-			return status;
-
-		reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (1 << 12);
-		reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
-		status = ixgbe_write_cs4227(hw, reg_slice, reg_val);
-		if (status != IXGBE_SUCCESS)
-			return status;
-
-		reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB + (1 << 12);
-		reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
-		status = ixgbe_write_cs4227(hw, reg_slice, reg_val);
-		if (status != IXGBE_SUCCESS)
-			return status;
-
-		msec_delay(10);
-	}
-
-	/* Verify that the ucode is operational on all ports. */
-	reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB;
-	reg_val = 0xFFFF;
-	status = ixgbe_read_cs4227(hw, reg_slice, &reg_val);
-	if (status != IXGBE_SUCCESS)
-		return status;
-	if (reg_val != 0)
-		return IXGBE_ERR_PHY;
-
-	reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB;
-	reg_val = 0xFFFF;
-	status = ixgbe_read_cs4227(hw, reg_slice, &reg_val);
-	if (status != IXGBE_SUCCESS)
-		return status;
-	if (reg_val != 0)
-		return IXGBE_ERR_PHY;
-
-	reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (1 << 12);
-	reg_val = 0xFFFF;
-	status = ixgbe_read_cs4227(hw, reg_slice, &reg_val);
-	if (status != IXGBE_SUCCESS)
-		return status;
-	if (reg_val != 0)
-		return IXGBE_ERR_PHY;
-
-	reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB + (1 << 12);
-	reg_val = 0xFFFF;
-	status = ixgbe_read_cs4227(hw, reg_slice, &reg_val);
-	if (status != IXGBE_SUCCESS)
-		return status;
-	if (reg_val != 0)
-		return IXGBE_ERR_PHY;
-
-	/* Set scratch indicating that the diagnostic was successful. */
-	status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
-				    IXGBE_CS4227_SCRATCH_VALUE);
-	if (status != IXGBE_SUCCESS)
-		return status;
-	status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
-	if (status != IXGBE_SUCCESS)
-		return status;
-	if (value != IXGBE_CS4227_SCRATCH_VALUE)
-		return IXGBE_ERR_PHY;
-
-	return IXGBE_SUCCESS;
-}
-
-/**
  * ixgbe_read_pe - Read register from port expander
  * @hw: pointer to hardware structure
  * @reg: register number to read
@@ -281,13 +155,17 @@ STATIC s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
  * ixgbe_reset_cs4227 - Reset CS4227 using port expander
  * @hw: pointer to hardware structure
  *
+ * This function assumes that the caller has acquired the proper semaphore.
  * Returns error code
  **/
 STATIC s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
 {
 	s32 status;
+	u32 retry;
+	u16 value;
 	u8 reg;
 
+	/* Trigger hard reset. */
 	status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
 	if (status != IXGBE_SUCCESS)
 		return status;
@@ -322,7 +200,29 @@ STATIC s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
 	if (status != IXGBE_SUCCESS)
 		return status;
 
+	/* Wait for the reset to complete. */
 	msec_delay(IXGBE_CS4227_RESET_DELAY);
+	for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
+		status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
+					   &value);
+		if (status == IXGBE_SUCCESS &&
+		    value == IXGBE_CS4227_EEPROM_LOAD_OK)
+			break;
+		msec_delay(IXGBE_CS4227_CHECK_DELAY);
+	}
+	if (retry == IXGBE_CS4227_RETRIES) {
+		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
+			"CS4227 reset did not complete.");
+		return IXGBE_ERR_PHY;
+	}
+
+	status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
+	if (status != IXGBE_SUCCESS ||
+	    !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
+		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
+			"CS4227 EEPROM did not load successfully.");
+		return IXGBE_ERR_PHY;
+	}
 
 	return IXGBE_SUCCESS;
 }
@@ -333,29 +233,75 @@ STATIC s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
  **/
 STATIC void ixgbe_check_cs4227(struct ixgbe_hw *hw)
 {
+	s32 status = IXGBE_SUCCESS;
 	u32 swfw_mask = hw->phy.phy_semaphore_mask;
-	s32 status;
+	u16 value = 0;
 	u8 retry;
 
 	for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
 		status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
 		if (status != IXGBE_SUCCESS) {
 			ERROR_REPORT2(IXGBE_ERROR_CAUTION,
-				      "semaphore failed with %d\n", status);
-			return;
+				"semaphore failed with %d", status);
+			msec_delay(IXGBE_CS4227_CHECK_DELAY);
+			continue;
 		}
-		status = ixgbe_get_cs4227_status(hw);
-		if (status == IXGBE_SUCCESS) {
-			hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-			msec_delay(hw->eeprom.semaphore_delay);
+
+		/* Get status of reset flow. */
+		status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
+
+		if (status == IXGBE_SUCCESS &&
+		    value == IXGBE_CS4227_RESET_COMPLETE)
+			goto out;
+
+		if (status != IXGBE_SUCCESS ||
+		    value != IXGBE_CS4227_RESET_PENDING)
+			break;
+
+		/* Reset is pending. Wait and check again. */
+		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+		msec_delay(IXGBE_CS4227_CHECK_DELAY);
+	}
+
+	/* If still pending, assume other instance failed. */
+	if (retry == IXGBE_CS4227_RETRIES) {
+		status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
+		if (status != IXGBE_SUCCESS) {
+			ERROR_REPORT2(IXGBE_ERROR_CAUTION,
+				      "semaphore failed with %d", status);
 			return;
 		}
-		ixgbe_reset_cs4227(hw);
-		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-		msec_delay(hw->eeprom.semaphore_delay);
 	}
-	ERROR_REPORT2(IXGBE_ERROR_CAUTION,
-		      "Unable to initialize CS4227, err=%d\n", status);
+
+	/* Reset the CS4227. */
+	status = ixgbe_reset_cs4227(hw);
+	if (status != IXGBE_SUCCESS) {
+		ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
+			"CS4227 reset failed: %d", status);
+		goto out;
+	}
+
+	/* Reset takes so long, temporarily release semaphore in case the
+	 * other driver instance is waiting for the reset indication.
+	 */
+	ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
+			   IXGBE_CS4227_RESET_PENDING);
+	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+	msec_delay(10);
+	status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
+	if (status != IXGBE_SUCCESS) {
+		ERROR_REPORT2(IXGBE_ERROR_CAUTION,
+			"semaphore failed with %d", status);
+		return;
+	}
+
+	/* Record completion for next time. */
+	status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
+		IXGBE_CS4227_RESET_COMPLETE);
+
+out:
+	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+	msec_delay(hw->eeprom.semaphore_delay);
 }
 
 /**
@@ -1506,14 +1452,6 @@ s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
 		 * to determine internal PHY mode.
 		 */
 		phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
-
-		/* If internal PHY mode is KR, then initialize KR link */
-		if (phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) {
-			speed = IXGBE_LINK_SPEED_10GB_FULL |
-				IXGBE_LINK_SPEED_1GB_FULL;
-			ret_val = ixgbe_setup_kr_speed_x550em(hw, speed);
-		}
-
 		phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em;
 	}
 
@@ -1772,36 +1710,53 @@ s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
 	if (ret_val != IXGBE_SUCCESS)
 		return ret_val;
 
-	/* Configure CS4227 LINE side to 10G SR. */
-	reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB + (hw->bus.lan_id << 12);
-	reg_val = IXGBE_CS4227_SPEED_10G;
-	ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
-		reg_val);
+	if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
+		/* Configure CS4227 LINE side to 10G SR. */
+		reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB +
+			    (hw->bus.lan_id << 12);
+		reg_val = IXGBE_CS4227_SPEED_10G;
+		ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
+						   reg_val);
 
-	reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12);
-	reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
-	ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
-		reg_val);
+		reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
+			    (hw->bus.lan_id << 12);
+		reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
+		ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
+						   reg_val);
 
-	/* Configure CS4227 for HOST connection rate then type. */
-	reg_slice = IXGBE_CS4227_HOST_SPARE22_MSB + (hw->bus.lan_id << 12);
-	reg_val = (speed & IXGBE_LINK_SPEED_10GB_FULL) ?
+		/* Configure CS4227 for HOST connection rate then type. */
+		reg_slice = IXGBE_CS4227_HOST_SPARE22_MSB +
+			    (hw->bus.lan_id << 12);
+		reg_val = (speed & IXGBE_LINK_SPEED_10GB_FULL) ?
 		IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G;
-	ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
-					   reg_val);
+		ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
+						   reg_val);
 
-	reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB + (hw->bus.lan_id << 12);
-	if (setup_linear)
-		reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
-	else
-		reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
-	ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
-					   reg_val);
+		reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB +
+			    (hw->bus.lan_id << 12);
+		if (setup_linear)
+			reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
+		else
+			reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
+		ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
+						   reg_val);
 
-	/* If internal link mode is XFI, then setup XFI internal link. */
-	if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE))
+		/* Setup XFI internal link. */
 		ret_val = ixgbe_setup_ixfi_x550em(hw, &speed);
-
+	} else {
+		/* Configure internal PHY for KR/KX. */
+		ixgbe_setup_kr_speed_x550em(hw, speed);
+
+		/* Configure CS4227 LINE side to proper mode. */
+		reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB +
+			    (hw->bus.lan_id << 12);
+		if (setup_linear)
+			reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
+		else
+			reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
+		ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
+						   reg_val);
+	}
 	return ret_val;
 }
 
-- 
1.9.3

  parent reply	other threads:[~2015-11-20  7:18 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-20  7:17 [dpdk-dev] [PATCH 00/17] Update ixgbe base code Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 01/17] ixgbe/base: update README Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 02/17] ixgbe/base: avoid needless PHY access on copper phys Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 03/17] ixgbe/base: do not wait for signature rule addition Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 04/17] ixgbe/base: use mvals values instead of defines Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 05/17] ixgbe/base: add Single-port Sage Pond device ID Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 06/17] ixgbe/base: remove driver config of KX4 PHY Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 07/17] ixgbe/base: add Flow Control Ethertype to ETQF filter list Wenzhuo Lu
2015-11-20  7:17 ` Wenzhuo Lu [this message]
2015-11-20  7:17 ` [dpdk-dev] [PATCH 09/17] ixgbe/base: add flow director drop queue Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 10/17] ixgbe/base: check mac type for iosf and phy Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 11/17] ixgbe/base: configure x550 MDIO clock speed Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 12/17] ixgbe/base: fill at least min credits to a TC credit refills Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 13/17] ixgbe/base: support new thermal alarm Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 14/17] ixgbe/base: add new iXFI configuration helper function Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 15/17] ixgbe/base: prevent KR PHY reset in init Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 16/17] ixgbe/base: new defines for FW Wenzhuo Lu
2015-11-20  7:17 ` [dpdk-dev] [PATCH 17/17] ixgbe: add new device X550T1 Wenzhuo Lu
2015-11-20 16:41   ` Stephen Hemminger
2016-01-14  8:48 ` [dpdk-dev] [PATCH 00/17] Update ixgbe base code Thomas Monjalon

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=1448003879-29960-9-git-send-email-wenzhuo.lu@intel.com \
    --to=wenzhuo.lu@intel.com \
    --cc=dev@dpdk.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 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).