int keystone_sgmii_link_status(int port) { u32 status = 0; status = __raw_readl(SGMII_STATUS_REG(port)); return (status & SGMII_REG_STATUS_LOCK) && (status & SGMII_REG_STATUS_LINK); }
int keystone_sgmii_config(struct phy_device *phy_dev, int port, int interface) { unsigned int i, status, mask; unsigned int mr_adv_ability, control; switch (interface) { case SGMII_LINK_MAC_MAC_AUTONEG: mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | SGMII_REG_MR_ADV_LINK | SGMII_REG_MR_ADV_FULL_DUPLEX | SGMII_REG_MR_ADV_GIG_MODE); control = (SGMII_REG_CONTROL_MASTER | SGMII_REG_CONTROL_AUTONEG); break; case SGMII_LINK_MAC_PHY: case SGMII_LINK_MAC_PHY_FORCED: mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; control = SGMII_REG_CONTROL_AUTONEG; break; case SGMII_LINK_MAC_MAC_FORCED: mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | SGMII_REG_MR_ADV_LINK | SGMII_REG_MR_ADV_FULL_DUPLEX | SGMII_REG_MR_ADV_GIG_MODE); control = SGMII_REG_CONTROL_MASTER; break; case SGMII_LINK_MAC_FIBER: mr_adv_ability = 0x20; control = SGMII_REG_CONTROL_AUTONEG; break; default: mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; control = SGMII_REG_CONTROL_AUTONEG; } __raw_writel(0, SGMII_CTL_REG(port)); /* * Wait for the SerDes pll to lock, * but don't trap if lock is never read */ for (i = 0; i < 1000; i++) { udelay(2000); status = __raw_readl(SGMII_STATUS_REG(port)); if ((status & SGMII_REG_STATUS_LOCK) != 0) break; } __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port)); __raw_writel(control, SGMII_CTL_REG(port)); mask = SGMII_REG_STATUS_LINK; if (control & SGMII_REG_CONTROL_AUTONEG) mask |= SGMII_REG_STATUS_AUTONEG; status = __raw_readl(SGMII_STATUS_REG(port)); if ((status & mask) == mask) return 0; printf("\n%s Waiting for SGMII auto negotiation to complete", phy_dev->dev->name); while ((status & mask) != mask) { /* * Timeout reached ? */ if (i > SGMII_ANEG_TIMEOUT) { puts(" TIMEOUT !\n"); phy_dev->link = 0; return 0; } if (ctrlc()) { puts("user interrupt!\n"); phy_dev->link = 0; return -EINTR; } if ((i++ % 500) == 0) printf("."); udelay(1000); /* 1 ms */ status = __raw_readl(SGMII_STATUS_REG(port)); } puts(" done\n"); return 0; }