ixgbe/base: rework link negotiation
[dpdk.git] / lib / librte_pmd_ixgbe / ixgbe / ixgbe_vf.c
index caeb439..98fde8b 100644 (file)
@@ -477,8 +477,7 @@ s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
  *
  *  Set the link speed in the AUTOC register and restarts link.
  **/
-s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw,
-                           ixgbe_link_speed speed, bool autoneg,
+s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed,
                            bool autoneg_wait_to_complete)
 {
        UNREFERENCED_3PARAMETER(hw, speed, autoneg_wait_to_complete);
@@ -497,23 +496,26 @@ s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw,
 s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
                            bool *link_up, bool autoneg_wait_to_complete)
 {
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       struct ixgbe_mac_info *mac = &hw->mac;
+       s32 ret_val = IXGBE_SUCCESS;
        u32 links_reg;
+       u32 in_msg = 0;
        UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
 
-       if (!(hw->mbx.ops.check_for_rst(hw, 0))) {
-               *link_up = false;
-               *speed = 0;
-               return -1;
-       }
+       /* 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;
 
-       links_reg = IXGBE_VFREAD_REG(hw, IXGBE_VFLINKS);
+       if (!mac->get_link_status)
+               goto out;
 
-       if (links_reg & IXGBE_LINKS_UP)
-               *link_up = true;
-       else
-               *link_up = false;
+       /* 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;
 
-       switch (links_reg & IXGBE_LINKS_SPEED_10G_82599) {
+       switch (links_reg & IXGBE_LINKS_SPEED_82599) {
        case IXGBE_LINKS_SPEED_10G_82599:
                *speed = IXGBE_LINK_SPEED_10GB_FULL;
                break;
@@ -525,7 +527,33 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
                break;
        }
 
-       return IXGBE_SUCCESS;
+       /* 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;
 }
 
 /**