X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fnet%2Fkeystone_net.c;h=bedab1d606863494956c99eaca130b3357f57677;hb=cc0856cd149acc7069ae97ebe10b92090a65f575;hp=43c263e612e6dbaffbe3d94e49178a2bf2c7a438;hpb=3c61502aad85e8b25b75e349dfd5a5a7eee22301;p=u-boot diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c index 43c263e612..bedab1d606 100644 --- a/drivers/net/keystone_net.c +++ b/drivers/net/keystone_net.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,7 @@ static unsigned int sys_has_mdio = 1; #define RX_BUFF_NUMS 24 #define RX_BUFF_LEN 1520 #define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN +#define SGMII_ANEG_TIMEOUT 4000 static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16); @@ -169,7 +171,7 @@ int keystone_sgmii_link_status(int port) (status & SGMII_REG_STATUS_LINK); } -int keystone_sgmii_config(int port, int interface) +int keystone_sgmii_config(struct phy_device *phy_dev, int port, int interface) { unsigned int i, status, mask; unsigned int mr_adv_ability, control; @@ -230,11 +232,35 @@ int keystone_sgmii_config(int port, int interface) if (control & SGMII_REG_CONTROL_AUTONEG) mask |= SGMII_REG_STATUS_AUTONEG; - for (i = 0; i < 1000; i++) { + 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)); - if ((status & mask) == mask) - break; } + puts(" done\n"); return 0; } @@ -289,6 +315,11 @@ int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg) writel(cfg->max_rx_len, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN); writel(cfg->ctl, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL); +#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) + /* Map RX packet flow priority to 0 */ + writel(0, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RX_PRI_MAP); +#endif + return ret; } @@ -369,7 +400,10 @@ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis) keystone2_net_serdes_setup(); - keystone_sgmii_config(eth_priv->slave_port - 1, + if (sys_has_mdio) + keystone2_mdio_reset(mdio_bus); + + keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1, eth_priv->sgmii_link_type); udelay(10000); @@ -551,7 +585,7 @@ static void keystone2_net_serdes_setup(void) &ks2_serdes_sgmii_156p25mhz, CONFIG_KSNET_SERDES_LANES_PER_SGMII); -#ifdef CONFIG_SOC_K2E +#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII2_BASE, &ks2_serdes_sgmii_156p25mhz, CONFIG_KSNET_SERDES_LANES_PER_SGMII);