Merge branch 'upstream-16.11-stable' into 16.11.x
[deb_dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.c
index 73996bb..2dc69ff 100644 (file)
@@ -93,6 +93,9 @@
 /* Timer value included in XOFF frames. */
 #define IXGBE_FC_PAUSE 0x680
 
+/*Default value of Max Rx Queue*/
+#define IXGBE_MAX_RX_QUEUE_NUM 128
+
 #define IXGBE_LINK_DOWN_CHECK_TIMEOUT 4000 /* ms */
 #define IXGBE_LINK_UP_CHECK_TIMEOUT   1000 /* ms */
 #define IXGBE_VMDQ_NUM_UC_MAC         4096 /* Maximum nb. of UC MAC addr. */
@@ -249,6 +252,8 @@ static int eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev);
 static int  ixgbevf_dev_configure(struct rte_eth_dev *dev);
 static int  ixgbevf_dev_start(struct rte_eth_dev *dev);
+static int ixgbevf_dev_link_update(struct rte_eth_dev *dev,
+                                  int wait_to_complete);
 static void ixgbevf_dev_stop(struct rte_eth_dev *dev);
 static void ixgbevf_dev_close(struct rte_eth_dev *dev);
 static void ixgbevf_intr_disable(struct ixgbe_hw *hw);
@@ -619,7 +624,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
        .dev_configure        = ixgbevf_dev_configure,
        .dev_start            = ixgbevf_dev_start,
        .dev_stop             = ixgbevf_dev_stop,
-       .link_update          = ixgbe_dev_link_update,
+       .link_update          = ixgbevf_dev_link_update,
        .stats_get            = ixgbevf_dev_stats_get,
        .xstats_get           = ixgbevf_dev_xstats_get,
        .stats_reset          = ixgbevf_dev_stats_reset,
@@ -1959,9 +1964,10 @@ ixgbe_check_vf_rss_rxq_num(struct rte_eth_dev *dev, uint16_t nb_rx_q)
                return -EINVAL;
        }
 
-       RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool = nb_rx_q;
-       RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx = dev->pci_dev->max_vfs * nb_rx_q;
-
+       RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool =
+               IXGBE_MAX_RX_QUEUE_NUM / RTE_ETH_DEV_SRIOV(dev).active;
+       RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx =
+               dev->pci_dev->max_vfs * RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool;
        return 0;
 }
 
@@ -2001,8 +2007,6 @@ ixgbe_check_mq_mode(struct rte_eth_dev *dev)
                case ETH_MQ_RX_NONE:
                        /* if nothing mq mode configure, use default scheme */
                        dev->data->dev_conf.rxmode.mq_mode = ETH_MQ_RX_VMDQ_ONLY;
-                       if (RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool > 1)
-                               RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool = 1;
                        break;
                default: /* ETH_MQ_RX_DCB, ETH_MQ_RX_DCB_RSS or ETH_MQ_TX_DCB*/
                        /* SRIOV only works in VMDq enable mode */
@@ -3217,15 +3221,123 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
        dev_info->tx_desc_lim = tx_desc_lim;
 }
 
+static int
+ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
+                  int *link_up, int wait_to_complete)
+{
+       /**
+        * for a quick link status checking, wait_to_compelet == 0,
+        * skip PF link status checking
+        */
+       bool no_pflink_check = wait_to_complete == 0;
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       struct ixgbe_mac_info *mac = &hw->mac;
+       uint32_t links_reg, in_msg;
+       int ret_val = 0;
+
+       /* If we were hit with a reset drop the link */
+       if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout)
+               mac->get_link_status = true;
+
+       if (!mac->get_link_status)
+               goto out;
+
+       /* if link status is down no point in checking to see if pf is up */
+       links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
+       if (!(links_reg & IXGBE_LINKS_UP))
+               goto out;
+
+       /* for SFP+ modules and DA cables on 82599 it can take up to 500usecs
+        * before the link status is correct
+        */
+       if (mac->type == ixgbe_mac_82599_vf) {
+               int i;
+
+               for (i = 0; i < 5; i++) {
+                       rte_delay_us(100);
+                       links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
+
+                       if (!(links_reg & IXGBE_LINKS_UP))
+                               goto out;
+               }
+       }
+
+       switch (links_reg & IXGBE_LINKS_SPEED_82599) {
+       case IXGBE_LINKS_SPEED_10G_82599:
+               *speed = IXGBE_LINK_SPEED_10GB_FULL;
+               if (hw->mac.type >= ixgbe_mac_X550) {
+                       if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
+                               *speed = IXGBE_LINK_SPEED_2_5GB_FULL;
+               }
+               break;
+       case IXGBE_LINKS_SPEED_1G_82599:
+               *speed = IXGBE_LINK_SPEED_1GB_FULL;
+               break;
+       case IXGBE_LINKS_SPEED_100_82599:
+               *speed = IXGBE_LINK_SPEED_100_FULL;
+               if (hw->mac.type == ixgbe_mac_X550) {
+                       if (links_reg & IXGBE_LINKS_SPEED_NON_STD)
+                               *speed = IXGBE_LINK_SPEED_5GB_FULL;
+               }
+               break;
+       case IXGBE_LINKS_SPEED_10_X550EM_A:
+               *speed = IXGBE_LINK_SPEED_UNKNOWN;
+               /* Since Reserved in older MAC's */
+               if (hw->mac.type >= ixgbe_mac_X550)
+                       *speed = IXGBE_LINK_SPEED_10_FULL;
+               break;
+       default:
+               *speed = IXGBE_LINK_SPEED_UNKNOWN;
+       }
+
+       if (no_pflink_check) {
+               if (*speed == IXGBE_LINK_SPEED_UNKNOWN)
+                       mac->get_link_status = true;
+               else
+                       mac->get_link_status = false;
+
+               goto out;
+       }
+       /* if the read failed it could just be a mailbox collision, best wait
+        * until we are called again and don't report an error
+        */
+       if (mbx->ops.read(hw, &in_msg, 1, 0))
+               goto out;
+
+       if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) {
+               /* msg is not CTS and is NACK we must have lost CTS status */
+               if (in_msg & IXGBE_VT_MSGTYPE_NACK)
+                       ret_val = -1;
+               goto out;
+       }
+
+       /* the pf is talking, if we timed out in the past we reinit */
+       if (!mbx->timeout) {
+               ret_val = -1;
+               goto out;
+       }
+
+       /* if we passed all the tests above then the link is up and we no
+        * longer need to check for link
+        */
+       mac->get_link_status = false;
+
+out:
+       *link_up = !mac->get_link_status;
+       return ret_val;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
-ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
+                           int wait_to_complete, int vf)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct rte_eth_link link, old;
        ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
        int link_up;
        int diag;
+       int wait = 1;
 
        link.link_status = ETH_LINK_DOWN;
        link.link_speed = 0;
@@ -3238,9 +3350,12 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
 
        /* 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)
-               diag = ixgbe_check_link(hw, &link_speed, &link_up, 0);
+               wait = 0;
+
+       if (vf)
+               diag = ixgbevf_check_link(hw, &link_speed, &link_up, wait);
        else
-               diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
+               diag = ixgbe_check_link(hw, &link_speed, &link_up, wait);
 
        if (diag != 0) {
                link.link_speed = ETH_SPEED_NUM_100M;
@@ -3287,6 +3402,18 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
        return 0;
 }
 
+static int
+ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+       return ixgbe_dev_link_update_share(dev, wait_to_complete, 0);
+}
+
+static int
+ixgbevf_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+       return ixgbe_dev_link_update_share(dev, wait_to_complete, 1);
+}
+
 static void
 ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
@@ -4206,7 +4333,11 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
 
        PMD_INIT_FUNC_TRACE();
 
-       hw->mac.ops.reset_hw(hw);
+       err = hw->mac.ops.reset_hw(hw);
+       if (err) {
+               PMD_INIT_LOG(ERR, "Unable to reset vf hardware (%d)", err);
+               return err;
+       }
        hw->mac.get_link_status = true;
 
        /* negotiate mailbox API version to use with the PF. */
@@ -4233,7 +4364,8 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
        ixgbevf_dev_rxtx_start(dev);
 
        /* check and configure queue intr-vector mapping */
-       if (dev->data->dev_conf.intr_conf.rxq != 0) {
+       if (rte_intr_cap_multiple(intr_handle) &&
+           dev->data->dev_conf.intr_conf.rxq != 0) {
                intr_vector = dev->data->nb_rx_queues;
                if (rte_intr_efd_enable(intr_handle, intr_vector))
                        return -1;
@@ -7569,12 +7701,17 @@ static void ixgbevf_mbx_process(struct rte_eth_dev *dev)
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        u32 in_msg = 0;
 
-       if (ixgbe_read_mbx(hw, &in_msg, 1, 0))
-               return;
+       /* peek the message first */
+       in_msg = IXGBE_READ_REG(hw, IXGBE_VFMBMEM);
 
        /* PF reset VF event */
-       if (in_msg == IXGBE_PF_CONTROL_MSG)
-               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
+       if (in_msg == IXGBE_PF_CONTROL_MSG) {
+               /* dummy mbx read to ack pf */
+               if (ixgbe_read_mbx(hw, &in_msg, 1, 0))
+                       return;
+               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
+                                             NULL);
+       }
 }
 
 static int