]> git.sur5r.net Git - u-boot/blobdiff - drivers/net/fm/eth.c
meson: odroid-c2: enable Ethernet support through the device tree
[u-boot] / drivers / net / fm / eth.c
index 8ecfd069cc4af7f1be50467b707aebd5bb4ab118..eb8e93618f27614aad40287f0ad794e2273c977b 100644 (file)
@@ -13,8 +13,8 @@
 #include <fsl_mdio.h>
 #include <miiphy.h>
 #include <phy.h>
-#include <asm/fsl_dtsec.h>
-#include <asm/fsl_tgec.h>
+#include <fsl_dtsec.h>
+#include <fsl_tgec.h>
 #include <fsl_memac.h>
 
 #include "fm.h"
@@ -41,28 +41,35 @@ static void dtsec_configure_serdes(struct fm_eth *priv)
        bus.priv = priv->mac->phyregs;
        bool sgmii_2500 = (priv->enet_if ==
                        PHY_INTERFACE_MODE_SGMII_2500) ? true : false;
+       int i = 0;
 
+qsgmii_loop:
        /* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */
        value = PHY_SGMII_IF_MODE_SGMII;
        if (!sgmii_2500)
                value |= PHY_SGMII_IF_MODE_AN;
 
-       memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x14, value);
+       memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x14, value);
 
        /* Dev ability according to SGMII specification */
        value = PHY_SGMII_DEV_ABILITY_SGMII;
-       memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x4, value);
+       memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x4, value);
 
        /* Adjust link timer for SGMII  -
        1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 */
-       memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x3);
-       memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0xd40);
+       memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x13, 0x3);
+       memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x12, 0xd40);
 
        /* Restart AN */
        value = PHY_SGMII_CR_DEF_VAL;
        if (!sgmii_2500)
                value |= PHY_SGMII_CR_RESET_AN;
-       memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0, value);
+       memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0, value);
+
+       if ((priv->enet_if == PHY_INTERFACE_MODE_QSGMII) && (i < 3)) {
+               i++;
+               goto qsgmii_loop;
+       }
 #else
        struct dtsec *regs = priv->mac->base;
        struct tsec_mii_mng *phyregs = priv->mac->phyregs;
@@ -91,10 +98,12 @@ static void dtsec_init_phy(struct eth_device *dev)
 #endif
 
        if (fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII ||
+           fm_eth->enet_if == PHY_INTERFACE_MODE_QSGMII ||
            fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII_2500)
                dtsec_configure_serdes(fm_eth);
 }
 
+#ifdef CONFIG_PHYLIB
 static int tgec_is_fibre(struct eth_device *dev)
 {
        struct fm_eth *fm = dev->priv;
@@ -105,6 +114,7 @@ static int tgec_is_fibre(struct eth_device *dev)
        return hwconfig_arg_cmp(phyopt, "xfi");
 }
 #endif
+#endif
 
 static u16 muram_readw(u16 *addr)
 {
@@ -211,7 +221,7 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth)
                FM_PRAM_SIZE, FM_PRAM_ALIGN);
        if (!pram) {
                printf("%s: No muram for Rx global parameter\n", __func__);
-               return 0;
+               return -ENOMEM;
        }
 
        fm_eth->rx_pram = pram;
@@ -232,14 +242,16 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth)
        rx_bd_ring_base = malloc(sizeof(struct fm_port_bd)
                        * RX_BD_RING_SIZE);
        if (!rx_bd_ring_base)
-               return 0;
+               return -ENOMEM;
+
        memset(rx_bd_ring_base, 0, sizeof(struct fm_port_bd)
                        * RX_BD_RING_SIZE);
 
        /* alloc Rx buffer from main memory */
        rx_buf_pool = malloc(MAX_RXBUF_LEN * RX_BD_RING_SIZE);
        if (!rx_buf_pool)
-               return 0;
+               return -ENOMEM;
+
        memset(rx_buf_pool, 0, MAX_RXBUF_LEN * RX_BD_RING_SIZE);
        debug("%s: rx_buf_pool = %p\n", __func__, rx_buf_pool);
 
@@ -277,7 +289,7 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth)
        /* set IM parameter ram pointer to Rx Frame Queue ID */
        out_be32(&bmi_rx_port->fmbm_rfqid, pram_page_offset);
 
-       return 1;
+       return 0;
 }
 
 static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth)
@@ -296,7 +308,7 @@ static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth)
                FM_PRAM_SIZE, FM_PRAM_ALIGN);
        if (!pram) {
                printf("%s: No muram for Tx global parameter\n", __func__);
-               return 0;
+               return -ENOMEM;
        }
        fm_eth->tx_pram = pram;
 
@@ -313,7 +325,8 @@ static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth)
        tx_bd_ring_base = malloc(sizeof(struct fm_port_bd)
                        * TX_BD_RING_SIZE);
        if (!tx_bd_ring_base)
-               return 0;
+               return -ENOMEM;
+
        memset(tx_bd_ring_base, 0, sizeof(struct fm_port_bd)
                        * TX_BD_RING_SIZE);
        /* save it to fm_eth */
@@ -344,29 +357,35 @@ static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth)
        /* set IM parameter ram pointer to Tx Confirmation Frame Queue ID */
        out_be32(&bmi_tx_port->fmbm_tcfqid, pram_page_offset);
 
-       return 1;
+       return 0;
 }
 
 static int fm_eth_init(struct fm_eth *fm_eth)
 {
+       int ret;
 
-       if (!fm_eth_rx_port_parameter_init(fm_eth))
-               return 0;
+       ret = fm_eth_rx_port_parameter_init(fm_eth);
+       if (ret)
+               return ret;
 
-       if (!fm_eth_tx_port_parameter_init(fm_eth))
-               return 0;
+       ret = fm_eth_tx_port_parameter_init(fm_eth);
+       if (ret)
+               return ret;
 
-       return 1;
+       return 0;
 }
 
 static int fm_eth_startup(struct fm_eth *fm_eth)
 {
        struct fsl_enet_mac *mac;
+       int ret;
+
        mac = fm_eth->mac;
 
        /* Rx/TxBDs, Rx/TxQDs, Rx buff and parameter ram init */
-       if (!fm_eth_init(fm_eth))
-               return 0;
+       ret = fm_eth_init(fm_eth);
+       if (ret)
+               return ret;
        /* setup the MAC controller */
        mac->init_mac(mac);
 
@@ -381,7 +400,7 @@ static int fm_eth_startup(struct fm_eth *fm_eth)
        /* init bmi tx port, IM mode and disable */
        bmi_tx_port_init(fm_eth->tx_port);
 
-       return 1;
+       return 0;
 }
 
 static void fmc_tx_port_graceful_stop_enable(struct fm_eth *fm_eth)
@@ -474,8 +493,10 @@ static void fm_eth_halt(struct eth_device *dev)
        /* disable bmi Rx port */
        bmi_rx_port_disable(fm_eth->rx_port);
 
+#ifdef CONFIG_PHYLIB
        if (fm_eth->phydev)
                phy_shutdown(fm_eth->phydev);
+#endif
 }
 
 static int fm_eth_send(struct eth_device *dev, void *buf, int len)
@@ -628,7 +649,7 @@ static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg)
        /* alloc mac controller */
        mac = malloc(sizeof(struct fsl_enet_mac));
        if (!mac)
-               return 0;
+               return -ENOMEM;
        memset(mac, 0, sizeof(struct fsl_enet_mac));
 
        /* save the mac to fm_eth struct */
@@ -643,19 +664,21 @@ static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg)
                init_tgec(mac, base, phyregs, MAX_RXBUF_LEN);
 #endif
 
-       return 1;
+       return 0;
 }
 
 static int init_phy(struct eth_device *dev)
 {
        struct fm_eth *fm_eth = dev->priv;
+#ifdef CONFIG_PHYLIB
        struct phy_device *phydev = NULL;
        u32 supported;
+#endif
 
-#ifdef CONFIG_PHYLIB
        if (fm_eth->type == FM_ETH_1G_E)
                dtsec_init_phy(dev);
 
+#ifdef CONFIG_PHYLIB
        if (fm_eth->bus) {
                phydev = phy_connect(fm_eth->bus, fm_eth->phyaddr, dev,
                                        fm_eth->enet_if);
@@ -696,17 +719,18 @@ int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info)
        struct eth_device *dev;
        struct fm_eth *fm_eth;
        int i, num = info->num;
+       int ret;
 
        /* alloc eth device */
        dev = (struct eth_device *)malloc(sizeof(struct eth_device));
        if (!dev)
-               return 0;
+               return -ENOMEM;
        memset(dev, 0, sizeof(struct eth_device));
 
        /* alloc the FMan ethernet private struct */
        fm_eth = (struct fm_eth *)malloc(sizeof(struct fm_eth));
        if (!fm_eth)
-               return 0;
+               return -ENOMEM;
        memset(fm_eth, 0, sizeof(struct fm_eth));
 
        /* save off some things we need from the info struct */
@@ -721,8 +745,9 @@ int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info)
        fm_eth->max_rx_len = MAX_RXBUF_LEN;
 
        /* init global mac structure */
-       if (!fm_eth_init_mac(fm_eth, reg))
-               return 0;
+       ret = fm_eth_init_mac(fm_eth, reg);
+       if (ret)
+               return ret;
 
        /* keep same as the manual, we call FMAN1, FMAN2, DTSEC1, DTSEC2, etc */
        if (fm_eth->type == FM_ETH_1G_E)
@@ -743,8 +768,9 @@ int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info)
        fm_eth->enet_if = info->enet_if;
 
        /* startup the FM im */
-       if (!fm_eth_startup(fm_eth))
-               return 0;
+       ret = fm_eth_startup(fm_eth);
+       if (ret)
+               return ret;
 
        init_phy(dev);
 
@@ -753,5 +779,5 @@ int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info)
                dev->enetaddr[i] = 0;
        eth_register(dev);
 
-       return 1;
+       return 0;
 }