+static int
+hns3_dev_set_link_up(struct rte_eth_dev *dev)
+{
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ int ret;
+
+ /*
+ * The "tx_pkt_burst" will be restored. But the secondary process does
+ * not support the mechanism for notifying the primary process.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ hns3_err(hw, "secondary process does not support to set link up.");
+ return -ENOTSUP;
+ }
+
+ /*
+ * If device isn't started Rx/Tx function is still disabled, setting
+ * link up is not allowed. But it is probably better to return success
+ * to reduce the impact on the upper layer.
+ */
+ if (hw->adapter_state != HNS3_NIC_STARTED) {
+ hns3_info(hw, "device isn't started, can't set link up.");
+ return 0;
+ }
+
+ if (!hw->set_link_down)
+ return 0;
+
+ rte_spinlock_lock(&hw->lock);
+ ret = hns3_cfg_mac_mode(hw, true);
+ if (ret) {
+ rte_spinlock_unlock(&hw->lock);
+ hns3_err(hw, "failed to set link up, ret = %d", ret);
+ return ret;
+ }
+
+ hw->set_link_down = false;
+ hns3_start_tx_datapath(dev);
+ rte_spinlock_unlock(&hw->lock);
+
+ return 0;
+}
+
+static int
+hns3_dev_set_link_down(struct rte_eth_dev *dev)
+{
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ int ret;
+
+ /*
+ * The "tx_pkt_burst" will be set to dummy function. But the secondary
+ * process does not support the mechanism for notifying the primary
+ * process.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ hns3_err(hw, "secondary process does not support to set link down.");
+ return -ENOTSUP;
+ }
+
+ /*
+ * If device isn't started or the API has been called, link status is
+ * down, return success.
+ */
+ if (hw->adapter_state != HNS3_NIC_STARTED || hw->set_link_down)
+ return 0;
+
+ rte_spinlock_lock(&hw->lock);
+ hns3_stop_tx_datapath(dev);
+ ret = hns3_cfg_mac_mode(hw, false);
+ if (ret) {
+ hns3_start_tx_datapath(dev);
+ rte_spinlock_unlock(&hw->lock);
+ hns3_err(hw, "failed to set link down, ret = %d", ret);
+ return ret;
+ }
+
+ hw->set_link_down = true;
+ rte_spinlock_unlock(&hw->lock);
+
+ return 0;
+}
+