net/ixgbe/base: fix skipping PHY config
[dpdk.git] / drivers / net / ixgbe / base / ixgbe_common.c
index c01f919..8230ae1 100644 (file)
@@ -168,13 +168,24 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
        switch (hw->phy.media_type) {
        case ixgbe_media_type_fiber_qsfp:
        case ixgbe_media_type_fiber:
-               hw->mac.ops.check_link(hw, &speed, &link_up, false);
-               /* if link is down, assume supported */
-               if (link_up)
-                       supported = speed == IXGBE_LINK_SPEED_1GB_FULL ?
+               /* flow control autoneg black list */
+               switch (hw->device_id) {
+               case IXGBE_DEV_ID_X550EM_A_SFP:
+               case IXGBE_DEV_ID_X550EM_A_SFP_N:
+               case IXGBE_DEV_ID_X550EM_A_QSFP:
+               case IXGBE_DEV_ID_X550EM_A_QSFP_N:
+                       supported = false;
+                       break;
+               default:
+                       hw->mac.ops.check_link(hw, &speed, &link_up, false);
+                       /* if link is down, assume supported */
+                       if (link_up)
+                               supported = speed == IXGBE_LINK_SPEED_1GB_FULL ?
                                true : false;
-               else
-                       supported = true;
+                       else
+                               supported = true;
+               }
+
                break;
        case ixgbe_media_type_backplane:
                supported = true;
@@ -189,6 +200,8 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
                case IXGBE_DEV_ID_X550T1:
                case IXGBE_DEV_ID_X550EM_X_10G_T:
                case IXGBE_DEV_ID_X550EM_A_10G_T:
+               case IXGBE_DEV_ID_X550EM_A_1G_T:
+               case IXGBE_DEV_ID_X550EM_A_1G_T_L:
                        supported = true;
                        break;
                default:
@@ -198,9 +211,10 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
                break;
        }
 
-       ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED,
-                     "Device %x does not support flow control autoneg",
-                     hw->device_id);
+       if (!supported)
+               ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED,
+                             "Device %x does not support flow control autoneg",
+                             hw->device_id);
        return supported;
 }
 
@@ -395,8 +409,8 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
 
        /* Setup flow control */
        ret_val = ixgbe_setup_fc(hw);
-       if (ret_val != IXGBE_SUCCESS)
-               goto out;
+       if (ret_val != IXGBE_SUCCESS && ret_val != IXGBE_NOT_IMPLEMENTED)
+               return ret_val;
 
        /* Cache bit indicating need for crosstalk fix */
        switch (hw->mac.type) {
@@ -417,8 +431,7 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
        /* Clear adapter stopped flag */
        hw->adapter_stopped = false;
 
-out:
-       return ret_val;
+       return IXGBE_SUCCESS;
 }
 
 /**
@@ -4173,6 +4186,13 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
                                *speed = IXGBE_LINK_SPEED_5GB_FULL;
                }
                break;
+       case IXGBE_LINKS_SPEED_10_X550EM_A:
+               *speed = IXGBE_LINK_SPEED_UNKNOWN;
+               if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T ||
+                   hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) {
+                       *speed = IXGBE_LINK_SPEED_10_FULL;
+               }
+               break;
        default:
                *speed = IXGBE_LINK_SPEED_UNKNOWN;
        }
@@ -4404,43 +4424,31 @@ u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
 }
 
 /**
- *  ixgbe_host_interface_command - Issue command to manageability block
+ *  ixgbe_hic_unlocked - Issue command to manageability block unlocked
  *  @hw: pointer to the HW structure
- *  @buffer: contains the command to write and where the return status will
- *   be placed
+ *  @buffer: command to write and where the return status will be placed
  *  @length: length of buffer, must be multiple of 4 bytes
  *  @timeout: time in ms to wait for command completion
- *  @return_data: read and return data from the buffer (true) or not (false)
- *   Needed because FW structures are big endian and decoding of
- *   these fields can be 8 bit or 16 bit based on command. Decoding
- *   is not easily understood without making a table of commands.
- *   So we will leave this up to the caller to read back the data
- *   in these cases.
  *
  *  Communicates with the manageability block. On success return IXGBE_SUCCESS
  *  else returns semaphore error when encountering an error acquiring
  *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
+ *
+ *  This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held
+ *  by the caller.
  **/
-s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
-                                u32 length, u32 timeout, bool return_data)
+s32 ixgbe_hic_unlocked(struct ixgbe_hw *hw, u32 *buffer, u32 length,
+                      u32 timeout)
 {
-       u32 hicr, i, bi, fwsts;
-       u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
-       u16 buf_len;
+       u32 hicr, i, fwsts;
        u16 dword_len;
-       s32 status;
 
-       DEBUGFUNC("ixgbe_host_interface_command");
+       DEBUGFUNC("ixgbe_hic_unlocked");
 
-       if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
+       if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
                DEBUGOUT1("Buffer length failure buffersize=%d.\n", length);
                return IXGBE_ERR_HOST_INTERFACE_COMMAND;
        }
-       /* Take management host interface semaphore */
-       status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
-
-       if (status)
-               return status;
 
        /* Set bit 9 of FWSTS clearing FW reset indication */
        fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS);
@@ -4448,17 +4456,15 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
 
        /* Check that the host interface is enabled. */
        hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
-       if ((hicr & IXGBE_HICR_EN) == 0) {
+       if (!(hicr & IXGBE_HICR_EN)) {
                DEBUGOUT("IXGBE_HOST_EN bit disabled.\n");
-               status = IXGBE_ERR_HOST_INTERFACE_COMMAND;
-               goto rel_out;
+               return IXGBE_ERR_HOST_INTERFACE_COMMAND;
        }
 
        /* Calculate length in DWORDs. We must be DWORD aligned */
-       if ((length % (sizeof(u32))) != 0) {
+       if (length % sizeof(u32)) {
                DEBUGOUT("Buffer length failure, not aligned to dword");
-               status = IXGBE_ERR_INVALID_ARGUMENT;
-               goto rel_out;
+               return IXGBE_ERR_INVALID_ARGUMENT;
        }
 
        dword_len = length >> 2;
@@ -4481,14 +4487,59 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
        }
 
        /* Check command completion */
-       if ((timeout != 0 && i == timeout) ||
+       if ((timeout && i == timeout) ||
            !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) {
                ERROR_REPORT1(IXGBE_ERROR_CAUTION,
                             "Command has failed with no status valid.\n");
-               status = IXGBE_ERR_HOST_INTERFACE_COMMAND;
-               goto rel_out;
+               return IXGBE_ERR_HOST_INTERFACE_COMMAND;
        }
 
+       return IXGBE_SUCCESS;
+}
+
+/**
+ *  ixgbe_host_interface_command - Issue command to manageability block
+ *  @hw: pointer to the HW structure
+ *  @buffer: contains the command to write and where the return status will
+ *   be placed
+ *  @length: length of buffer, must be multiple of 4 bytes
+ *  @timeout: time in ms to wait for command completion
+ *  @return_data: read and return data from the buffer (true) or not (false)
+ *   Needed because FW structures are big endian and decoding of
+ *   these fields can be 8 bit or 16 bit based on command. Decoding
+ *   is not easily understood without making a table of commands.
+ *   So we will leave this up to the caller to read back the data
+ *   in these cases.
+ *
+ *  Communicates with the manageability block. On success return IXGBE_SUCCESS
+ *  else returns semaphore error when encountering an error acquiring
+ *  semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
+ **/
+s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
+                                u32 length, u32 timeout, bool return_data)
+{
+       u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
+       u16 dword_len;
+       u16 buf_len;
+       s32 status;
+       u32 bi;
+
+       DEBUGFUNC("ixgbe_host_interface_command");
+
+       if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
+               DEBUGOUT1("Buffer length failure buffersize=%d.\n", length);
+               return IXGBE_ERR_HOST_INTERFACE_COMMAND;
+       }
+
+       /* Take management host interface semaphore */
+       status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
+       if (status)
+               return status;
+
+       status = ixgbe_hic_unlocked(hw, buffer, length, timeout);
+       if (status)
+               goto rel_out;
+
        if (!return_data)
                goto rel_out;
 
@@ -4503,7 +4554,7 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
 
        /* If there is any thing in data position pull it in */
        buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len;
-       if (buf_len == 0)
+       if (!buf_len)
                goto rel_out;
 
        if (length < buf_len + hdr_size) {
@@ -5009,14 +5060,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                speedcnt++;
                highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
 
-               /* If we already have link at this speed, just jump out */
-               status = ixgbe_check_link(hw, &link_speed, &link_up, false);
-               if (status != IXGBE_SUCCESS)
-                       return status;
-
-               if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
-                       goto out;
-
                /* Set the module link speed */
                switch (hw->phy.media_type) {
                case ixgbe_media_type_fiber:
@@ -5067,14 +5110,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
                        highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
 
-               /* If we already have link at this speed, just jump out */
-               status = ixgbe_check_link(hw, &link_speed, &link_up, false);
-               if (status != IXGBE_SUCCESS)
-                       return status;
-
-               if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
-                       goto out;
-
                /* Set the module link speed */
                switch (hw->phy.media_type) {
                case ixgbe_media_type_fiber: