X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fkeystone_net.c;h=209fae94a77b69cbea2426e25d786adc0bbfe3be;hb=192bc6948b02ff4168cab16162fffb507946dc2b;hp=13a1778298afa124f70a5717d931f4b52938ce1c;hpb=a4d2adee110d1534705d84c573a41e6d7877f0d7;p=u-boot diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c index 13a1778298..209fae94a7 100644 --- a/drivers/net/keystone_net.c +++ b/drivers/net/keystone_net.c @@ -8,9 +8,11 @@ */ #include #include +#include #include #include +#include #include #include #include @@ -30,6 +32,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); @@ -40,7 +43,9 @@ struct rx_buff_desc net_rx_buffs = { .rx_flow = 22, }; +#ifndef CONFIG_SOC_K2G static void keystone2_net_serdes_setup(void); +#endif int keystone2_eth_read_mac_addr(struct eth_device *dev) { @@ -159,17 +164,38 @@ static void __attribute__((unused)) DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + CPGMACSL_REG_CTL); } -int keystone_sgmii_link_status(int port) +#ifdef CONFIG_SOC_K2G +int keystone_rgmii_config(struct phy_device *phy_dev) { - u32 status = 0; + unsigned int i, status; + + i = 0; + do { + if (i > SGMII_ANEG_TIMEOUT) { + puts(" TIMEOUT !\n"); + phy_dev->link = 0; + return 0; + } - status = __raw_readl(SGMII_STATUS_REG(port)); + if (ctrlc()) { + puts("user interrupt!\n"); + phy_dev->link = 0; + return -EINTR; + } - return (status & SGMII_REG_STATUS_LOCK) && - (status & SGMII_REG_STATUS_LINK); -} + if ((i++ % 500) == 0) + printf("."); -int keystone_sgmii_config(int port, int interface) + udelay(1000); /* 1 ms */ + status = readl(RGMII_STATUS_REG); + } while (!(status & RGMII_REG_STATUS_LINK)); + + puts(" done\n"); + + return 0; +} +#else +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,14 +256,39 @@ 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; } +#endif int mac_sl_reset(u32 port) { @@ -289,6 +340,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); +#ifndef CONFIG_SOC_K2HK + /* Map RX packet flow priority to 0 */ + writel(0, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RX_PRI_MAP); +#endif + return ret; } @@ -367,10 +423,15 @@ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis) sys_has_mdio = (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0; - keystone2_net_serdes_setup(); + if (sys_has_mdio) + keystone2_mdio_reset(mdio_bus); - keystone_sgmii_config(eth_priv->slave_port - 1, +#ifdef CONFIG_SOC_K2G + keystone_rgmii_config(phy_dev); +#else + keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1, eth_priv->sgmii_link_type); +#endif udelay(10000); @@ -473,13 +534,20 @@ static int keystone2_eth_rcv_packet(struct eth_device *dev) if (hd == NULL) return 0; - NetReceive((uchar *)pkt, pkt_size); + net_process_received_packet((uchar *)pkt, pkt_size); ksnav_release_rxhd(&netcp_pktdma, hd); return pkt_size; } +#ifdef CONFIG_MCAST_TFTP +static int keystone2_eth_bcast_addr(struct eth_device *dev, u32 ip, u8 set) +{ + return 0; +} +#endif + /* * This function initializes the EMAC hardware. */ @@ -505,6 +573,9 @@ int keystone2_emac_initialize(struct eth_priv_t *eth_priv) dev->halt = keystone2_eth_close; dev->send = keystone2_eth_send_packet; dev->recv = keystone2_eth_rcv_packet; +#ifdef CONFIG_MCAST_TFTP + dev->mcast = keystone2_eth_bcast_addr; +#endif eth_register(dev); @@ -515,21 +586,25 @@ int keystone2_emac_initialize(struct eth_priv_t *eth_priv) mdio_bus->write = keystone2_mdio_write; mdio_bus->reset = keystone2_mdio_reset; mdio_bus->priv = (void *)EMAC_MDIO_BASE_ADDR; - sprintf(mdio_bus->name, "ethernet-mdio"); + strcpy(mdio_bus->name, "ethernet-mdio"); res = mdio_register(mdio_bus); if (res) return res; } +#ifndef CONFIG_SOC_K2G + keystone2_net_serdes_setup(); +#endif + /* Create phy device and bind it with driver */ #ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr, - dev, PHY_INTERFACE_MODE_SGMII); + dev, eth_priv->phy_if); phy_config(phy_dev); #else phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr, - PHY_INTERFACE_MODE_SGMII); + eth_priv->phy_if); phy_dev->dev = dev; #endif eth_priv->phy_dev = phy_dev; @@ -545,12 +620,20 @@ struct ks2_serdes ks2_serdes_sgmii_156p25mhz = { .loopback = 0, }; +#ifndef CONFIG_SOC_K2G static void keystone2_net_serdes_setup(void) { ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII_BASE, &ks2_serdes_sgmii_156p25mhz, CONFIG_KSNET_SERDES_LANES_PER_SGMII); +#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); +#endif + /* wait till setup */ udelay(5000); } +#endif