]> git.sur5r.net Git - u-boot/blobdiff - drivers/net/keystone_net.c
Fix GCC format-security errors and convert sprintfs.
[u-boot] / drivers / net / keystone_net.c
index fa8e1ef3ce593e91b0bdb5ea9abd155131b5faa6..209fae94a77b69cbea2426e25d786adc0bbfe3be 100644 (file)
@@ -8,9 +8,11 @@
  */
 #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>
@@ -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,9 +43,9 @@ struct rx_buff_desc net_rx_buffs = {
        .rx_flow        = 22,
 };
 
+#ifndef CONFIG_SOC_K2G
 static void keystone2_net_serdes_setup(void);
-
-static int gen_get_link_speed(int phy_addr);
+#endif
 
 int keystone2_eth_read_mac_addr(struct eth_device *dev)
 {
@@ -137,19 +140,6 @@ static int keystone2_mdio_write(struct mii_dev *bus,
        return 0;
 }
 
-/* PHY functions for a generic PHY */
-static int gen_get_link_speed(int phy_addr)
-{
-       u_int16_t tmp;
-
-       tmp = mdio_bus->read(mdio_bus, phy_addr,
-                            MDIO_DEVAD_NONE, MII_STATUS_REG);
-       if (tmp & 0x04)
-               return 0;
-
-       return -1;
-}
-
 static void  __attribute__((unused))
        keystone2_eth_gigabit_enable(struct eth_device *dev)
 {
@@ -174,44 +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;
-
-       status = __raw_readl(SGMII_STATUS_REG(port));
-
-       return status & SGMII_REG_STATUS_LINK;
-}
+       unsigned int i, status;
+
+       i = 0;
+       do {
+               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;
+               }
 
-int keystone_get_link_status(struct eth_device *dev)
-{
-       struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
-       int sgmii_link;
-       int link_state = 0;
-#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
-       int j;
+               if ((i++ % 500) == 0)
+                       printf(".");
 
-       for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0);
-            j++) {
-#endif
-               sgmii_link =
-                       keystone_sgmii_link_status(eth_priv->slave_port - 1);
+               udelay(1000);   /* 1 ms */
+               status = readl(RGMII_STATUS_REG);
+       } while (!(status & RGMII_REG_STATUS_LINK));
 
-               if (sgmii_link) {
-                       link_state = 1;
+       puts(" done\n");
 
-                       if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY)
-                               if (gen_get_link_speed(eth_priv->phy_addr))
-                                       link_state = 0;
-               }
-#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
-       }
-#endif
-       return link_state;
+       return 0;
 }
-
-int keystone_sgmii_config(int port, int interface)
+#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;
@@ -272,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)
 {
@@ -331,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;
 }
 
@@ -409,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);
 
@@ -490,8 +509,10 @@ static int keystone2_eth_send_packet(struct eth_device *dev,
 {
        int ret_status = -1;
        struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+       struct phy_device *phy_dev = eth_priv->phy_dev;
 
-       if (keystone_get_link_status(dev) == 0)
+       genphy_update_link(phy_dev);
+       if (phy_dev->link == 0)
                return -1;
 
        if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0)
@@ -513,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.
  */
@@ -545,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);
 
@@ -555,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;
@@ -585,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