|
@@ -273,52 +273,28 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
|
|
case I40E_PHY_TYPE_40GBASE_AOC:
|
|
case I40E_PHY_TYPE_40GBASE_AOC:
|
|
ecmd->supported = SUPPORTED_40000baseCR4_Full;
|
|
ecmd->supported = SUPPORTED_40000baseCR4_Full;
|
|
break;
|
|
break;
|
|
- case I40E_PHY_TYPE_40GBASE_KR4:
|
|
|
|
- ecmd->supported = SUPPORTED_Autoneg |
|
|
|
|
- SUPPORTED_40000baseKR4_Full;
|
|
|
|
- ecmd->advertising = ADVERTISED_Autoneg |
|
|
|
|
- ADVERTISED_40000baseKR4_Full;
|
|
|
|
- break;
|
|
|
|
case I40E_PHY_TYPE_40GBASE_SR4:
|
|
case I40E_PHY_TYPE_40GBASE_SR4:
|
|
ecmd->supported = SUPPORTED_40000baseSR4_Full;
|
|
ecmd->supported = SUPPORTED_40000baseSR4_Full;
|
|
break;
|
|
break;
|
|
case I40E_PHY_TYPE_40GBASE_LR4:
|
|
case I40E_PHY_TYPE_40GBASE_LR4:
|
|
ecmd->supported = SUPPORTED_40000baseLR4_Full;
|
|
ecmd->supported = SUPPORTED_40000baseLR4_Full;
|
|
break;
|
|
break;
|
|
- case I40E_PHY_TYPE_20GBASE_KR2:
|
|
|
|
- ecmd->supported = SUPPORTED_Autoneg |
|
|
|
|
- SUPPORTED_20000baseKR2_Full;
|
|
|
|
- ecmd->advertising = ADVERTISED_Autoneg |
|
|
|
|
- ADVERTISED_20000baseKR2_Full;
|
|
|
|
- break;
|
|
|
|
- case I40E_PHY_TYPE_10GBASE_KX4:
|
|
|
|
- ecmd->supported = SUPPORTED_Autoneg |
|
|
|
|
- SUPPORTED_10000baseKX4_Full;
|
|
|
|
- ecmd->advertising = ADVERTISED_Autoneg |
|
|
|
|
- ADVERTISED_10000baseKX4_Full;
|
|
|
|
- break;
|
|
|
|
- case I40E_PHY_TYPE_10GBASE_KR:
|
|
|
|
- ecmd->supported = SUPPORTED_Autoneg |
|
|
|
|
- SUPPORTED_10000baseKR_Full;
|
|
|
|
- ecmd->advertising = ADVERTISED_Autoneg |
|
|
|
|
- ADVERTISED_10000baseKR_Full;
|
|
|
|
- break;
|
|
|
|
case I40E_PHY_TYPE_10GBASE_SR:
|
|
case I40E_PHY_TYPE_10GBASE_SR:
|
|
case I40E_PHY_TYPE_10GBASE_LR:
|
|
case I40E_PHY_TYPE_10GBASE_LR:
|
|
case I40E_PHY_TYPE_1000BASE_SX:
|
|
case I40E_PHY_TYPE_1000BASE_SX:
|
|
case I40E_PHY_TYPE_1000BASE_LX:
|
|
case I40E_PHY_TYPE_1000BASE_LX:
|
|
- ecmd->supported = SUPPORTED_10000baseT_Full |
|
|
|
|
- SUPPORTED_1000baseT_Full;
|
|
|
|
|
|
+ ecmd->supported = SUPPORTED_10000baseT_Full;
|
|
|
|
+ if (hw_link_info->module_type[2] &
|
|
|
|
+ I40E_MODULE_TYPE_1000BASE_SX ||
|
|
|
|
+ hw_link_info->module_type[2] &
|
|
|
|
+ I40E_MODULE_TYPE_1000BASE_LX) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_1000baseT_Full;
|
|
|
|
+ if (hw_link_info->requested_speeds &
|
|
|
|
+ I40E_LINK_SPEED_1GB)
|
|
|
|
+ ecmd->advertising |= ADVERTISED_1000baseT_Full;
|
|
|
|
+ }
|
|
if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
|
|
if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
|
|
ecmd->advertising |= ADVERTISED_10000baseT_Full;
|
|
ecmd->advertising |= ADVERTISED_10000baseT_Full;
|
|
- if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
|
|
|
|
- ecmd->advertising |= ADVERTISED_1000baseT_Full;
|
|
|
|
- break;
|
|
|
|
- case I40E_PHY_TYPE_1000BASE_KX:
|
|
|
|
- ecmd->supported = SUPPORTED_Autoneg |
|
|
|
|
- SUPPORTED_1000baseKX_Full;
|
|
|
|
- ecmd->advertising = ADVERTISED_Autoneg |
|
|
|
|
- ADVERTISED_1000baseKX_Full;
|
|
|
|
break;
|
|
break;
|
|
case I40E_PHY_TYPE_10GBASE_T:
|
|
case I40E_PHY_TYPE_10GBASE_T:
|
|
case I40E_PHY_TYPE_1000BASE_T:
|
|
case I40E_PHY_TYPE_1000BASE_T:
|
|
@@ -358,6 +334,15 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
|
|
if (hw_link_info->requested_speeds & I40E_LINK_SPEED_100MB)
|
|
if (hw_link_info->requested_speeds & I40E_LINK_SPEED_100MB)
|
|
ecmd->advertising |= ADVERTISED_100baseT_Full;
|
|
ecmd->advertising |= ADVERTISED_100baseT_Full;
|
|
break;
|
|
break;
|
|
|
|
+ /* Backplane is set based on supported phy types in get_settings
|
|
|
|
+ * so don't set anything here but don't warn either
|
|
|
|
+ */
|
|
|
|
+ case I40E_PHY_TYPE_40GBASE_KR4:
|
|
|
|
+ case I40E_PHY_TYPE_20GBASE_KR2:
|
|
|
|
+ case I40E_PHY_TYPE_10GBASE_KR:
|
|
|
|
+ case I40E_PHY_TYPE_10GBASE_KX4:
|
|
|
|
+ case I40E_PHY_TYPE_1000BASE_KX:
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
/* if we got here and link is up something bad is afoot */
|
|
/* if we got here and link is up something bad is afoot */
|
|
netdev_info(netdev, "WARNING: Link is up but PHY type 0x%x is not recognized.\n",
|
|
netdev_info(netdev, "WARNING: Link is up but PHY type 0x%x is not recognized.\n",
|
|
@@ -397,64 +382,67 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
|
|
static void i40e_get_settings_link_down(struct i40e_hw *hw,
|
|
static void i40e_get_settings_link_down(struct i40e_hw *hw,
|
|
struct ethtool_cmd *ecmd)
|
|
struct ethtool_cmd *ecmd)
|
|
{
|
|
{
|
|
- struct i40e_link_status *hw_link_info = &hw->phy.link_info;
|
|
|
|
|
|
+ enum i40e_aq_capabilities_phy_type phy_types = hw->phy.phy_types;
|
|
|
|
|
|
/* link is down and the driver needs to fall back on
|
|
/* link is down and the driver needs to fall back on
|
|
- * device ID to determine what kinds of info to display,
|
|
|
|
- * it's mostly a guess that may change when link is up
|
|
|
|
|
|
+ * supported phy types to figure out what info to display
|
|
*/
|
|
*/
|
|
- switch (hw->device_id) {
|
|
|
|
- case I40E_DEV_ID_QSFP_A:
|
|
|
|
- case I40E_DEV_ID_QSFP_B:
|
|
|
|
- case I40E_DEV_ID_QSFP_C:
|
|
|
|
- /* pluggable QSFP */
|
|
|
|
- ecmd->supported = SUPPORTED_40000baseSR4_Full |
|
|
|
|
- SUPPORTED_40000baseCR4_Full |
|
|
|
|
- SUPPORTED_40000baseLR4_Full;
|
|
|
|
- ecmd->advertising = ADVERTISED_40000baseSR4_Full |
|
|
|
|
- ADVERTISED_40000baseCR4_Full |
|
|
|
|
- ADVERTISED_40000baseLR4_Full;
|
|
|
|
- break;
|
|
|
|
- case I40E_DEV_ID_KX_B:
|
|
|
|
- /* backplane 40G */
|
|
|
|
- ecmd->supported = SUPPORTED_40000baseKR4_Full;
|
|
|
|
- ecmd->advertising = ADVERTISED_40000baseKR4_Full;
|
|
|
|
- break;
|
|
|
|
- case I40E_DEV_ID_KX_C:
|
|
|
|
- /* backplane 10G */
|
|
|
|
- ecmd->supported = SUPPORTED_10000baseKR_Full;
|
|
|
|
- ecmd->advertising = ADVERTISED_10000baseKR_Full;
|
|
|
|
- break;
|
|
|
|
- case I40E_DEV_ID_10G_BASE_T:
|
|
|
|
- case I40E_DEV_ID_10G_BASE_T4:
|
|
|
|
- ecmd->supported = SUPPORTED_10000baseT_Full |
|
|
|
|
- SUPPORTED_1000baseT_Full |
|
|
|
|
- SUPPORTED_100baseT_Full;
|
|
|
|
- /* Figure out what has been requested */
|
|
|
|
- if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
|
|
|
|
- ecmd->advertising |= ADVERTISED_10000baseT_Full;
|
|
|
|
- if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
|
|
|
|
- ecmd->advertising |= ADVERTISED_1000baseT_Full;
|
|
|
|
- if (hw_link_info->requested_speeds & I40E_LINK_SPEED_100MB)
|
|
|
|
- ecmd->advertising |= ADVERTISED_100baseT_Full;
|
|
|
|
- break;
|
|
|
|
- case I40E_DEV_ID_20G_KR2:
|
|
|
|
- case I40E_DEV_ID_20G_KR2_A:
|
|
|
|
- /* backplane 20G */
|
|
|
|
- ecmd->supported = SUPPORTED_20000baseKR2_Full;
|
|
|
|
- ecmd->advertising = ADVERTISED_20000baseKR2_Full;
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- /* all the rest are 10G/1G */
|
|
|
|
- ecmd->supported = SUPPORTED_10000baseT_Full |
|
|
|
|
- SUPPORTED_1000baseT_Full;
|
|
|
|
- /* Figure out what has been requested */
|
|
|
|
- if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
|
|
|
|
- ecmd->advertising |= ADVERTISED_10000baseT_Full;
|
|
|
|
- if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
|
|
|
|
- ecmd->advertising |= ADVERTISED_1000baseT_Full;
|
|
|
|
- break;
|
|
|
|
|
|
+ ecmd->supported = 0x0;
|
|
|
|
+ ecmd->advertising = 0x0;
|
|
|
|
+ if (phy_types & I40E_CAP_PHY_TYPE_SGMII) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_Autoneg |
|
|
|
|
+ SUPPORTED_1000baseT_Full |
|
|
|
|
+ SUPPORTED_100baseT_Full;
|
|
|
|
+ ecmd->advertising |= ADVERTISED_Autoneg |
|
|
|
|
+ ADVERTISED_1000baseT_Full |
|
|
|
|
+ ADVERTISED_100baseT_Full;
|
|
|
|
+ }
|
|
|
|
+ if (phy_types & I40E_CAP_PHY_TYPE_XAUI ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_XFI ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_SFI ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_10GBASE_AOC)
|
|
|
|
+ ecmd->supported |= SUPPORTED_10000baseT_Full;
|
|
|
|
+ if (phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1 ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_10GBASE_T ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_10GBASE_SR ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_10GBASE_LR) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_Autoneg |
|
|
|
|
+ SUPPORTED_10000baseT_Full;
|
|
|
|
+ ecmd->advertising |= ADVERTISED_Autoneg |
|
|
|
|
+ ADVERTISED_10000baseT_Full;
|
|
|
|
+ }
|
|
|
|
+ if (phy_types & I40E_CAP_PHY_TYPE_XLAUI ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_XLPPI ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_40GBASE_AOC)
|
|
|
|
+ ecmd->supported |= SUPPORTED_40000baseCR4_Full;
|
|
|
|
+ if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_CR4_CU ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_40GBASE_CR4) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_Autoneg |
|
|
|
|
+ SUPPORTED_40000baseCR4_Full;
|
|
|
|
+ ecmd->advertising |= ADVERTISED_Autoneg |
|
|
|
|
+ ADVERTISED_40000baseCR4_Full;
|
|
|
|
+ }
|
|
|
|
+ if (phy_types & I40E_CAP_PHY_TYPE_100BASE_TX) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_Autoneg |
|
|
|
|
+ SUPPORTED_100baseT_Full;
|
|
|
|
+ ecmd->advertising |= ADVERTISED_Autoneg |
|
|
|
|
+ ADVERTISED_100baseT_Full;
|
|
|
|
+ }
|
|
|
|
+ if (phy_types & I40E_CAP_PHY_TYPE_1000BASE_T ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_1000BASE_SX ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_1000BASE_LX ||
|
|
|
|
+ phy_types & I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_Autoneg |
|
|
|
|
+ SUPPORTED_1000baseT_Full;
|
|
|
|
+ ecmd->advertising |= ADVERTISED_Autoneg |
|
|
|
|
+ ADVERTISED_1000baseT_Full;
|
|
}
|
|
}
|
|
|
|
+ if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_SR4)
|
|
|
|
+ ecmd->supported |= SUPPORTED_40000baseSR4_Full;
|
|
|
|
+ if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_LR4)
|
|
|
|
+ ecmd->supported |= SUPPORTED_40000baseLR4_Full;
|
|
|
|
|
|
/* With no link speed and duplex are unknown */
|
|
/* With no link speed and duplex are unknown */
|
|
ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
|
|
ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
|
|
@@ -484,6 +472,37 @@ static int i40e_get_settings(struct net_device *netdev,
|
|
|
|
|
|
/* Now set the settings that don't rely on link being up/down */
|
|
/* Now set the settings that don't rely on link being up/down */
|
|
|
|
|
|
|
|
+ /* For backplane, supported and advertised are only reliant on the
|
|
|
|
+ * phy types the NVM specifies are supported.
|
|
|
|
+ */
|
|
|
|
+ if (hw->device_id == I40E_DEV_ID_KX_B ||
|
|
|
|
+ hw->device_id == I40E_DEV_ID_KX_C ||
|
|
|
|
+ hw->device_id == I40E_DEV_ID_20G_KR2 ||
|
|
|
|
+ hw->device_id == I40E_DEV_ID_20G_KR2_A) {
|
|
|
|
+ ecmd->supported = SUPPORTED_Autoneg;
|
|
|
|
+ ecmd->advertising = ADVERTISED_Autoneg;
|
|
|
|
+ if (hw->phy.phy_types & I40E_CAP_PHY_TYPE_40GBASE_KR4) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_40000baseKR4_Full;
|
|
|
|
+ ecmd->advertising |= ADVERTISED_40000baseKR4_Full;
|
|
|
|
+ }
|
|
|
|
+ if (hw->phy.phy_types & I40E_CAP_PHY_TYPE_20GBASE_KR2) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_20000baseKR2_Full;
|
|
|
|
+ ecmd->advertising |= ADVERTISED_20000baseKR2_Full;
|
|
|
|
+ }
|
|
|
|
+ if (hw->phy.phy_types & I40E_CAP_PHY_TYPE_10GBASE_KR) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_10000baseKR_Full;
|
|
|
|
+ ecmd->advertising |= ADVERTISED_10000baseKR_Full;
|
|
|
|
+ }
|
|
|
|
+ if (hw->phy.phy_types & I40E_CAP_PHY_TYPE_10GBASE_KX4) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_10000baseKX4_Full;
|
|
|
|
+ ecmd->advertising |= ADVERTISED_10000baseKX4_Full;
|
|
|
|
+ }
|
|
|
|
+ if (hw->phy.phy_types & I40E_CAP_PHY_TYPE_1000BASE_KX) {
|
|
|
|
+ ecmd->supported |= SUPPORTED_1000baseKX_Full;
|
|
|
|
+ ecmd->advertising |= ADVERTISED_1000baseKX_Full;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Set autoneg settings */
|
|
/* Set autoneg settings */
|
|
ecmd->autoneg = ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
|
|
ecmd->autoneg = ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
|
|
AUTONEG_ENABLE : AUTONEG_DISABLE);
|
|
AUTONEG_ENABLE : AUTONEG_DISABLE);
|
|
@@ -583,6 +602,14 @@ static int i40e_set_settings(struct net_device *netdev,
|
|
hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
|
|
hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
|
|
return -EOPNOTSUPP;
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
|
|
+ if (hw->device_id == I40E_DEV_ID_KX_B ||
|
|
|
|
+ hw->device_id == I40E_DEV_ID_KX_C ||
|
|
|
|
+ hw->device_id == I40E_DEV_ID_20G_KR2 ||
|
|
|
|
+ hw->device_id == I40E_DEV_ID_20G_KR2_A) {
|
|
|
|
+ netdev_info(netdev, "Changing settings is not supported on backplane.\n");
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* get our own copy of the bits to check against */
|
|
/* get our own copy of the bits to check against */
|
|
memset(&safe_ecmd, 0, sizeof(struct ethtool_cmd));
|
|
memset(&safe_ecmd, 0, sizeof(struct ethtool_cmd));
|
|
i40e_get_settings(netdev, &safe_ecmd);
|
|
i40e_get_settings(netdev, &safe_ecmd);
|
|
@@ -704,7 +731,7 @@ static int i40e_set_settings(struct net_device *netdev,
|
|
return -EAGAIN;
|
|
return -EAGAIN;
|
|
}
|
|
}
|
|
|
|
|
|
- status = i40e_aq_get_link_info(hw, true, NULL, NULL);
|
|
|
|
|
|
+ status = i40e_update_link_info(hw);
|
|
if (status)
|
|
if (status)
|
|
netdev_info(netdev, "Updating link info failed with err %s aq_err %s\n",
|
|
netdev_info(netdev, "Updating link info failed with err %s aq_err %s\n",
|
|
i40e_stat_str(hw, status),
|
|
i40e_stat_str(hw, status),
|