Update DPDK version from 19.11 to 20.11 and also support hns3 PMD for Kunpeng 920 and Kunpeng 930. Signed-off-by: speech_white <humin29@huawei.com>
240 lines
6.8 KiB
Diff
240 lines
6.8 KiB
Diff
From d2f7bc262f17f8f640e279706f6b3bc99a4dbb0f Mon Sep 17 00:00:00 2001
|
|
From: Huisong Li <lihuisong@huawei.com>
|
|
Date: Tue, 13 Apr 2021 21:47:18 +0800
|
|
Subject: [PATCH 115/189] net/hns3: support flow control autoneg for copper
|
|
port
|
|
|
|
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 019d9fe..1ee1651 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
|
|
|