bool falcon_xaui_link_ok(struct efx_nic *efx) { efx_oword_t reg; bool align_done, link_ok = false; int sync_status; if (LOOPBACK_INTERNAL(efx)) return true; falcon_read(efx, ®, XX_CORE_STAT_REG); align_done = EFX_OWORD_FIELD(reg, XX_ALIGN_DONE); sync_status = EFX_OWORD_FIELD(reg, XX_SYNC_STAT); if (align_done && (sync_status == XX_SYNC_STAT_DECODE_SYNCED)) link_ok = true; EFX_SET_OWORD_FIELD(reg, XX_COMMA_DET, XX_COMMA_DET_RESET); EFX_SET_OWORD_FIELD(reg, XX_CHARERR, XX_CHARERR_RESET); EFX_SET_OWORD_FIELD(reg, XX_DISPERR, XX_DISPERR_RESET); falcon_write(efx, ®, XX_CORE_STAT_REG); if (efx->link_up && link_ok) if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS)) link_ok = efx_mdio_phyxgxs_lane_sync(efx); return link_ok; }
static bool falcon_xmac_link_ok(struct efx_nic *efx) { /* * Check MAC's XGXS link status except when using XGMII loopback * which bypasses the XGXS block. * If possible, check PHY's XGXS link status except when using * MAC loopback. */ return (efx->loopback_mode == LOOPBACK_XGMII || falcon_xgxs_link_ok(efx)) && (!(efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) || LOOPBACK_INTERNAL(efx) || efx_mdio_phyxgxs_lane_sync(efx)); }