New upstream version 18.11-rc2
[deb_dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.c
index 269595b..c9e82d5 100644 (file)
@@ -220,6 +220,8 @@ static int ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev);
 static int ixgbe_dev_interrupt_action(struct rte_eth_dev *dev);
 static void ixgbe_dev_interrupt_handler(void *param);
 static void ixgbe_dev_interrupt_delayed_handler(void *param);
+static void ixgbe_dev_setup_link_alarm_handler(void *param);
+
 static int ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
                         uint32_t index, uint32_t pool);
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
@@ -1303,7 +1305,7 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
        PMD_INIT_FUNC_TRACE();
 
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-               return -EPERM;
+               return 0;
 
        hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 
@@ -1702,7 +1704,7 @@ eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
        PMD_INIT_FUNC_TRACE();
 
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
-               return -EPERM;
+               return 0;
 
        hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 
@@ -2793,6 +2795,8 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 
        PMD_INIT_FUNC_TRACE();
 
+       rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);
+
        /* disable interrupts */
        ixgbe_disable_intr(hw);
 
@@ -3971,6 +3975,25 @@ out:
        return ret_val;
 }
 
+static void
+ixgbe_dev_setup_link_alarm_handler(void *param)
+{
+       struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ixgbe_interrupt *intr =
+               IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+       u32 speed;
+       bool autoneg = false;
+
+       speed = hw->phy.autoneg_advertised;
+       if (!speed)
+               ixgbe_get_link_capabilities(hw, &speed, &autoneg);
+
+       ixgbe_setup_link(hw, speed, true);
+
+       intr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 int
 ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
@@ -3983,9 +4006,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
                IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
        int link_up;
        int diag;
-       u32 speed = 0;
        int wait = 1;
-       bool autoneg = false;
 
        memset(&link, 0, sizeof(link));
        link.link_status = ETH_LINK_DOWN;
@@ -3995,13 +4016,8 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 
        hw->mac.get_link_status = true;
 
-       if ((intr->flags & IXGBE_FLAG_NEED_LINK_CONFIG) &&
-               ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
-               speed = hw->phy.autoneg_advertised;
-               if (!speed)
-                       ixgbe_get_link_capabilities(hw, &speed, &autoneg);
-               ixgbe_setup_link(hw, speed, true);
-       }
+       if (intr->flags & IXGBE_FLAG_NEED_LINK_CONFIG)
+               return rte_eth_linkstatus_set(dev, &link);
 
        /* check if it needs to wait to complete, if lsc interrupt is enabled */
        if (wait_to_complete == 0 || dev->data->dev_conf.intr_conf.lsc != 0)
@@ -4019,11 +4035,14 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
        }
 
        if (link_up == 0) {
-               intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+               if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
+                       intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+                       rte_eal_alarm_set(10,
+                               ixgbe_dev_setup_link_alarm_handler, dev);
+               }
                return rte_eth_linkstatus_set(dev, &link);
        }
 
-       intr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
        link.link_status = ETH_LINK_UP;
        link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
@@ -5128,6 +5147,8 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev)
 
        PMD_INIT_FUNC_TRACE();
 
+       rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);
+
        ixgbevf_intr_disable(dev);
 
        hw->adapter_stopped = 1;