static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) { set_bit(XGBE_LINK_INIT, &pdata->dev_state); pdata->link_check = jiffies; if (pdata->phy.autoneg != AUTONEG_ENABLE) return xgbe_phy_config_fixed(pdata); netif_dbg(pdata, link, pdata->netdev, "AN PHY configuration\n"); /* Disable auto-negotiation interrupt */ disable_irq(pdata->an_irq); /* Start auto-negotiation in a supported mode */ if (pdata->phy.advertising & ADVERTISED_10000baseKR_Full) { xgbe_set_mode(pdata, XGBE_MODE_KR); } else if ((pdata->phy.advertising & ADVERTISED_1000baseKX_Full) || (pdata->phy.advertising & ADVERTISED_2500baseX_Full)) { xgbe_set_mode(pdata, XGBE_MODE_KX); } else { enable_irq(pdata->an_irq); return -EINVAL; } /* Disable and stop any in progress auto-negotiation */ xgbe_disable_an(pdata); /* Clear any auto-negotitation interrupts */ XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, 0); pdata->an_result = XGBE_AN_READY; pdata->an_state = XGBE_AN_READY; pdata->kr_state = XGBE_RX_BPA; pdata->kx_state = XGBE_RX_BPA; /* Re-enable auto-negotiation interrupt */ enable_irq(pdata->an_irq); /* Set up advertisement registers based on current settings */ xgbe_an_init(pdata); /* Enable and start auto-negotiation */ xgbe_restart_an(pdata); return 0; }
static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata) { int ret; set_bit(XGBE_LINK_INIT, &pdata->dev_state); pdata->link_check = jiffies; ret = pdata->phy_if.phy_impl.an_config(pdata); if (ret) return ret; if (pdata->phy.autoneg != AUTONEG_ENABLE) { ret = xgbe_phy_config_fixed(pdata); if (ret || !pdata->kr_redrv) return ret; netif_dbg(pdata, link, pdata->netdev, "AN redriver support\n"); } else { netif_dbg(pdata, link, pdata->netdev, "AN PHY configuration\n"); } /* Disable auto-negotiation interrupt */ disable_irq(pdata->an_irq); /* Start auto-negotiation in a supported mode */ if (xgbe_use_mode(pdata, XGBE_MODE_KR)) { xgbe_set_mode(pdata, XGBE_MODE_KR); } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_2500)) { xgbe_set_mode(pdata, XGBE_MODE_KX_2500); } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_1000)) { xgbe_set_mode(pdata, XGBE_MODE_KX_1000); } else if (xgbe_use_mode(pdata, XGBE_MODE_SFI)) { xgbe_set_mode(pdata, XGBE_MODE_SFI); } else if (xgbe_use_mode(pdata, XGBE_MODE_X)) { xgbe_set_mode(pdata, XGBE_MODE_X); } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_1000)) { xgbe_set_mode(pdata, XGBE_MODE_SGMII_1000); } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) { xgbe_set_mode(pdata, XGBE_MODE_SGMII_100); } else { enable_irq(pdata->an_irq); return -EINVAL; } /* Disable and stop any in progress auto-negotiation */ xgbe_an_disable_all(pdata); /* Clear any auto-negotitation interrupts */ xgbe_an_clear_interrupts_all(pdata); pdata->an_result = XGBE_AN_READY; pdata->an_state = XGBE_AN_READY; pdata->kr_state = XGBE_RX_BPA; pdata->kx_state = XGBE_RX_BPA; /* Re-enable auto-negotiation interrupt */ enable_irq(pdata->an_irq); xgbe_an_init(pdata); xgbe_an_restart(pdata); return 0; }