DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report
@ 2021-04-13 13:47 Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 1/9] net/hns3: fix supported speed of copper ports Min Hu (Connor)
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-13 13:47 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

The patchset has the following functions:
1.report speed capability supported by the current hardware.
2.support link speed autoneg and force link speed for PF.
3.support flow control autoneg for copper port.

Huisong Li (9):
  net/hns3: fix supported speed of copper ports
  net/hns3: add 1000M speed bit for copper PHYs
  net/hns3: fix flow control mode
  net/hns3: fix firmware compatibility configuration
  net/hns3: obtain the supported speed for fiber port
  net/hns3: report the speed capability for PF
  net/hns3: support link speed autoneg for PF
  net/hns3: support flow control autoneg for copper port
  net/hns3: add the configuration of fixed speed

 drivers/net/hns3/hns3_cmd.c    | 116 +++++++
 drivers/net/hns3/hns3_cmd.h    |  45 ++-
 drivers/net/hns3/hns3_dcb.c    |  23 +-
 drivers/net/hns3/hns3_ethdev.c | 755 +++++++++++++++++++++++++++++++++++------
 drivers/net/hns3/hns3_ethdev.h |  37 +-
 5 files changed, 832 insertions(+), 144 deletions(-)

-- 
2.7.4


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

* [dpdk-dev] [PATCH 1/9] net/hns3: fix supported speed of copper ports
  2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
@ 2021-04-13 13:47 ` Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 2/9] net/hns3: add 1000M speed bit for copper PHYs Min Hu (Connor)
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-13 13:47 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Huisong Li <lihuisong@huawei.com>

The "supported" obtaining from firmware on copper ports includes the
speed capability, auto-negotiation capability, and flow control
capability. Therefore, this patch changes "supported_capa" to
"supported_speed" and parses the speed capability supported by the
driver from the "supported".

Fixes: 2e4859f3b362 ("net/hns3: support PF device with copper PHYs")

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 11 +++++++----
 drivers/net/hns3/hns3_ethdev.h |  2 +-
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 846e5a2..d7766e1 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -4612,7 +4612,10 @@ hns3_update_fiber_link_info(struct hns3_hw *hw)
 static void
 hns3_parse_copper_phy_params(struct hns3_cmd_desc *desc, struct hns3_mac *mac)
 {
+#define HNS3_PHY_SUPPORTED_SPEED_MASK   0x2f
+
 	struct hns3_phy_params_bd0_cmd *req;
+	uint32_t supported;
 
 	req = (struct hns3_phy_params_bd0_cmd *)desc[0].data;
 	mac->link_speed = rte_le_to_cpu_32(req->speed);
@@ -4620,11 +4623,11 @@ hns3_parse_copper_phy_params(struct hns3_cmd_desc *desc, struct hns3_mac *mac)
 					   HNS3_PHY_DUPLEX_CFG_B);
 	mac->link_autoneg = hns3_get_bit(req->autoneg,
 					   HNS3_PHY_AUTONEG_CFG_B);
-	mac->supported_capa = rte_le_to_cpu_32(req->supported);
 	mac->advertising = rte_le_to_cpu_32(req->advertising);
 	mac->lp_advertising = rte_le_to_cpu_32(req->lp_advertising);
-	mac->support_autoneg = !!(mac->supported_capa &
-				HNS3_PHY_LINK_MODE_AUTONEG_BIT);
+	supported = rte_le_to_cpu_32(req->supported);
+	mac->supported_speed = supported & HNS3_PHY_SUPPORTED_SPEED_MASK;
+	mac->support_autoneg = !!(supported & HNS3_PHY_LINK_MODE_AUTONEG_BIT);
 }
 
 static int
@@ -4673,7 +4676,7 @@ hns3_update_copper_link_info(struct hns3_hw *hw)
 	mac->link_speed = mac_info.link_speed;
 	mac->link_duplex = mac_info.link_duplex;
 	mac->link_autoneg = mac_info.link_autoneg;
-	mac->supported_capa = mac_info.supported_capa;
+	mac->supported_speed = mac_info.supported_speed;
 	mac->advertising = mac_info.advertising;
 	mac->lp_advertising = mac_info.lp_advertising;
 	mac->support_autoneg = mac_info.support_autoneg;
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 72d718c..cbeadc0 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -183,7 +183,7 @@ struct hns3_mac {
 	uint8_t link_autoneg : 1; /* ETH_LINK_[AUTONEG/FIXED] */
 	uint8_t link_status  : 1; /* ETH_LINK_[DOWN/UP] */
 	uint32_t link_speed;      /* ETH_SPEED_NUM_ */
-	uint32_t supported_capa;  /* supported capability for current media */
+	uint32_t supported_speed;  /* supported speed for current media type */
 	uint32_t advertising;     /* advertised capability in the local part */
 	/* advertised capability in the link partner */
 	uint32_t lp_advertising;
-- 
2.7.4


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

* [dpdk-dev] [PATCH 2/9] net/hns3: add 1000M speed bit for copper PHYs
  2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 1/9] net/hns3: fix supported speed of copper ports Min Hu (Connor)
@ 2021-04-13 13:47 ` Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 3/9] net/hns3: fix flow control mode Min Hu (Connor)
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-13 13:47 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Huisong Li <lihuisong@huawei.com>

The bit(5) of supported, advertising and lp_advertising for copper
PHYs obtained from the firmware indicates 1000M full-duplex. This
speed capability bit is missing in the current codes.

Fixes: 2e4859f3b362 ("net/hns3: support PF device with copper PHYs")

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_cmd.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
index 9958fde..a39f159 100644
--- a/drivers/net/hns3/hns3_cmd.h
+++ b/drivers/net/hns3/hns3_cmd.h
@@ -686,6 +686,7 @@ struct hns3_firmware_compat_cmd {
 #define HNS3_PHY_LINK_SPEED_10M_BIT		BIT(1)
 #define HNS3_PHY_LINK_SPEED_100M_HD_BIT		BIT(2)
 #define HNS3_PHY_LINK_SPEED_100M_BIT		BIT(3)
+#define HNS3_PHY_LINK_SPEED_1000M_BIT		BIT(5)
 #define HNS3_PHY_LINK_MODE_AUTONEG_BIT		BIT(6)
 #define HNS3_PHY_LINK_MODE_PAUSE_BIT		BIT(13)
 #define HNS3_PHY_LINK_MODE_ASYM_PAUSE_BIT	BIT(14)
-- 
2.7.4


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

* [dpdk-dev] [PATCH 3/9] net/hns3: fix flow control mode
  2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 1/9] net/hns3: fix supported speed of copper ports Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 2/9] net/hns3: add 1000M speed bit for copper PHYs Min Hu (Connor)
@ 2021-04-13 13:47 ` Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 4/9] net/hns3: fix firmware compatibility configuration Min Hu (Connor)
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-13 13:47 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Huisong Li <lihuisong@huawei.com>

Currently, hns3 driver doesn't support to flow control auto-negotiation.
The FC mode requested by user is the same as the current FC mode. It is
not necessary to maintain the current FC mode. We only report the current
FC mode based on actual flow control mode in hns3_flow_ctrl_get().

This patch removes this redundant field. In addition, "requested_mode" in
hns3_hw struct indicates the FC mode requested by user, and the name is
unreasonable. It needs to be modified to "requested_fc_mode".

Fixes: 62e3ccc2b94c ("net/hns3: support flow control")
Cc: stable@dpdk.org

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_dcb.c    | 23 ++++++++---------------
 drivers/net/hns3/hns3_ethdev.c | 28 ++++++++++------------------
 drivers/net/hns3/hns3_ethdev.h |  3 +--
 3 files changed, 19 insertions(+), 35 deletions(-)

diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c
index 096afe8..30e59e8 100644
--- a/drivers/net/hns3/hns3_dcb.c
+++ b/drivers/net/hns3/hns3_dcb.c
@@ -1238,7 +1238,7 @@ hns3_qs_bp_cfg(struct hns3_hw *hw, uint8_t tc, uint8_t grp_id, uint32_t bit_map)
 static void
 hns3_get_rx_tx_en_status(struct hns3_hw *hw, bool *tx_en, bool *rx_en)
 {
-	switch (hw->current_mode) {
+	switch (hw->requested_fc_mode) {
 	case HNS3_FC_NONE:
 		*tx_en = false;
 		*rx_en = false;
@@ -1415,7 +1415,7 @@ hns3_dcb_cfg_validate(struct hns3_adapter *hns, uint8_t *tc, bool *changed)
 	 * We ensure that dcb information can be reconfigured
 	 * after the hns3_priority_flow_ctrl_set function called.
 	 */
-	if (hw->current_mode != HNS3_FC_FULL)
+	if (hw->requested_fc_mode != HNS3_FC_FULL)
 		*changed = true;
 	pfc_en = RTE_LEN2MASK((uint8_t)dcb_rx_conf->nb_tcs, uint8_t);
 	if (hw->dcb_info.pfc_en != pfc_en)
@@ -1529,7 +1529,7 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns)
 	struct hns3_pf *pf = &hns->pf;
 	struct hns3_hw *hw = &hns->hw;
 	enum hns3_fc_status fc_status = hw->current_fc_status;
-	enum hns3_fc_mode current_mode = hw->current_mode;
+	enum hns3_fc_mode requested_fc_mode = hw->requested_fc_mode;
 	uint8_t hw_pfc_map = hw->dcb_info.hw_pfc_map;
 	int ret, status;
 
@@ -1559,7 +1559,7 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns)
 			return ret;
 
 		hw->current_fc_status = HNS3_FC_STATUS_PFC;
-		hw->current_mode = HNS3_FC_FULL;
+		hw->requested_fc_mode = HNS3_FC_FULL;
 		ret = hns3_dcb_pause_setup_hw(hw);
 		if (ret) {
 			hns3_err(hw, "setup pfc failed! ret = %d", ret);
@@ -1580,7 +1580,7 @@ hns3_dcb_hw_configure(struct hns3_adapter *hns)
 	return 0;
 
 pfc_setup_fail:
-	hw->current_mode = current_mode;
+	hw->requested_fc_mode = requested_fc_mode;
 	hw->current_fc_status = fc_status;
 	hw->dcb_info.hw_pfc_map = hw_pfc_map;
 	status = hns3_buffer_alloc(hw);
@@ -1659,8 +1659,7 @@ hns3_dcb_init(struct hns3_hw *hw)
 	 * will be changed.
 	 */
 	if (hw->adapter_state == HNS3_NIC_UNINITIALIZED) {
-		hw->requested_mode = HNS3_FC_NONE;
-		hw->current_mode = hw->requested_mode;
+		hw->requested_fc_mode = HNS3_FC_NONE;
 		pf->pause_time = HNS3_DEFAULT_PAUSE_TRANS_TIME;
 		hw->current_fc_status = HNS3_FC_STATUS_NONE;
 
@@ -1761,7 +1760,6 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf)
 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	enum hns3_fc_status fc_status = hw->current_fc_status;
-	enum hns3_fc_mode current_mode = hw->current_mode;
 	uint8_t hw_pfc_map = hw->dcb_info.hw_pfc_map;
 	uint8_t pfc_en = hw->dcb_info.pfc_en;
 	uint8_t priority = pfc_conf->priority;
@@ -1769,7 +1767,6 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf)
 	int ret, status;
 
 	pf->pause_time = pfc_conf->fc.pause_time;
-	hw->current_mode = hw->requested_mode;
 	hw->current_fc_status = HNS3_FC_STATUS_PFC;
 	hw->dcb_info.pfc_en |= BIT(priority);
 	hw->dcb_info.hw_pfc_map =
@@ -1780,7 +1777,7 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf)
 
 	/*
 	 * The flow control mode of all UPs will be changed based on
-	 * current_mode coming from user.
+	 * requested_fc_mode coming from user.
 	 */
 	ret = hns3_dcb_pause_setup_hw(hw);
 	if (ret) {
@@ -1791,7 +1788,6 @@ hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf)
 	return 0;
 
 pfc_setup_fail:
-	hw->current_mode = current_mode;
 	hw->current_fc_status = fc_status;
 	pf->pause_time = pause_time;
 	hw->dcb_info.pfc_en = pfc_en;
@@ -1815,18 +1811,16 @@ hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	enum hns3_fc_status fc_status = hw->current_fc_status;
-	enum hns3_fc_mode current_mode = hw->current_mode;
 	uint16_t pause_time = pf->pause_time;
 	int ret;
 
 	pf->pause_time = fc_conf->pause_time;
-	hw->current_mode = hw->requested_mode;
 
 	/*
 	 * In fact, current_fc_status is HNS3_FC_STATUS_NONE when mode
 	 * of flow control is configured to be HNS3_FC_NONE.
 	 */
-	if (hw->current_mode == HNS3_FC_NONE)
+	if (hw->requested_fc_mode == HNS3_FC_NONE)
 		hw->current_fc_status = HNS3_FC_STATUS_NONE;
 	else
 		hw->current_fc_status = HNS3_FC_STATUS_MAC_PAUSE;
@@ -1840,7 +1834,6 @@ hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 	return 0;
 
 setup_fc_fail:
-	hw->current_mode = current_mode;
 	hw->current_fc_status = fc_status;
 	pf->pause_time = pause_time;
 
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index d7766e1..62a23b8 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -5496,8 +5496,11 @@ hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 
 	fc_conf->pause_time = pf->pause_time;
 
-	/* return fc current mode */
-	switch (hw->current_mode) {
+	/*
+	 * If fc auto-negotiation is not supported, the configured fc mode
+	 * from user is the current fc mode.
+	 */
+	switch (hw->requested_fc_mode) {
 	case HNS3_FC_FULL:
 		fc_conf->mode = RTE_FC_FULL;
 		break;
@@ -5521,19 +5524,19 @@ hns3_get_fc_mode(struct hns3_hw *hw, enum rte_eth_fc_mode mode)
 {
 	switch (mode) {
 	case RTE_FC_NONE:
-		hw->requested_mode = HNS3_FC_NONE;
+		hw->requested_fc_mode = HNS3_FC_NONE;
 		break;
 	case RTE_FC_RX_PAUSE:
-		hw->requested_mode = HNS3_FC_RX_PAUSE;
+		hw->requested_fc_mode = HNS3_FC_RX_PAUSE;
 		break;
 	case RTE_FC_TX_PAUSE:
-		hw->requested_mode = HNS3_FC_TX_PAUSE;
+		hw->requested_fc_mode = HNS3_FC_TX_PAUSE;
 		break;
 	case RTE_FC_FULL:
-		hw->requested_mode = HNS3_FC_FULL;
+		hw->requested_fc_mode = HNS3_FC_FULL;
 		break;
 	default:
-		hw->requested_mode = HNS3_FC_NONE;
+		hw->requested_fc_mode = HNS3_FC_NONE;
 		hns3_warn(hw, "fc_mode(%u) exceeds member scope and is "
 			  "configured to RTE_FC_NONE", mode);
 		break;
@@ -5544,7 +5547,6 @@ static int
 hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 {
 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
 	int ret;
 
 	if (fc_conf->high_water || fc_conf->low_water ||
@@ -5579,9 +5581,6 @@ hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 	}
 
 	hns3_get_fc_mode(hw, fc_conf->mode);
-	if (hw->requested_mode == hw->current_mode &&
-	    pf->pause_time == fc_conf->pause_time)
-		return 0;
 
 	rte_spinlock_lock(&hw->lock);
 	ret = hns3_fc_enable(dev, fc_conf);
@@ -5595,8 +5594,6 @@ hns3_priority_flow_ctrl_set(struct rte_eth_dev *dev,
 			    struct rte_eth_pfc_conf *pfc_conf)
 {
 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	uint8_t priority;
 	int ret;
 
 	if (!hns3_dev_dcb_supported(hw)) {
@@ -5631,12 +5628,7 @@ hns3_priority_flow_ctrl_set(struct rte_eth_dev *dev,
 		return -EOPNOTSUPP;
 	}
 
-	priority = pfc_conf->priority;
 	hns3_get_fc_mode(hw, pfc_conf->fc.mode);
-	if (hw->dcb_info.pfc_en & BIT(priority) &&
-	    hw->requested_mode == hw->current_mode &&
-	    pfc_conf->fc.pause_time == pf->pause_time)
-		return 0;
 
 	rte_spinlock_lock(&hw->lock);
 	ret = hns3_dcb_pfc_enable(dev, pfc_conf);
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index cbeadc0..553caa3 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -470,8 +470,7 @@ struct hns3_hw {
 
 	uint8_t num_tc;             /* Total number of enabled TCs */
 	uint8_t hw_tc_map;
-	enum hns3_fc_mode current_mode;
-	enum hns3_fc_mode requested_mode;
+	enum hns3_fc_mode requested_fc_mode; /* FC mode requested by user */
 	struct hns3_dcb_info dcb_info;
 	enum hns3_fc_status current_fc_status; /* current flow control status */
 	struct hns3_tc_queue_info tc_queue[HNS3_MAX_TC_NUM];
-- 
2.7.4


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

* [dpdk-dev] [PATCH 4/9] net/hns3: fix firmware compatibility configuration
  2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
                   ` (2 preceding siblings ...)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 3/9] net/hns3: fix flow control mode Min Hu (Connor)
@ 2021-04-13 13:47 ` Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 5/9] net/hns3: obtain the supported speed for fiber port Min Hu (Connor)
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-13 13:47 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Huisong Li <lihuisong@huawei.com>

The firmware compatibility configuration in PF driver is used to
maintain the compatibility of some features of the driver and
firmware, and requires firmware to enable these features. Currently,
the configuration is in hns3_init_hardware(), which is a little back.
Because firmware may clear some configurations (such as, MAC related)
after receiving the command. And firmware can not be aware of some
default initializations (such as, flow control) before executing the
command to set the copper PHY when the PHY is controlled by firmware.
Therefore, it is recommended that no other hardware resources are
configured before the compatibility configuration. And it should be
moved to hns3_cmd_init(), which is responsible for the firmware
command initialization of driver.

In addition, the driver needs to perform corresponding processing
if the command fails to be sent.
1) If firmware fails to take over the copper PHY, the copper port
fails to initialize.
2) If fails to enable the report of link events, the device does
not support the LSC capability.

Fixes: 7035ee35e26b ("net/hns3: refactor PF LSC event report")
Fixes: bac6a0644121 ("net/hns3: fix link status change from firmware")
Cc: stable@dpdk.org

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_cmd.c    | 116 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/hns3/hns3_ethdev.c |  56 --------------------
 2 files changed, 116 insertions(+), 56 deletions(-)

diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c
index 1d8ef7a..e6900ec 100644
--- a/drivers/net/hns3/hns3_cmd.c
+++ b/drivers/net/hns3/hns3_cmd.c
@@ -515,9 +515,99 @@ hns3_cmd_init_queue(struct hns3_hw *hw)
 	return ret;
 }
 
+static void
+hns3_update_dev_lsc_cap(struct hns3_hw *hw, int fw_compact_cmd_result)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
+
+	if (hw->adapter_state != HNS3_NIC_UNINITIALIZED)
+		return;
+
+	if (fw_compact_cmd_result != 0) {
+		/*
+		 * If fw_compact_cmd_result is not zero, it means firmware don't
+		 * support link status change interrupt.
+		 * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver
+		 * declared RTE_PCI_DRV_INTR_LSC in drv_flags. It need to clear
+		 * the RTE_ETH_DEV_INTR_LSC capability when detect firmware
+		 * don't support link status change interrupt.
+		 */
+		dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
+	}
+}
+
+static int
+hns3_apply_fw_compat_cmd_result(struct hns3_hw *hw, int result)
+{
+	if (result != 0 && hns3_dev_copper_supported(hw)) {
+		hns3_err(hw, "firmware fails to initialize the PHY, ret = %d.",
+			 result);
+		return result;
+	}
+
+	hns3_update_dev_lsc_cap(hw, result);
+
+	return 0;
+}
+
+static int
+hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init)
+{
+	struct hns3_firmware_compat_cmd *req;
+	struct hns3_cmd_desc desc;
+	uint32_t compat = 0;
+
+#if defined(RTE_HNS3_ONLY_1630_FPGA)
+	/* If resv reg enabled phy driver of imp is not configured, driver
+	 * will use temporary phy driver.
+	 */
+	struct rte_pci_device *pci_dev;
+	struct rte_eth_dev *eth_dev;
+	uint8_t revision;
+	int ret;
+
+	eth_dev = &rte_eth_devices[hw->data->port_id];
+	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	/* Get PCI revision id */
+	ret = rte_pci_read_config(pci_dev, &revision, HNS3_PCI_REVISION_ID_LEN,
+				  HNS3_PCI_REVISION_ID);
+	if (ret != HNS3_PCI_REVISION_ID_LEN) {
+		PMD_INIT_LOG(ERR, "failed to read pci revision id, ret = %d",
+			     ret);
+		return -EIO;
+	}
+	if (revision == PCI_REVISION_ID_HIP09_A) {
+		struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw);
+		if (hns3_dev_copper_supported(hw) == 0 || pf->is_tmp_phy) {
+			PMD_INIT_LOG(ERR, "***use temp phy driver in dpdk***");
+			pf->is_tmp_phy = true;
+			hns3_set_bit(hw->capability,
+				     HNS3_DEV_SUPPORT_COPPER_B, 1);
+			return 0;
+		}
+
+		PMD_INIT_LOG(ERR, "***use phy driver in imp***");
+	}
+#endif
+
+	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FIRMWARE_COMPAT_CFG, false);
+	req = (struct hns3_firmware_compat_cmd *)desc.data;
+
+	if (is_init) {
+		hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1);
+		hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0);
+		if (hns3_dev_copper_supported(hw))
+			hns3_set_bit(compat, HNS3_FIRMWARE_PHY_DRIVER_EN_B, 1);
+	}
+	req->compat = rte_cpu_to_le_32(compat);
+
+	return hns3_cmd_send(hw, &desc, 1);
+}
+
 int
 hns3_cmd_init(struct hns3_hw *hw)
 {
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	uint32_t version;
 	int ret;
 
@@ -564,6 +654,27 @@ hns3_cmd_init(struct hns3_hw *hw)
 		     hns3_get_field(version, HNS3_FW_VERSION_BYTE0_M,
 				    HNS3_FW_VERSION_BYTE0_S));
 
+	if (hns->is_vf)
+		return 0;
+
+	/*
+	 * Requiring firmware to enable some features, firber port can still
+	 * work without it, but copper port can't work because the firmware
+	 * fails to take over the PHY.
+	 */
+	ret = hns3_firmware_compat_config(hw, true);
+	if (ret)
+		PMD_INIT_LOG(WARNING, "firmware compatible features not "
+			     "supported, ret = %d.", ret);
+
+	/*
+	 * Perform some corresponding operations based on the firmware
+	 * compatibility configuration result.
+	 */
+	ret = hns3_apply_fw_compat_cmd_result(hw, ret);
+	if (ret)
+		goto err_cmd_init;
+
 	return 0;
 
 err_cmd_init:
@@ -591,6 +702,11 @@ hns3_cmd_destroy_queue(struct hns3_hw *hw)
 void
 hns3_cmd_uninit(struct hns3_hw *hw)
 {
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+
+	if (!hns->is_vf)
+		(void)hns3_firmware_compat_config(hw, false);
+
 	__atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED);
 
 	/*
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 62a23b8..d22d31d 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -4118,28 +4118,6 @@ hns3_buffer_alloc(struct hns3_hw *hw)
 }
 
 static int
-hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init)
-{
-	struct hns3_firmware_compat_cmd *req;
-	struct hns3_cmd_desc desc;
-	uint32_t compat = 0;
-
-	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FIRMWARE_COMPAT_CFG, false);
-	req = (struct hns3_firmware_compat_cmd *)desc.data;
-
-	if (is_init) {
-		hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1);
-		hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0);
-		if (hw->mac.media_type == HNS3_MEDIA_TYPE_COPPER)
-			hns3_set_bit(compat, HNS3_FIRMWARE_PHY_DRIVER_EN_B, 1);
-	}
-
-	req->compat = rte_cpu_to_le_32(compat);
-
-	return hns3_cmd_send(hw, &desc, 1);
-}
-
-static int
 hns3_mac_init(struct hns3_hw *hw)
 {
 	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
@@ -4815,28 +4793,6 @@ hns3_service_handler(void *param)
 	rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, eth_dev);
 }
 
-static void
-hns3_update_dev_lsc_cap(struct hns3_hw *hw,
-			int fw_compact_cmd_result)
-{
-	struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
-
-	if (hw->adapter_state != HNS3_NIC_UNINITIALIZED)
-		return;
-
-	if (fw_compact_cmd_result != 0) {
-		/*
-		 * If fw_compact_cmd_result is not zero, it means firmware don't
-		 * support link status change interrupt.
-		 * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver
-		 * declared RTE_PCI_DRV_INTR_LSC in drv_flags. It need to clear
-		 * the RTE_ETH_DEV_INTR_LSC capability when detect firmware
-		 * don't support link status change interrupt.
-		 */
-		dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
-	}
-}
-
 static int
 hns3_init_hardware(struct hns3_adapter *hns)
 {
@@ -4916,16 +4872,6 @@ hns3_init_hardware(struct hns3_adapter *hns)
 		goto err_mac_init;
 	}
 
-	/*
-	 * Requiring firmware to enable some features, driver can
-	 * still work without it.
-	 */
-	ret = hns3_firmware_compat_config(hw, true);
-	if (ret)
-		PMD_INIT_LOG(WARNING, "firmware compatible features not "
-			     "supported, ret = %d.", ret);
-	hns3_update_dev_lsc_cap(hw, ret);
-
 	return 0;
 
 err_mac_init:
@@ -5073,7 +5019,6 @@ hns3_init_pf(struct rte_eth_dev *eth_dev)
 err_enable_intr:
 	hns3_fdir_filter_uninit(hns);
 err_fdir:
-	(void)hns3_firmware_compat_config(hw, false);
 	hns3_uninit_umv_space(hw);
 err_init_hw:
 	hns3_tqp_stats_uninit(hw);
@@ -5108,7 +5053,6 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev)
 	(void)hns3_config_gro(hw, false);
 	hns3_promisc_uninit(hw);
 	hns3_fdir_filter_uninit(hns);
-	(void)hns3_firmware_compat_config(hw, false);
 	hns3_uninit_umv_space(hw);
 	hns3_tqp_stats_uninit(hw);
 	hns3_config_mac_tnl_int(hw, false);
-- 
2.7.4


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

* [dpdk-dev] [PATCH 5/9] net/hns3: obtain the supported speed for fiber port
  2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
                   ` (3 preceding siblings ...)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 4/9] net/hns3: fix firmware compatibility configuration Min Hu (Connor)
@ 2021-04-13 13:47 ` Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 6/9] net/hns3: report the speed capability for PF Min Hu (Connor)
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-13 13:47 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Huisong Li <lihuisong@huawei.com>

Currently, the speed of fiber port is obtained by using the default
query type of HNS3_OPC_GET_SFP_INFO opcode. In this way, only
the speed of the optical module can be obtained. In fact, the opcode
also supports an active query type, which is a channel for obtaining
information such as the speed, the supported speed, auto-negotiation
capability, and FEC mode. This patch changes the query type of the
opcode from the default query type to the active query type to obtain
the supported speed of fiber port.

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_cmd.h    | 41 ++++++++++++++--------
 drivers/net/hns3/hns3_ethdev.c | 80 ++++++++++++++++++++++++++++++++----------
 drivers/net/hns3/hns3_ethdev.h | 26 ++++++++++++--
 3 files changed, 113 insertions(+), 34 deletions(-)

diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
index a39f159..35f26c0 100644
--- a/drivers/net/hns3/hns3_cmd.h
+++ b/drivers/net/hns3/hns3_cmd.h
@@ -237,7 +237,7 @@ enum hns3_opcode_type {
 	/* SFP command */
 	HNS3_OPC_GET_SFP_EEPROM         = 0x7100,
 	HNS3_OPC_GET_SFP_EXIST          = 0x7101,
-	HNS3_OPC_SFP_GET_SPEED          = 0x7104,
+	HNS3_OPC_GET_SFP_INFO           = 0x7104,
 
 	/* Interrupts commands */
 	HNS3_OPC_ADD_RING_TO_VECTOR     = 0x1503,
@@ -774,13 +774,6 @@ struct hns3_config_auto_neg_cmd {
 	uint8_t   rsv[20];
 };
 
-#define HNS3_MAC_CFG_FEC_AUTO_EN_B	0
-#define HNS3_MAC_CFG_FEC_MODE_S		1
-#define HNS3_MAC_CFG_FEC_MODE_M	GENMASK(3, 1)
-#define HNS3_MAC_FEC_OFF		0
-#define HNS3_MAC_FEC_BASER		1
-#define HNS3_MAC_FEC_RS			2
-
 #define HNS3_SFP_INFO_BD0_LEN  20UL
 #define HNS3_SFP_INFO_BDX_LEN  24UL
 
@@ -795,14 +788,34 @@ struct hns3_sfp_type {
 	uint8_t ext_type;
 };
 
-struct hns3_sfp_speed_cmd {
-	uint32_t  sfp_speed;
-	uint8_t   query_type; /* 0: sfp speed, 1: active fec */
-	uint8_t   active_fec; /* current FEC mode */
-	uint16_t  rsv1;
-	uint32_t  rsv2[4];
+/* Bitmap flags in supported_speed */
+#define HNS3_FIBER_LINK_SPEED_1G_BIT		BIT(0)
+#define HNS3_FIBER_LINK_SPEED_10G_BIT		BIT(1)
+#define HNS3_FIBER_LINK_SPEED_25G_BIT		BIT(2)
+#define HNS3_FIBER_LINK_SPEED_50G_BIT		BIT(3)
+#define HNS3_FIBER_LINK_SPEED_100G_BIT		BIT(4)
+#define HNS3_FIBER_LINK_SPEED_40G_BIT		BIT(5)
+#define HNS3_FIBER_LINK_SPEED_100M_BIT		BIT(6)
+#define HNS3_FIBER_LINK_SPEED_10M_BIT		BIT(7)
+#define HNS3_FIBER_LINK_SPEED_200G_BIT		BIT(8)
+
+struct hns3_sfp_info_cmd {
+	uint32_t sfp_speed;
+	uint8_t query_type; /* 0: sfp speed, 1: active */
+	uint8_t active_fec; /* current FEC mode */
+	uint16_t rsv;
+	uint32_t supported_speed; /* speed supported by current media */
+	uint32_t module_type;
+	uint8_t rsv1[8];
 };
 
+#define HNS3_MAC_CFG_FEC_AUTO_EN_B	0
+#define HNS3_MAC_CFG_FEC_MODE_S		1
+#define HNS3_MAC_CFG_FEC_MODE_M	GENMASK(3, 1)
+#define HNS3_MAC_FEC_OFF		0
+#define HNS3_MAC_FEC_BASER		1
+#define HNS3_MAC_FEC_RS			2
+
 /* Configure FEC mode, opcode:0x031A */
 struct hns3_config_fec_cmd {
 	uint8_t fec_mode;
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index d22d31d..e8ae288 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -4507,24 +4507,45 @@ hns3_dev_promisc_restore(struct hns3_adapter *hns)
 }
 
 static int
-hns3_get_sfp_speed(struct hns3_hw *hw, uint32_t *speed)
+hns3_get_sfp_info(struct hns3_hw *hw, struct hns3_mac *mac_info)
 {
-	struct hns3_sfp_speed_cmd *resp;
+	struct hns3_sfp_info_cmd *resp;
 	struct hns3_cmd_desc desc;
 	int ret;
 
-	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_SFP_GET_SPEED, true);
-	resp = (struct hns3_sfp_speed_cmd *)desc.data;
+	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GET_SFP_INFO, true);
+	resp = (struct hns3_sfp_info_cmd *)desc.data;
+	resp->query_type = HNS3_ACTIVE_QUERY;
+
 	ret = hns3_cmd_send(hw, &desc, 1);
 	if (ret == -EOPNOTSUPP) {
-		hns3_err(hw, "IMP do not support get SFP speed %d", ret);
+		hns3_warn(hw, "firmware does not support get SFP info,"
+			  " ret = %d.", ret);
 		return ret;
 	} else if (ret) {
-		hns3_err(hw, "get sfp speed failed %d", ret);
+		hns3_err(hw, "get sfp info failed, ret = %d.", ret);
 		return ret;
 	}
 
-	*speed = resp->sfp_speed;
+	/*
+	 * In some case, the speed of MAC obtained from firmware may be 0, it
+	 * shouldn't be set to mac->speed.
+	 */
+	if (!rte_le_to_cpu_32(resp->sfp_speed))
+		return 0;
+
+	mac_info->link_speed = rte_le_to_cpu_32(resp->sfp_speed);
+	/*
+	 * if resp->supported_speed is 0, it means it's an old version
+	 * firmware, do not update these params.
+	 */
+	if (resp->supported_speed) {
+		mac_info->query_type = HNS3_ACTIVE_QUERY;
+		mac_info->supported_speed =
+					rte_le_to_cpu_32(resp->supported_speed);
+	} else {
+		mac_info->query_type = HNS3_DEFAULT_QUERY;
+	}
 
 	return 0;
 }
@@ -4566,25 +4587,49 @@ static int
 hns3_update_fiber_link_info(struct hns3_hw *hw)
 {
 	struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw);
-	uint32_t speed;
+	struct hns3_mac *mac = &hw->mac;
+	struct hns3_mac mac_info;
 	int ret;
 
-	/* If IMP do not support get SFP/qSFP speed, return directly */
+	/* If firmware do not support get SFP/qSFP speed, return directly */
 	if (!pf->support_sfp_query)
 		return 0;
 
-	ret = hns3_get_sfp_speed(hw, &speed);
+	memset(&mac_info, 0, sizeof(struct hns3_mac));
+	ret = hns3_get_sfp_info(hw, &mac_info);
 	if (ret == -EOPNOTSUPP) {
 		pf->support_sfp_query = false;
 		return ret;
 	} else if (ret)
 		return ret;
 
-	if (speed == ETH_SPEED_NUM_NONE)
-		return 0; /* do nothing if no SFP */
+	/* Do nothing if no SFP */
+	if (mac_info.link_speed == ETH_SPEED_NUM_NONE)
+		return 0;
+
+	/*
+	 * If query_type is HNS3_ACTIVE_QUERY, it is no need
+	 * to reconfigure the speed of MAC. Otherwise, it indicates
+	 * that the current firmware only supports to obtain the
+	 * speed of the SFP, and the speed of MAC needs to reconfigure.
+	 */
+	mac->query_type = mac_info.query_type;
+	if (mac->query_type == HNS3_ACTIVE_QUERY) {
+		if (mac_info.link_speed != mac->link_speed) {
+			ret = hns3_port_shaper_update(hw, mac_info.link_speed);
+			if (ret)
+				return ret;
+		}
+
+		mac->link_speed = mac_info.link_speed;
+		mac->supported_speed = mac_info.supported_speed;
+
+		return 0;
+	}
 
 	/* Config full duplex for SFP */
-	return hns3_cfg_mac_speed_dup(hw, speed, ETH_LINK_FULL_DUPLEX);
+	return hns3_cfg_mac_speed_dup(hw, mac_info.link_speed,
+				      ETH_LINK_FULL_DUPLEX);
 }
 
 static void
@@ -6200,8 +6245,7 @@ get_current_fec_auto_state(struct hns3_hw *hw, uint8_t *state)
 static int
 hns3_fec_get_internal(struct hns3_hw *hw, uint32_t *fec_capa)
 {
-#define QUERY_ACTIVE_SPEED	1
-	struct hns3_sfp_speed_cmd *resp;
+	struct hns3_sfp_info_cmd *resp;
 	uint32_t tmp_fec_capa;
 	uint8_t auto_state;
 	struct hns3_cmd_desc desc;
@@ -6223,9 +6267,9 @@ hns3_fec_get_internal(struct hns3_hw *hw, uint32_t *fec_capa)
 		}
 	}
 
-	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_SFP_GET_SPEED, true);
-	resp = (struct hns3_sfp_speed_cmd *)desc.data;
-	resp->query_type = QUERY_ACTIVE_SPEED;
+	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GET_SFP_INFO, true);
+	resp = (struct hns3_sfp_info_cmd *)desc.data;
+	resp->query_type = HNS3_ACTIVE_QUERY;
 
 	ret = hns3_cmd_send(hw, &desc, 1);
 	if (ret == -EOPNOTSUPP) {
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 553caa3..a09d825 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -174,6 +174,9 @@ enum hns3_media_type {
 	HNS3_MEDIA_TYPE_NONE,
 };
 
+#define HNS3_DEFAULT_QUERY		0
+#define HNS3_ACTIVE_QUERY		1
+
 struct hns3_mac {
 	uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
 	bool default_addr_setted; /* whether default addr(mac_addr) is set */
@@ -183,10 +186,29 @@ struct hns3_mac {
 	uint8_t link_autoneg : 1; /* ETH_LINK_[AUTONEG/FIXED] */
 	uint8_t link_status  : 1; /* ETH_LINK_[DOWN/UP] */
 	uint32_t link_speed;      /* ETH_SPEED_NUM_ */
+	/*
+	 * Some firmware versions support only the SFP speed query. In addition
+	 * to the SFP speed query, some firmware supports the query of the speed
+	 * capability, auto-negotiation capability, and FEC mode, which can be
+	 * selected by the 'query_type' filed in the HNS3_OPC_GET_SFP_INFO CMD.
+	 * This field is used to record the SFP information query mode.
+	 * Value range:
+	 *       HNS3_DEFAULT_QUERY/HNS3_ACTIVE_QUERY
+	 *
+	 * - HNS3_DEFAULT_QUERY
+	 * Speed obtained is from SFP. When the queried speed changes, the MAC
+	 * speed needs to be reconfigured.
+	 *
+	 * - HNS3_ACTIVE_QUERY
+	 * Speed obtained is from MAC. At this time, it is unnecessary for
+	 * driver to reconfigured the MAC speed. In addition, more information,
+	 * such as, the speed capability, auto-negotiation capability and FEC
+	 * mode, can be obtained by the HNS3_OPC_GET_SFP_INFO CMD.
+	 */
+	uint8_t query_type;
 	uint32_t supported_speed;  /* supported speed for current media type */
 	uint32_t advertising;     /* advertised capability in the local part */
-	/* advertised capability in the link partner */
-	uint32_t lp_advertising;
+	uint32_t lp_advertising; /* advertised capability in the link partner */
 	uint8_t support_autoneg;
 };
 
-- 
2.7.4


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

* [dpdk-dev] [PATCH 6/9] net/hns3: report the speed capability for PF
  2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
                   ` (4 preceding siblings ...)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 5/9] net/hns3: obtain the supported speed for fiber port Min Hu (Connor)
@ 2021-04-13 13:47 ` Min Hu (Connor)
  2021-04-15  0:39   ` Ferruh Yigit
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 7/9] net/hns3: support link speed autoneg " Min Hu (Connor)
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-13 13:47 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Huisong Li <lihuisong@huawei.com>

The speed capability of the device can be reported to the upper-layer app
in rte_eth_dev_info_get API. In this API, the speed capability is derived
from the 'supported_speed', which is the speed capability actually
supported by the NIC. The value of the 'supported_speed' is obtained
once in the probe stage and may be updated in the scheduled task to deal
with the change of the transmission interface.

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 136 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 136 insertions(+)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index e8ae288..7893379 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2617,6 +2617,67 @@ hns3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+static uint32_t
+hns3_get_copper_port_speed_capa(uint32_t supported_speed)
+{
+	uint32_t speed_capa = 0;
+
+	if (supported_speed & HNS3_PHY_LINK_SPEED_10M_HD_BIT)
+		speed_capa |= ETH_LINK_SPEED_10M_HD;
+	if (supported_speed & HNS3_PHY_LINK_SPEED_10M_BIT)
+		speed_capa |= ETH_LINK_SPEED_10M;
+	if (supported_speed & HNS3_PHY_LINK_SPEED_100M_HD_BIT)
+		speed_capa |= ETH_LINK_SPEED_100M_HD;
+	if (supported_speed & HNS3_PHY_LINK_SPEED_100M_BIT)
+		speed_capa |= ETH_LINK_SPEED_100M;
+	if (supported_speed & HNS3_PHY_LINK_SPEED_1000M_BIT)
+		speed_capa |= ETH_LINK_SPEED_1G;
+
+	return speed_capa;
+}
+
+static uint32_t
+hns3_get_firber_port_speed_capa(uint32_t supported_speed)
+{
+	uint32_t speed_capa = 0;
+
+	if (supported_speed & HNS3_FIBER_LINK_SPEED_1G_BIT)
+		speed_capa |= ETH_LINK_SPEED_1G;
+	if (supported_speed & HNS3_FIBER_LINK_SPEED_10G_BIT)
+		speed_capa |= ETH_LINK_SPEED_10G;
+	if (supported_speed & HNS3_FIBER_LINK_SPEED_25G_BIT)
+		speed_capa |= ETH_LINK_SPEED_25G;
+	if (supported_speed & HNS3_FIBER_LINK_SPEED_40G_BIT)
+		speed_capa |= ETH_LINK_SPEED_40G;
+	if (supported_speed & HNS3_FIBER_LINK_SPEED_50G_BIT)
+		speed_capa |= ETH_LINK_SPEED_50G;
+	if (supported_speed & HNS3_FIBER_LINK_SPEED_100G_BIT)
+		speed_capa |= ETH_LINK_SPEED_100G;
+	if (supported_speed & HNS3_FIBER_LINK_SPEED_200G_BIT)
+		speed_capa |= ETH_LINK_SPEED_200G;
+
+	return speed_capa;
+}
+
+static uint32_t
+hns3_get_speed_capa(struct hns3_hw *hw)
+{
+	struct hns3_mac *mac = &hw->mac;
+	uint32_t speed_capa;
+
+	if (mac->media_type == HNS3_MEDIA_TYPE_COPPER)
+		speed_capa =
+			hns3_get_copper_port_speed_capa(mac->supported_speed);
+	else
+		speed_capa =
+			hns3_get_firber_port_speed_capa(mac->supported_speed);
+
+	if (mac->support_autoneg == 0)
+		speed_capa |= ETH_LINK_SPEED_FIXED;
+
+	return speed_capa;
+}
+
 int
 hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 {
@@ -2688,6 +2749,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
 		.nb_mtu_seg_max = hw->max_non_tso_bd_num,
 	};
 
+	info->speed_capa = hns3_get_speed_capa(hw);
 	info->default_rxconf = (struct rte_eth_rxconf) {
 		.rx_free_thresh = HNS3_DEFAULT_RX_FREE_THRESH,
 		/*
@@ -4957,6 +5019,71 @@ hns3_config_all_msix_error(struct hns3_hw *hw, bool enable)
 	hns3_write_dev(hw, HNS3_VECTOR0_OTER_EN_REG, val);
 }
 
+static uint32_t
+hns3_set_firber_default_support_speed(struct hns3_hw *hw)
+{
+	struct hns3_mac *mac = &hw->mac;
+
+	switch (mac->link_speed) {
+	case ETH_SPEED_NUM_1G:
+		return HNS3_FIBER_LINK_SPEED_1G_BIT;
+	case ETH_SPEED_NUM_10G:
+		return HNS3_FIBER_LINK_SPEED_10G_BIT;
+	case ETH_SPEED_NUM_25G:
+		return HNS3_FIBER_LINK_SPEED_25G_BIT;
+	case ETH_SPEED_NUM_40G:
+		return HNS3_FIBER_LINK_SPEED_40G_BIT;
+	case ETH_SPEED_NUM_50G:
+		return HNS3_FIBER_LINK_SPEED_50G_BIT;
+	case ETH_SPEED_NUM_100G:
+		return HNS3_FIBER_LINK_SPEED_100G_BIT;
+	case ETH_SPEED_NUM_200G:
+		return HNS3_FIBER_LINK_SPEED_200G_BIT;
+	default:
+		hns3_warn(hw, "invalid speed %u Mbps.", mac->link_speed);
+		return 0;
+	}
+}
+
+/*
+ * Validity of supported_speed for firber and copper media type can be
+ * guaranteed by the following policy:
+ * Copper:
+ *       Although the initialization of the phy in the firmware may not be
+ *       completed, the firmware can guarantees that the supported_speed is
+ *       an valid value.
+ * Firber:
+ *       If the version of firmware supports the acitive query way of the
+ *       HNS3_OPC_GET_SFP_INFO opcode, the supported_speed can be obtained
+ *       through it. If unsupported, use the SFP's speed as the value of the
+ *       supported_speed.
+ */
+static int
+hns3_get_port_supported_speed(struct rte_eth_dev *eth_dev)
+{
+	struct hns3_adapter *hns = eth_dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	struct hns3_mac *mac = &hw->mac;
+	int ret;
+
+	ret = hns3_update_link_info(eth_dev);
+	if (ret)
+		return ret;
+
+	if (mac->media_type == HNS3_MEDIA_TYPE_FIBER) {
+		/*
+		 * Some firmware does not support the report of supported_speed,
+		 * and only report the effective speed of SFP. In this case, it
+		 * is necessary to use the SFP's speed as the supported_speed.
+		 */
+		if (mac->supported_speed == 0)
+			mac->supported_speed =
+				hns3_set_firber_default_support_speed(hw);
+	}
+
+	return 0;
+}
+
 static int
 hns3_init_pf(struct rte_eth_dev *eth_dev)
 {
@@ -5057,10 +5184,19 @@ hns3_init_pf(struct rte_eth_dev *eth_dev)
 		goto err_enable_intr;
 	}
 
+	ret = hns3_get_port_supported_speed(eth_dev);
+	if (ret) {
+		PMD_INIT_LOG(ERR, "failed to get speed capabilities supported "
+			     "by device, ret = %d.", ret);
+		goto err_supported_speed;
+	}
+
 	hns3_tm_conf_init(eth_dev);
 
 	return 0;
 
+err_supported_speed:
+	(void)hns3_enable_hw_error_intr(hns, false);
 err_enable_intr:
 	hns3_fdir_filter_uninit(hns);
 err_fdir:
-- 
2.7.4


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

* [dpdk-dev] [PATCH 7/9] net/hns3: support link speed autoneg for PF
  2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
                   ` (5 preceding siblings ...)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 6/9] net/hns3: report the speed capability for PF Min Hu (Connor)
@ 2021-04-13 13:47 ` Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 8/9] net/hns3: support flow control autoneg for copper port Min Hu (Connor)
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-13 13:47 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Huisong Li <lihuisong@huawei.com>

This patch supports link speed auto-negotiation for PF. If the
device supports auto-negotiation, the device negotiates with
the link partner at all speeds supported by the device.

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_cmd.h    |   5 +-
 drivers/net/hns3/hns3_ethdev.c | 152 ++++++++++++++++++++++++++++++++++++++++-
 drivers/net/hns3/hns3_ethdev.h |   6 ++
 3 files changed, 160 insertions(+), 3 deletions(-)

diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
index 35f26c0..14f2f21 100644
--- a/drivers/net/hns3/hns3_cmd.h
+++ b/drivers/net/hns3/hns3_cmd.h
@@ -115,6 +115,7 @@ enum hns3_opcode_type {
 
 	/* MAC command */
 	HNS3_OPC_CONFIG_MAC_MODE        = 0x0301,
+	HNS3_OPC_CONFIG_AN_MODE         = 0x0304,
 	HNS3_OPC_QUERY_LINK_STATUS      = 0x0307,
 	HNS3_OPC_CONFIG_MAX_FRM_SIZE    = 0x0308,
 	HNS3_OPC_CONFIG_SPEED_DUP       = 0x0309,
@@ -803,7 +804,9 @@ struct hns3_sfp_info_cmd {
 	uint32_t sfp_speed;
 	uint8_t query_type; /* 0: sfp speed, 1: active */
 	uint8_t active_fec; /* current FEC mode */
-	uint16_t rsv;
+	uint8_t autoneg; /* current autoneg state */
+	/* 0: not support autoneg, 1: support autoneg */
+	uint8_t autoneg_ability;
 	uint32_t supported_speed; /* speed supported by current media */
 	uint32_t module_type;
 	uint8_t rsv1[8];
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 7893379..e251b97 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2850,8 +2850,7 @@ hns3_setup_linkstatus(struct rte_eth_dev *eth_dev,
 
 	new_link->link_duplex = mac->link_duplex;
 	new_link->link_status = mac->link_status ? ETH_LINK_UP : ETH_LINK_DOWN;
-	new_link->link_autoneg =
-	    !(eth_dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED);
+	new_link->link_autoneg = mac->link_autoneg;
 }
 
 static int
@@ -4605,6 +4604,9 @@ hns3_get_sfp_info(struct hns3_hw *hw, struct hns3_mac *mac_info)
 		mac_info->query_type = HNS3_ACTIVE_QUERY;
 		mac_info->supported_speed =
 					rte_le_to_cpu_32(resp->supported_speed);
+		mac_info->support_autoneg = resp->autoneg_ability;
+		mac_info->link_autoneg = (resp->autoneg == 0) ? ETH_LINK_FIXED
+					: ETH_LINK_AUTONEG;
 	} else {
 		mac_info->query_type = HNS3_DEFAULT_QUERY;
 	}
@@ -4685,6 +4687,8 @@ hns3_update_fiber_link_info(struct hns3_hw *hw)
 
 		mac->link_speed = mac_info.link_speed;
 		mac->supported_speed = mac_info.supported_speed;
+		mac->support_autoneg = mac_info.support_autoneg;
+		mac->link_autoneg = mac_info.link_autoneg;
 
 		return 0;
 	}
@@ -5248,6 +5252,144 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev)
 }
 
 static int
+hns3_set_copper_port_link_speed(struct hns3_hw *hw,
+				struct hns3_set_link_speed_cfg *cfg)
+{
+	struct hns3_cmd_desc desc[HNS3_PHY_PARAM_CFG_BD_NUM];
+	struct hns3_phy_params_bd0_cmd *req;
+	uint16_t i;
+
+	for (i = 0; i < HNS3_PHY_PARAM_CFG_BD_NUM - 1; i++) {
+		hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_PHY_PARAM_CFG,
+					  false);
+		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
+	}
+	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_PHY_PARAM_CFG, false);
+	req = (struct hns3_phy_params_bd0_cmd *)desc[0].data;
+	req->autoneg = cfg->autoneg;
+
+	/*
+	 * The full speed capability is used to negotiate when
+	 * auto-negotiation is enabled.
+	 */
+	if (cfg->autoneg) {
+		req->advertising = HNS3_PHY_LINK_SPEED_10M_BIT |
+				    HNS3_PHY_LINK_SPEED_10M_HD_BIT |
+				    HNS3_PHY_LINK_SPEED_100M_BIT |
+				    HNS3_PHY_LINK_SPEED_100M_HD_BIT |
+				    HNS3_PHY_LINK_SPEED_1000M_BIT;
+	}
+
+	return hns3_cmd_send(hw, desc, HNS3_PHY_PARAM_CFG_BD_NUM);
+}
+
+static int
+hns3_set_autoneg(struct hns3_hw *hw, bool enable)
+{
+	struct hns3_config_auto_neg_cmd *req;
+	struct hns3_cmd_desc desc;
+	uint32_t flag = 0;
+	int ret;
+
+	hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CONFIG_AN_MODE, false);
+
+	req = (struct hns3_config_auto_neg_cmd *)desc.data;
+	if (enable)
+		hns3_set_bit(flag, HNS3_MAC_CFG_AN_EN_B, 1);
+	req->cfg_an_cmd_flag = rte_cpu_to_le_32(flag);
+
+	ret = hns3_cmd_send(hw, &desc, 1);
+	if (ret)
+		hns3_err(hw, "autoneg set cmd failed, ret = %d.", ret);
+
+	return ret;
+}
+
+static int
+hns3_set_fiber_port_link_speed(struct hns3_hw *hw,
+			       struct hns3_set_link_speed_cfg *cfg)
+{
+	int ret;
+
+	if (hw->mac.support_autoneg) {
+		ret = hns3_set_autoneg(hw, cfg->autoneg);
+		if (ret) {
+			hns3_err(hw, "failed to configure auto-negotiation.");
+			return ret;
+		}
+
+		/*
+		 * To enable auto-negotiation, we only need to open the switch
+		 * of auto-negotiation, then firmware sets all speed
+		 * capabilities.
+		 */
+		if (cfg->autoneg)
+			return 0;
+	}
+
+	/*
+	 * Some hardware doesn't support auto-negotiation, but users may not
+	 * configure link_speeds (default 0), which means auto-negotiation
+	 * In this case, a warning message need to be printed, instead of
+	 * an error.
+	 */
+	if (cfg->autoneg) {
+		hns3_warn(hw, "auto-negotiation is not supported.");
+		return 0;
+	}
+
+	return 0;
+}
+
+static int
+hns3_set_port_link_speed(struct hns3_hw *hw,
+			 struct hns3_set_link_speed_cfg *cfg)
+{
+	int ret;
+
+	if (hw->mac.media_type == HNS3_MEDIA_TYPE_COPPER) {
+#if defined(RTE_HNS3_ONLY_1630_FPGA)
+		struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw);
+		if (pf->is_tmp_phy)
+			return 0;
+#endif
+
+		ret = hns3_set_copper_port_link_speed(hw, cfg);
+		if (ret) {
+			hns3_err(hw, "failed to set copper port link speed,"
+				 "ret = %d.", ret);
+			return ret;
+		}
+	} else if (hw->mac.media_type == HNS3_MEDIA_TYPE_FIBER) {
+		ret = hns3_set_fiber_port_link_speed(hw, cfg);
+		if (ret) {
+			hns3_err(hw, "failed to set fiber port link speed,"
+				 "ret = %d.", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int
+hns3_apply_link_speed(struct hns3_hw *hw)
+{
+	struct rte_eth_conf *conf = &hw->data->dev_conf;
+	struct hns3_set_link_speed_cfg cfg;
+
+	memset(&cfg, 0, sizeof(struct hns3_set_link_speed_cfg));
+	cfg.autoneg = (conf->link_speeds == ETH_LINK_SPEED_AUTONEG) ?
+			ETH_LINK_AUTONEG : ETH_LINK_FIXED;
+	if (cfg.autoneg != ETH_LINK_AUTONEG) {
+		hns3_err(hw, "device doesn't support to force link speed.");
+		return -EOPNOTSUPP;
+	}
+
+	return hns3_set_port_link_speed(hw, &cfg);
+}
+
+static int
 hns3_do_start(struct hns3_adapter *hns, bool reset_queue)
 {
 	struct hns3_hw *hw = &hns->hw;
@@ -5280,9 +5422,15 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue)
 		PMD_INIT_LOG(ERR, "failed to enable MAC, ret = %d", ret);
 		goto err_config_mac_mode;
 	}
+
+	ret = hns3_apply_link_speed(hw);
+	if (ret)
+		goto err_config_mac_mode;
+
 	return 0;
 
 err_config_mac_mode:
+	(void)hns3_cfg_mac_mode(hw, false);
 	hns3_dev_release_mbufs(hns);
 	/*
 	 * Here is exception handling, hns3_reset_all_tqps will have the
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index a09d825..3e2fe7b 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -165,6 +165,12 @@ struct hns3_cfg {
 	uint16_t umv_space;
 };
 
+struct hns3_set_link_speed_cfg {
+	uint32_t speed;
+	uint8_t duplex  : 1;
+	uint8_t autoneg : 1;
+};
+
 /* mac media type */
 enum hns3_media_type {
 	HNS3_MEDIA_TYPE_UNKNOWN,
-- 
2.7.4


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

* [dpdk-dev] [PATCH 8/9] net/hns3: support flow control autoneg for copper port
  2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
                   ` (6 preceding siblings ...)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 7/9] net/hns3: support link speed autoneg " Min Hu (Connor)
@ 2021-04-13 13:47 ` Min Hu (Connor)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 9/9] net/hns3: add the configuration of fixed speed Min Hu (Connor)
  2021-04-15  0:55 ` [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Ferruh Yigit
  9 siblings, 0 replies; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-13 13:47 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Huisong Li <lihuisong@huawei.com>

If the flow control auto-negotiation is not supported and the flow
control modes on the local and link partner is asymmetric, the flow
control on the NIC does not take effect. The support of the
auto-negotiation capability requires the cooperation of the firmware
and driver.

This patch supports the flow control auto-negotiation only for copper
port. For optical ports, the forced flow control mode is still used.

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 162 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 152 insertions(+), 10 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index e251b97..6262bf0 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -5088,6 +5088,24 @@ hns3_get_port_supported_speed(struct rte_eth_dev *eth_dev)
 	return 0;
 }
 
+static void
+hns3_get_fc_autoneg_capability(struct hns3_adapter *hns)
+{
+	struct hns3_mac *mac = &hns->hw.mac;
+
+	if (mac->media_type == HNS3_MEDIA_TYPE_COPPER) {
+		hns->pf.support_fc_autoneg = true;
+		return;
+	}
+
+	/*
+	 * Flow control auto-negotiation requires the cooperation of the driver
+	 * and firmware. Currently, the optical port does not support flow
+	 * control auto-negotiation.
+	 */
+	hns->pf.support_fc_autoneg = false;
+}
+
 static int
 hns3_init_pf(struct rte_eth_dev *eth_dev)
 {
@@ -5195,6 +5213,8 @@ hns3_init_pf(struct rte_eth_dev *eth_dev)
 		goto err_supported_speed;
 	}
 
+	hns3_get_fc_autoneg_capability(hns);
+
 	hns3_tm_conf_init(eth_dev);
 
 	return 0;
@@ -5761,19 +5781,102 @@ hns3_dev_close(struct rte_eth_dev *eth_dev)
 	return ret;
 }
 
-static int
-hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+static void
+hns3_get_autoneg_rxtx_pause_copper(struct hns3_hw *hw, bool *rx_pause,
+				   bool *tx_pause)
+{
+	struct hns3_mac *mac = &hw->mac;
+	uint32_t advertising = mac->advertising;
+	uint32_t lp_advertising = mac->lp_advertising;
+	*rx_pause = false;
+	*tx_pause = false;
+
+	if (advertising & lp_advertising & HNS3_PHY_LINK_MODE_PAUSE_BIT) {
+		*rx_pause = true;
+		*tx_pause = true;
+	} else if (advertising & lp_advertising &
+		   HNS3_PHY_LINK_MODE_ASYM_PAUSE_BIT) {
+		if (advertising & HNS3_PHY_LINK_MODE_PAUSE_BIT)
+			*rx_pause = true;
+		else if (lp_advertising & HNS3_PHY_LINK_MODE_PAUSE_BIT)
+			*tx_pause = true;
+	}
+}
+
+static enum hns3_fc_mode
+hns3_get_autoneg_fc_mode(struct hns3_hw *hw)
+{
+	enum hns3_fc_mode current_mode;
+	bool rx_pause = false;
+	bool tx_pause = false;
+
+	switch (hw->mac.media_type) {
+	case HNS3_MEDIA_TYPE_COPPER:
+		hns3_get_autoneg_rxtx_pause_copper(hw, &rx_pause, &tx_pause);
+		break;
+
+	/*
+	 * Flow control auto-negotiation is not supported for fiber and
+	 * backpalne media type.
+	 */
+	case HNS3_MEDIA_TYPE_FIBER:
+	case HNS3_MEDIA_TYPE_BACKPLANE:
+		hns3_err(hw, "autoneg FC mode can't be obtained, but flow control auto-negotiation is enabled.");
+		current_mode = hw->requested_fc_mode;
+		goto out;
+	default:
+		hns3_err(hw, "autoneg FC mode can't be obtained for unknown media type(%u).",
+			 hw->mac.media_type);
+		current_mode = HNS3_FC_NONE;
+		goto out;
+	}
+
+	if (rx_pause && tx_pause)
+		current_mode = HNS3_FC_FULL;
+	else if (rx_pause)
+		current_mode = HNS3_FC_RX_PAUSE;
+	else if (tx_pause)
+		current_mode = HNS3_FC_TX_PAUSE;
+	else
+		current_mode = HNS3_FC_NONE;
+
+out:
+	return current_mode;
+}
+
+static enum hns3_fc_mode
+hns3_get_current_fc_mode(struct rte_eth_dev *dev)
 {
 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct hns3_mac *mac = &hw->mac;
 
-	fc_conf->pause_time = pf->pause_time;
+	/*
+	 * When the flow control mode is obtained, the device may not complete
+	 * auto-negotiation. It is necessary to wait for link establishment.
+	 */
+	(void)hns3_dev_link_update(dev, 1);
 
 	/*
-	 * If fc auto-negotiation is not supported, the configured fc mode
-	 * from user is the current fc mode.
+	 * If the link auto-negotiation of the nic is disabled, or the flow
+	 * control auto-negotiation is not supported, the forced flow control
+	 * mode is used.
 	 */
-	switch (hw->requested_fc_mode) {
+	if (mac->link_autoneg == 0 || !pf->support_fc_autoneg)
+		return hw->requested_fc_mode;
+
+	return hns3_get_autoneg_fc_mode(hw);
+}
+
+static int
+hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+{
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct hns3_pf *pf = HNS3_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	enum hns3_fc_mode current_mode;
+
+	current_mode = hns3_get_current_fc_mode(dev);
+	switch (current_mode) {
 	case HNS3_FC_FULL:
 		fc_conf->mode = RTE_FC_FULL;
 		break;
@@ -5789,6 +5892,9 @@ hns3_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 		break;
 	}
 
+	fc_conf->pause_time = pf->pause_time;
+	fc_conf->autoneg = pf->support_fc_autoneg ? hw->mac.link_autoneg : 0;
+
 	return 0;
 }
 
@@ -5817,6 +5923,41 @@ hns3_get_fc_mode(struct hns3_hw *hw, enum rte_eth_fc_mode mode)
 }
 
 static int
+hns3_check_fc_autoneg_valid(struct hns3_hw *hw, uint8_t autoneg)
+{
+	struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw);
+
+	if (!pf->support_fc_autoneg) {
+		if (autoneg != 0) {
+			hns3_err(hw, "unsupported fc auto-negotiation setting.");
+			return -EOPNOTSUPP;
+		}
+
+		/*
+		 * Flow control auto-negotiation of the NIC is not supported,
+		 * but other auto-negotiation features may be supported.
+		 */
+		if (autoneg != hw->mac.link_autoneg) {
+			hns3_err(hw, "please use 'link_speeds' in struct rte_eth_conf to disable autoneg!");
+			return -EOPNOTSUPP;
+		}
+
+		return 0;
+	}
+
+	/*
+	 * If flow control auto-negotiation of the NIC is supported, all
+	 * auto-negotiation features are supported.
+	 */
+	if (autoneg != hw->mac.link_autoneg) {
+		hns3_err(hw, "please use 'link_speeds' in struct rte_eth_conf to change autoneg!");
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int
 hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 {
 	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -5831,10 +5972,11 @@ hns3_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 			 fc_conf->send_xon, fc_conf->mac_ctrl_frame_fwd);
 		return -EINVAL;
 	}
-	if (fc_conf->autoneg) {
-		hns3_err(hw, "Unsupported fc auto-negotiation setting.");
-		return -EINVAL;
-	}
+
+	ret = hns3_check_fc_autoneg_valid(hw, fc_conf->autoneg);
+	if (ret)
+		return ret;
+
 	if (!fc_conf->pause_time) {
 		hns3_err(hw, "Invalid pause time %u setting.",
 			 fc_conf->pause_time);
-- 
2.7.4


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

* [dpdk-dev] [PATCH 9/9] net/hns3: add the configuration of fixed speed
  2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
                   ` (7 preceding siblings ...)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 8/9] net/hns3: support flow control autoneg for copper port Min Hu (Connor)
@ 2021-04-13 13:47 ` Min Hu (Connor)
  2021-04-15  0:55 ` [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Ferruh Yigit
  9 siblings, 0 replies; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-13 13:47 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

From: Huisong Li <lihuisong@huawei.com>

This patch adds the configuration of fixed speed for the PF device.

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 drivers/net/hns3/hns3_ethdev.c | 144 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 135 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 6262bf0..d5e2901 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -2473,12 +2473,6 @@ hns3_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	hw->adapter_state = HNS3_NIC_CONFIGURING;
-	if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
-		hns3_err(hw, "setting link speed/duplex not supported");
-		ret = -EINVAL;
-		goto cfg_err;
-	}
-
 	if ((uint32_t)mq_mode & ETH_MQ_RX_DCB_FLAG) {
 		ret = hns3_check_dcb_cfg(dev);
 		if (ret)
@@ -5271,6 +5265,130 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev)
 	hw->io_base = NULL;
 }
 
+static uint32_t
+hns3_convert_link_speeds2bitmap_copper(uint32_t link_speeds)
+{
+	uint32_t speed_bit;
+
+	switch (link_speeds & ~ETH_LINK_SPEED_FIXED) {
+	case ETH_LINK_SPEED_10M:
+		speed_bit = HNS3_PHY_LINK_SPEED_10M_BIT;
+		break;
+	case ETH_LINK_SPEED_10M_HD:
+		speed_bit = HNS3_PHY_LINK_SPEED_10M_HD_BIT;
+		break;
+	case ETH_LINK_SPEED_100M:
+		speed_bit = HNS3_PHY_LINK_SPEED_100M_BIT;
+		break;
+	case ETH_LINK_SPEED_100M_HD:
+		speed_bit = HNS3_PHY_LINK_SPEED_100M_HD_BIT;
+		break;
+	case ETH_LINK_SPEED_1G:
+		speed_bit = HNS3_PHY_LINK_SPEED_1000M_BIT;
+		break;
+	default:
+		speed_bit = 0;
+		break;
+	}
+
+	return speed_bit;
+}
+
+static uint32_t
+hns3_convert_link_speeds2bitmap_fiber(uint32_t link_speeds)
+{
+	uint32_t speed_bit;
+
+	switch (link_speeds & ~ETH_LINK_SPEED_FIXED) {
+	case ETH_LINK_SPEED_1G:
+		speed_bit = HNS3_FIBER_LINK_SPEED_1G_BIT;
+		break;
+	case ETH_LINK_SPEED_10G:
+		speed_bit = HNS3_FIBER_LINK_SPEED_10G_BIT;
+		break;
+	case ETH_LINK_SPEED_25G:
+		speed_bit = HNS3_FIBER_LINK_SPEED_25G_BIT;
+		break;
+	case ETH_LINK_SPEED_40G:
+		speed_bit = HNS3_FIBER_LINK_SPEED_40G_BIT;
+		break;
+	case ETH_LINK_SPEED_50G:
+		speed_bit = HNS3_FIBER_LINK_SPEED_50G_BIT;
+		break;
+	case ETH_LINK_SPEED_100G:
+		speed_bit = HNS3_FIBER_LINK_SPEED_100G_BIT;
+		break;
+	case ETH_LINK_SPEED_200G:
+		speed_bit = HNS3_FIBER_LINK_SPEED_200G_BIT;
+		break;
+	default:
+		speed_bit = 0;
+		break;
+	}
+
+	return speed_bit;
+}
+
+static int
+hns3_check_port_speed(struct hns3_hw *hw, uint32_t link_speeds)
+{
+	struct hns3_mac *mac = &hw->mac;
+	uint32_t supported_speed = mac->supported_speed;
+	uint32_t speed_bit = 0;
+
+	if (mac->media_type == HNS3_MEDIA_TYPE_COPPER)
+		speed_bit = hns3_convert_link_speeds2bitmap_copper(link_speeds);
+	else if (mac->media_type == HNS3_MEDIA_TYPE_FIBER)
+		speed_bit = hns3_convert_link_speeds2bitmap_fiber(link_speeds);
+
+	if (!(speed_bit & supported_speed)) {
+		hns3_err(hw, "link_speeds(0x%x) exceeds the supported speed capability or is incorrect.",
+			 link_speeds);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static inline uint32_t
+hns3_get_link_speed(uint32_t link_speeds)
+{
+	uint32_t speed = ETH_SPEED_NUM_NONE;
+
+	if (link_speeds & ETH_LINK_SPEED_10M ||
+	    link_speeds & ETH_LINK_SPEED_10M_HD)
+		speed = ETH_SPEED_NUM_10M;
+	if (link_speeds & ETH_LINK_SPEED_100M ||
+	    link_speeds & ETH_LINK_SPEED_100M_HD)
+		speed = ETH_SPEED_NUM_100M;
+	if (link_speeds & ETH_LINK_SPEED_1G)
+		speed = ETH_SPEED_NUM_1G;
+	if (link_speeds & ETH_LINK_SPEED_10G)
+		speed = ETH_SPEED_NUM_10G;
+	if (link_speeds & ETH_LINK_SPEED_25G)
+		speed = ETH_SPEED_NUM_25G;
+	if (link_speeds & ETH_LINK_SPEED_40G)
+		speed = ETH_SPEED_NUM_40G;
+	if (link_speeds & ETH_LINK_SPEED_50G)
+		speed = ETH_SPEED_NUM_50G;
+	if (link_speeds & ETH_LINK_SPEED_100G)
+		speed = ETH_SPEED_NUM_100G;
+	if (link_speeds & ETH_LINK_SPEED_200G)
+		speed = ETH_SPEED_NUM_200G;
+
+	return speed;
+}
+
+static uint8_t
+hns3_get_link_duplex(uint32_t link_speeds)
+{
+	if ((link_speeds & ETH_LINK_SPEED_10M_HD) ||
+	    (link_speeds & ETH_LINK_SPEED_100M_HD))
+		return ETH_LINK_HALF_DUPLEX;
+	else
+		return ETH_LINK_FULL_DUPLEX;
+}
+
 static int
 hns3_set_copper_port_link_speed(struct hns3_hw *hw,
 				struct hns3_set_link_speed_cfg *cfg)
@@ -5298,6 +5416,9 @@ hns3_set_copper_port_link_speed(struct hns3_hw *hw,
 				    HNS3_PHY_LINK_SPEED_100M_BIT |
 				    HNS3_PHY_LINK_SPEED_100M_HD_BIT |
 				    HNS3_PHY_LINK_SPEED_1000M_BIT;
+	} else {
+		req->speed = cfg->speed;
+		req->duplex = cfg->duplex;
 	}
 
 	return hns3_cmd_send(hw, desc, HNS3_PHY_PARAM_CFG_BD_NUM);
@@ -5358,7 +5479,7 @@ hns3_set_fiber_port_link_speed(struct hns3_hw *hw,
 		return 0;
 	}
 
-	return 0;
+	return hns3_cfg_mac_speed_dup(hw, cfg->speed, cfg->duplex);
 }
 
 static int
@@ -5397,13 +5518,18 @@ hns3_apply_link_speed(struct hns3_hw *hw)
 {
 	struct rte_eth_conf *conf = &hw->data->dev_conf;
 	struct hns3_set_link_speed_cfg cfg;
+	int ret;
 
 	memset(&cfg, 0, sizeof(struct hns3_set_link_speed_cfg));
 	cfg.autoneg = (conf->link_speeds == ETH_LINK_SPEED_AUTONEG) ?
 			ETH_LINK_AUTONEG : ETH_LINK_FIXED;
 	if (cfg.autoneg != ETH_LINK_AUTONEG) {
-		hns3_err(hw, "device doesn't support to force link speed.");
-		return -EOPNOTSUPP;
+		ret = hns3_check_port_speed(hw, conf->link_speeds);
+		if (ret)
+			return ret;
+
+		cfg.speed = hns3_get_link_speed(conf->link_speeds);
+		cfg.duplex = hns3_get_link_duplex(conf->link_speeds);
 	}
 
 	return hns3_set_port_link_speed(hw, &cfg);
-- 
2.7.4


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

* Re: [dpdk-dev] [PATCH 6/9] net/hns3: report the speed capability for PF
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 6/9] net/hns3: report the speed capability for PF Min Hu (Connor)
@ 2021-04-15  0:39   ` Ferruh Yigit
  2021-04-15  0:57     ` Ferruh Yigit
  0 siblings, 1 reply; 14+ messages in thread
From: Ferruh Yigit @ 2021-04-15  0:39 UTC (permalink / raw)
  To: Min Hu (Connor), dev

On 4/13/2021 2:47 PM, Min Hu (Connor) wrote:
> From: Huisong Li <lihuisong@huawei.com>
> 
> The speed capability of the device can be reported to the upper-layer app
> in rte_eth_dev_info_get API. In this API, the speed capability is derived
> from the 'supported_speed', which is the speed capability actually
> supported by the NIC. The value of the 'supported_speed' is obtained
> once in the probe stage and may be updated in the scheduled task to deal
> with the change of the transmission interface.
> 
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>

<...>

> @@ -2688,6 +2749,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
>   		.nb_mtu_seg_max = hw->max_non_tso_bd_num,
>   	};
>   
> +	info->speed_capa = hns3_get_speed_capa(hw);

Can you please update 'hns3.ini', to advertise 'Speed capabilities' support?

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

* Re: [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report
  2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
                   ` (8 preceding siblings ...)
  2021-04-13 13:47 ` [dpdk-dev] [PATCH 9/9] net/hns3: add the configuration of fixed speed Min Hu (Connor)
@ 2021-04-15  0:55 ` Ferruh Yigit
  9 siblings, 0 replies; 14+ messages in thread
From: Ferruh Yigit @ 2021-04-15  0:55 UTC (permalink / raw)
  To: Min Hu (Connor), dev

On 4/13/2021 2:47 PM, Min Hu (Connor) wrote:
> The patchset has the following functions:
> 1.report speed capability supported by the current hardware.
> 2.support link speed autoneg and force link speed for PF.
> 3.support flow control autoneg for copper port.
> 
> Huisong Li (9):
>    net/hns3: fix supported speed of copper ports
>    net/hns3: add 1000M speed bit for copper PHYs
>    net/hns3: fix flow control mode
>    net/hns3: fix firmware compatibility configuration
>    net/hns3: obtain the supported speed for fiber port
>    net/hns3: report the speed capability for PF
>    net/hns3: support link speed autoneg for PF
>    net/hns3: support flow control autoneg for copper port
>    net/hns3: add the configuration of fixed speed
> 

Series applied to dpdk-next-net/main, thanks.

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

* Re: [dpdk-dev] [PATCH 6/9] net/hns3: report the speed capability for PF
  2021-04-15  0:39   ` Ferruh Yigit
@ 2021-04-15  0:57     ` Ferruh Yigit
  2021-04-15  1:16       ` Min Hu (Connor)
  0 siblings, 1 reply; 14+ messages in thread
From: Ferruh Yigit @ 2021-04-15  0:57 UTC (permalink / raw)
  To: Min Hu (Connor), dev

On 4/15/2021 1:39 AM, Ferruh Yigit wrote:
> On 4/13/2021 2:47 PM, Min Hu (Connor) wrote:
>> From: Huisong Li <lihuisong@huawei.com>
>>
>> The speed capability of the device can be reported to the upper-layer app
>> in rte_eth_dev_info_get API. In this API, the speed capability is derived
>> from the 'supported_speed', which is the speed capability actually
>> supported by the NIC. The value of the 'supported_speed' is obtained
>> once in the probe stage and may be updated in the scheduled task to deal
>> with the change of the transmission interface.
>>
>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> 
> <...>
> 
>> @@ -2688,6 +2749,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct 
>> rte_eth_dev_info *info)
>>           .nb_mtu_seg_max = hw->max_non_tso_bd_num,
>>       };
>> +    info->speed_capa = hns3_get_speed_capa(hw);
> 
> Can you please update 'hns3.ini', to advertise 'Speed capabilities' support?

'hns3.ini' added while merging, please verify the final commit.


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

* Re: [dpdk-dev] [PATCH 6/9] net/hns3: report the speed capability for PF
  2021-04-15  0:57     ` Ferruh Yigit
@ 2021-04-15  1:16       ` Min Hu (Connor)
  0 siblings, 0 replies; 14+ messages in thread
From: Min Hu (Connor) @ 2021-04-15  1:16 UTC (permalink / raw)
  To: Ferruh Yigit, dev



在 2021/4/15 8:57, Ferruh Yigit 写道:
> On 4/15/2021 1:39 AM, Ferruh Yigit wrote:
>> On 4/13/2021 2:47 PM, Min Hu (Connor) wrote:
>>> From: Huisong Li <lihuisong@huawei.com>
>>>
>>> The speed capability of the device can be reported to the upper-layer 
>>> app
>>> in rte_eth_dev_info_get API. In this API, the speed capability is 
>>> derived
>>> from the 'supported_speed', which is the speed capability actually
>>> supported by the NIC. The value of the 'supported_speed' is obtained
>>> once in the probe stage and may be updated in the scheduled task to deal
>>> with the change of the transmission interface.
>>>
>>> Signed-off-by: Huisong Li <lihuisong@huawei.com>
>>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>>
>> <...>
>>
>>> @@ -2688,6 +2749,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, 
>>> struct rte_eth_dev_info *info)
>>>           .nb_mtu_seg_max = hw->max_non_tso_bd_num,
>>>       };
>>> +    info->speed_capa = hns3_get_speed_capa(hw);
>>
>> Can you please update 'hns3.ini', to advertise 'Speed capabilities' 
>> support?
> 
> 'hns3.ini' added while merging, please verify the final commit.
> 
Thanks Ferruh.
> .

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

end of thread, other threads:[~2021-04-15  1:16 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-13 13:47 [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Min Hu (Connor)
2021-04-13 13:47 ` [dpdk-dev] [PATCH 1/9] net/hns3: fix supported speed of copper ports Min Hu (Connor)
2021-04-13 13:47 ` [dpdk-dev] [PATCH 2/9] net/hns3: add 1000M speed bit for copper PHYs Min Hu (Connor)
2021-04-13 13:47 ` [dpdk-dev] [PATCH 3/9] net/hns3: fix flow control mode Min Hu (Connor)
2021-04-13 13:47 ` [dpdk-dev] [PATCH 4/9] net/hns3: fix firmware compatibility configuration Min Hu (Connor)
2021-04-13 13:47 ` [dpdk-dev] [PATCH 5/9] net/hns3: obtain the supported speed for fiber port Min Hu (Connor)
2021-04-13 13:47 ` [dpdk-dev] [PATCH 6/9] net/hns3: report the speed capability for PF Min Hu (Connor)
2021-04-15  0:39   ` Ferruh Yigit
2021-04-15  0:57     ` Ferruh Yigit
2021-04-15  1:16       ` Min Hu (Connor)
2021-04-13 13:47 ` [dpdk-dev] [PATCH 7/9] net/hns3: support link speed autoneg " Min Hu (Connor)
2021-04-13 13:47 ` [dpdk-dev] [PATCH 8/9] net/hns3: support flow control autoneg for copper port Min Hu (Connor)
2021-04-13 13:47 ` [dpdk-dev] [PATCH 9/9] net/hns3: add the configuration of fixed speed Min Hu (Connor)
2021-04-15  0:55 ` [dpdk-dev] [PATCH 0/9] support speed capability and autoneg report Ferruh Yigit

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