*/
#include <common.h>
#include <command.h>
+#include <console.h>
#include <net.h>
#include <phy.h>
+#include <errno.h>
#include <miiphy.h>
#include <malloc.h>
#include <asm/ti-common/keystone_nav.h>
#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);
.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)
{
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;
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)
{
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;
}
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);
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.
*/
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);
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;
.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);
-#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);
/* wait till setup */
udelay(5000);
}
+#endif