int efx_mcdi_phy_reconfigure(struct efx_nic *efx) { struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; u32 caps = (efx->link_advertising ? ethtool_to_mcdi_cap(efx->link_advertising) : phy_cfg->forced_cap); return efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx), efx->loopback_mode, 0); }
static int efx_mcdi_phy_set_link_ksettings(struct efx_nic *efx, const struct ethtool_link_ksettings *cmd) { struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; u32 caps; int rc; u32 advertising; ethtool_convert_link_mode_to_legacy_u32(&advertising, cmd->link_modes.advertising); if (cmd->base.autoneg) { caps = (ethtool_to_mcdi_cap(advertising) | 1 << MC_CMD_PHY_CAP_AN_LBN); } else if (cmd->base.duplex) { switch (cmd->base.speed) { case 10: caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN; break; case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break; case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break; case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break; case 40000: caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN; break; default: return -EINVAL; } } else { switch (cmd->base.speed) { case 10: caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN; break; case 100: caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN; break; case 1000: caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN; break; default: return -EINVAL; } } rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx), efx->loopback_mode, 0); if (rc) return rc; if (cmd->base.autoneg) { efx_link_set_advertising( efx, advertising | ADVERTISED_Autoneg); phy_cfg->forced_cap = 0; } else { efx_link_set_advertising(efx, 0); phy_cfg->forced_cap = caps; } return 0; }
static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; u32 caps; int rc; if (ecmd->autoneg) { caps = (ethtool_to_mcdi_cap(ecmd->advertising) | 1 << MC_CMD_PHY_CAP_AN_LBN); } else if (ecmd->duplex) { switch (ethtool_cmd_speed(ecmd)) { case 10: caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN; break; case 100: caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN; break; case 1000: caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN; break; case 10000: caps = 1 << MC_CMD_PHY_CAP_10000FDX_LBN; break; case 40000: caps = 1 << MC_CMD_PHY_CAP_40000FDX_LBN; break; default: return -EINVAL; } } else { switch (ethtool_cmd_speed(ecmd)) { case 10: caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN; break; case 100: caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN; break; case 1000: caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN; break; default: return -EINVAL; } } rc = efx_mcdi_set_link(efx, caps, efx_get_mcdi_phy_flags(efx), efx->loopback_mode, 0); if (rc) return rc; if (ecmd->autoneg) { efx_link_set_advertising( efx, ecmd->advertising | ADVERTISED_Autoneg); phy_cfg->forced_cap = 0; } else { efx_link_set_advertising(efx, 0); phy_cfg->forced_cap = caps; } return 0; }