All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Álvaro Fernández Rojas" <noltari@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v5 08/15] net: add support for bcm6348-enet
Date: Thu, 8 Mar 2018 20:50:30 +0100	[thread overview]
Message-ID: <99bc7f9a-252d-25ea-e67e-a79c0c62c0f0@gmail.com> (raw)
In-Reply-To: <CANr=Z=ZOc_spDaga-sE7gUPTEea1qVieGjbR2NDr8BWgOJHTZQ@mail.gmail.com>

Hi Joe,

El 07/03/2018 a las 22:46, Joe Hershberger escribió:
> On Mon, Mar 5, 2018 at 2:05 PM, Álvaro Fernández Rojas
> <noltari@gmail.com> wrote:
>> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
>> ---
>>   v5: Receive as much packets as possible from bcm6348-eth and cache them in
>>   net_rx_packets. This is needed in order to fix flow control issues.
>>   v4: Fix issues reported by Grygorii Strashko and other fixes:
>>    - Copy received dma buffer to net_rx_packets in order to avoid possible
>>    dma overwrites.
>>    - Reset dma rx channel when sending a new packet to prevent flow control
>>    issues.
>>    - Fix packet casting on bcm6348_eth_recv/send.
>>   v3: no changes
>>   v2: select DMA_CHANNELS.
>>
>>   drivers/net/Kconfig            |  10 +
>>   drivers/net/Makefile           |   1 +
>>   drivers/net/bcm6348-eth.c      | 575 +++++++++++++++++++++++++++++++++++++++++
>>   include/configs/bmips_common.h |   5 +-
>>   4 files changed, 590 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/net/bcm6348-eth.c
>>
>> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
>> index de1947ccc1..e532332d78 100644
>> --- a/drivers/net/Kconfig
>> +++ b/drivers/net/Kconfig
>> @@ -71,6 +71,16 @@ config BCM_SF2_ETH_GMAC
>>            by the BCM_SF2_ETH driver.
>>            Say Y to any bcmcygnus based platforms.
>>
>> +config BCM6348_ETH
>> +       bool "BCM6348 EMAC support"
>> +       depends on DM_ETH && ARCH_BMIPS
>> +       select DMA
>> +       select DMA_CHANNELS
>> +       select MII
>> +       select PHYLIB
>> +       help
>> +         This driver supports the BCM6348 Ethernet MAC.
>> +
>>   config DWC_ETH_QOS
>>          bool "Synopsys DWC Ethernet QOS device support"
>>          depends on DM_ETH
>> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
>> index ac5443c752..282adbc775 100644
>> --- a/drivers/net/Makefile
>> +++ b/drivers/net/Makefile
>> @@ -8,6 +8,7 @@
>>   obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
>>   obj-$(CONFIG_AG7XXX) += ag7xxx.o
>>   obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o
>> +obj-$(CONFIG_BCM6348_ETH) += bcm6348-eth.o
>>   obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
>>   obj-$(CONFIG_DRIVER_AX88180) += ax88180.o
>>   obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o
>> diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c
>> new file mode 100644
>> index 0000000000..43518f7b2d
>> --- /dev/null
>> +++ b/drivers/net/bcm6348-eth.c
>> @@ -0,0 +1,575 @@
>> +/*
>> + * Copyright (C) 2018 Álvaro Fernández Rojas <noltari@gmail.com>
>> + *
>> + * Derived from linux/drivers/net/ethernet/broadcom/bcm63xx_enet.c:
>> + *     Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <clk.h>
>> +#include <dm.h>
>> +#include <dma.h>
>> +#include <miiphy.h>
>> +#include <net.h>
>> +#include <phy.h>
>> +#include <reset.h>
>> +#include <wait_bit.h>
>> +#include <asm/io.h>
>> +
>> +#define ETH_RX_DESC                    PKTBUFSRX
>> +#define ETH_MAX_MTU_SIZE               1518
>> +#define ETH_TIMEOUT                    100
>> +#define ETH_TX_WATERMARK               32
>> +
>> +/* ETH Receiver Configuration register */
>> +#define ETH_RXCFG_REG                  0x00
>> +#define ETH_RXCFG_ENFLOW_SHIFT         5
>> +#define ETH_RXCFG_ENFLOW_MASK          (1 << ETH_RXCFG_ENFLOW_SHIFT)
>> +
>> +/* ETH Receive Maximum Length register */
>> +#define ETH_RXMAXLEN_REG               0x04
>> +#define ETH_RXMAXLEN_SHIFT             0
>> +#define ETH_RXMAXLEN_MASK              (0x7ff << ETH_RXMAXLEN_SHIFT)
>> +
>> +/* ETH Transmit Maximum Length register */
>> +#define ETH_TXMAXLEN_REG               0x08
>> +#define ETH_TXMAXLEN_SHIFT             0
>> +#define ETH_TXMAXLEN_MASK              (0x7ff << ETH_TXMAXLEN_SHIFT)
>> +
>> +/* MII Status/Control register */
>> +#define MII_SC_REG                     0x10
>> +#define MII_SC_MDCFREQDIV_SHIFT                0
>> +#define MII_SC_MDCFREQDIV_MASK         (0x7f << MII_SC_MDCFREQDIV_SHIFT)
>> +#define MII_SC_PREAMBLE_EN_SHIFT       7
>> +#define MII_SC_PREAMBLE_EN_MASK                (1 << MII_SC_PREAMBLE_EN_SHIFT)
>> +
>> +/* MII Data register */
>> +#define MII_DAT_REG                    0x14
>> +#define MII_DAT_DATA_SHIFT             0
>> +#define MII_DAT_DATA_MASK              (0xffff << MII_DAT_DATA_SHIFT)
>> +#define MII_DAT_TA_SHIFT               16
>> +#define MII_DAT_TA_MASK                        (0x3 << MII_DAT_TA_SHIFT)
>> +#define MII_DAT_REG_SHIFT              18
>> +#define MII_DAT_REG_MASK               (0x1f << MII_DAT_REG_SHIFT)
>> +#define MII_DAT_PHY_SHIFT              23
>> +#define MII_DAT_PHY_MASK               (0x1f << MII_DAT_PHY_SHIFT)
>> +#define MII_DAT_OP_SHIFT               28
>> +#define MII_DAT_OP_WRITE               (0x5 << MII_DAT_OP_SHIFT)
>> +#define MII_DAT_OP_READ                        (0x6 << MII_DAT_OP_SHIFT)
>> +
>> +/* ETH Interrupts Mask register */
>> +#define ETH_IRMASK_REG                 0x18
>> +
>> +/* ETH Interrupts register */
>> +#define ETH_IR_REG                     0x1c
>> +#define ETH_IR_MII_SHIFT               0
>> +#define ETH_IR_MII_MASK                        (1 << ETH_IR_MII_SHIFT)
>> +
>> +/* ETH Control register */
>> +#define ETH_CTL_REG                    0x2c
>> +#define ETH_CTL_ENABLE_SHIFT           0
>> +#define ETH_CTL_ENABLE_MASK            (1 << ETH_CTL_ENABLE_SHIFT)
>> +#define ETH_CTL_DISABLE_SHIFT          1
>> +#define ETH_CTL_DISABLE_MASK           (1 << ETH_CTL_DISABLE_SHIFT)
>> +#define ETH_CTL_RESET_SHIFT            2
>> +#define ETH_CTL_RESET_MASK             (1 << ETH_CTL_RESET_SHIFT)
>> +#define ETH_CTL_EPHY_SHIFT             3
>> +#define ETH_CTL_EPHY_MASK              (1 << ETH_CTL_EPHY_SHIFT)
>> +
>> +/* ETH Transmit Control register */
>> +#define ETH_TXCTL_REG                  0x30
>> +#define ETH_TXCTL_FD_SHIFT             0
>> +#define ETH_TXCTL_FD_MASK              (1 << ETH_TXCTL_FD_SHIFT)
>> +
>> +/* ETH Transmit Watermask register */
>> +#define ETH_TXWMARK_REG                        0x34
>> +#define ETH_TXWMARK_WM_SHIFT           0
>> +#define ETH_TXWMARK_WM_MASK            (0x3f << ETH_TXWMARK_WM_SHIFT)
>> +
>> +/* MIB Control register */
>> +#define MIB_CTL_REG                    0x38
>> +#define MIB_CTL_RDCLEAR_SHIFT          0
>> +#define MIB_CTL_RDCLEAR_MASK           (1 << MIB_CTL_RDCLEAR_SHIFT)
>> +
>> +/* ETH Perfect Match registers */
>> +#define ETH_PM_CNT                     4
>> +#define ETH_PML_REG(x)                 (0x58 + (x) * 0x8)
>> +#define ETH_PMH_REG(x)                 (0x5c + (x) * 0x8)
>> +#define ETH_PMH_VALID_SHIFT            16
>> +#define ETH_PMH_VALID_MASK             (1 << ETH_PMH_VALID_SHIFT)
>> +
>> +/* MIB Counters registers */
>> +#define MIB_REG_CNT                    55
>> +#define MIB_REG(x)                     (0x200 + (x) * 4)
>> +
>> +/* ETH data */
>> +struct bcm6348_eth_priv {
>> +       void __iomem *base;
>> +       /* RX */
>> +       uint8_t rx_desc;
>> +       uint8_t rx_pend;
>> +       int rx_ret[ETH_RX_DESC];
>> +       /* DMA */
>> +       struct dma rx_dma;
>> +       struct dma tx_dma;
>> +       /* PHY */
>> +       int phy_id;
>> +       struct phy_device *phy_dev;
>> +};
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +static void bcm6348_eth_mac_disable(struct bcm6348_eth_priv *priv)
>> +{
>> +       /* disable emac */
>> +       clrsetbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_ENABLE_MASK,
>> +                       ETH_CTL_DISABLE_MASK);
>> +
>> +       /* wait until emac is disabled */
>> +       if (wait_for_bit_be32(priv->base + ETH_CTL_REG,
>> +                             ETH_CTL_DISABLE_MASK, false,
>> +                             ETH_TIMEOUT, false))
>> +               pr_err("error disabling emac\n");
>> +}
>> +
>> +static void bcm6348_eth_mac_enable(struct bcm6348_eth_priv *priv)
>> +{
>> +       setbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_ENABLE_MASK);
>> +}
>> +
>> +static void bcm6348_eth_mac_reset(struct bcm6348_eth_priv *priv)
>> +{
>> +       /* reset emac */
>> +       writel_be(ETH_CTL_RESET_MASK, priv->base + ETH_CTL_REG);
>> +       wmb();
>> +
>> +       /* wait until emac is reset */
>> +       if (wait_for_bit_be32(priv->base + ETH_CTL_REG,
>> +                             ETH_CTL_RESET_MASK, false,
>> +                             ETH_TIMEOUT, false))
>> +               pr_err("error resetting emac\n");
>> +}
>> +
>> +static int bcm6348_eth_free_pkt(struct udevice *dev, uchar *packet, int len)
>> +{
>> +       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
>> +
>> +       /* sanity check */
>> +       if (packet != net_rx_packets[priv->rx_pend]) {
>> +               pr_err("rx_pend %d: packet is not matched,\n", priv->rx_pend);
>> +               return -EAGAIN;
>> +       }
>> +
>> +       /* free pending packet */
>> +       priv->rx_ret[priv->rx_pend] = 0;
>> +       priv->rx_pend = (priv->rx_pend + 1) % ETH_RX_DESC;
>> +
>> +       return 0;
>> +}
>> +
>> +static int _bcm6348_eth_recv(struct bcm6348_eth_priv *priv)
>> +{
>> +       uint8_t pkt = priv->rx_desc;
>> +
>> +       /* check if packet is free */
>> +       if (priv->rx_ret[pkt] > 0)
>> +               return -EAGAIN;
>> +
>> +       /* try to receive a new packet */
>> +       priv->rx_ret[pkt] = dma_receive(&priv->rx_dma,
>> +                                       (void **)&net_rx_packets[pkt]);
>> +       if (priv->rx_ret[pkt] > 0)
>> +               priv->rx_desc = (priv->rx_desc + 1) % ETH_RX_DESC;
>> +
>> +       return priv->rx_ret[pkt];
>> +}
>> +
>> +static int bcm6348_eth_recv(struct udevice *dev, int flags, uchar **packetp)
>> +{
>> +       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
>> +       uint8_t pkt_cnt = 0;
>> +       int ret;
>> +
>> +       /* try to receive packets */
>> +       while (_bcm6348_eth_recv(priv) > 0)
>> +               pkt_cnt++;
>> +
>> +       if (pkt_cnt)
>> +               debug("%s: received %u packet(s)\n", __func__, pkt_cnt);
>> +
>> +       /* return current packet */
>> +       ret = priv->rx_ret[priv->rx_pend];
>> +       if (ret > 0)
>> +               *packetp = net_rx_packets[priv->rx_pend];
>> +
>> +       return ret;
>> +}
>> +
>> +static int bcm6348_eth_send(struct udevice *dev, void *packet, int length)
>> +{
>> +       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
>> +
>> +       /* reset dma rx channel */
>> +       dma_disable(&priv->rx_dma);
>> +       dma_enable(&priv->rx_dma);
> Why. Please include reasoning in the comment.
For what I've seen flow control is a bit tricky on this dma controller 
and when you don't process a received packet in a short period of time, 
it may get into a an state where no new packets are correctly received.
However, resetting the dma channel here prevents that from hapenning.
>
>> +
>> +       return dma_send(&priv->tx_dma, (void *)packet, length);
>> +}
>> +
>> +static int bcm6348_eth_adjust_link(struct udevice *dev,
>> +                                  struct phy_device *phydev)
>> +{
>> +       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
>> +
>> +       /* mac duplex parameters */
>> +       if (phydev->duplex)
>> +               setbits_be32(priv->base + ETH_TXCTL_REG, ETH_TXCTL_FD_MASK);
>> +       else
>> +               clrbits_be32(priv->base + ETH_TXCTL_REG, ETH_TXCTL_FD_MASK);
>> +
>> +       /* rx flow control (pause frame handling) */
>> +       if (phydev->pause)
>> +               setbits_be32(priv->base + ETH_RXCFG_REG,
>> +                            ETH_RXCFG_ENFLOW_MASK);
>> +       else
>> +               clrbits_be32(priv->base + ETH_RXCFG_REG,
>> +                            ETH_RXCFG_ENFLOW_MASK);
>> +
>> +       return 0;
>> +}
>> +
>> +static int bcm6348_eth_start(struct udevice *dev)
>> +{
>> +       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
>> +       int ret, i;
>> +
>> +       priv->rx_desc = 0;
>> +       priv->rx_pend = 0;
>> +       for (i = 0; i < ETH_RX_DESC; i++)
>> +               priv->rx_ret[i] = 0;
>> +
>> +       /* enable dma rx channel */
>> +       dma_enable(&priv->rx_dma);
>> +
>> +       /* enable dma tx channel */
>> +       dma_enable(&priv->tx_dma);
>> +
>> +       ret = phy_startup(priv->phy_dev);
>> +       if (ret) {
>> +               pr_err("could not initialize phy\n");
>> +               return ret;
>> +       }
>> +
>> +       if (!priv->phy_dev->link) {
>> +               pr_err("no phy link\n");
>> +               return -EIO;
>> +       }
>> +
>> +       bcm6348_eth_adjust_link(dev, priv->phy_dev);
>> +
>> +       /* zero mib counters */
>> +       for (i = 0; i < MIB_REG_CNT; i++)
>> +               writel_be(0, MIB_REG(i));
>> +
>> +       /* enable rx flow control */
>> +       setbits_be32(priv->base + ETH_RXCFG_REG, ETH_RXCFG_ENFLOW_MASK);
>> +
>> +       /* set max rx/tx length */
>> +       writel_be((ETH_MAX_MTU_SIZE << ETH_RXMAXLEN_SHIFT) &
>> +                 ETH_RXMAXLEN_MASK, priv->base + ETH_RXMAXLEN_REG);
>> +       writel_be((ETH_MAX_MTU_SIZE << ETH_TXMAXLEN_SHIFT) &
>> +                  ETH_TXMAXLEN_MASK, priv->base + ETH_TXMAXLEN_REG);
>> +
>> +       /* set correct transmit fifo watermark */
>> +       writel_be((ETH_TX_WATERMARK << ETH_TXWMARK_WM_SHIFT) &
>> +                 ETH_TXWMARK_WM_MASK, priv->base + ETH_TXWMARK_REG);
>> +
>> +       /* enable emac */
>> +       bcm6348_eth_mac_enable(priv);
>> +
>> +       /* clear interrupts */
>> +       writel_be(0, priv->base + ETH_IRMASK_REG);
>> +
>> +       return 0;
>> +}
>> +
>> +static void bcm6348_eth_stop(struct udevice *dev)
>> +{
>> +       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
>> +
>> +       /* disable dma rx channel */
>> +       dma_disable(&priv->rx_dma);
>> +
>> +       /* disable dma tx channel */
>> +       dma_disable(&priv->tx_dma);
>> +
>> +       /* disable emac */
>> +       bcm6348_eth_mac_disable(priv);
>> +}
>> +
>> +static int bcm6348_eth_write_hwaddr(struct udevice *dev)
>> +{
>> +       struct eth_pdata *pdata = dev_get_platdata(dev);
>> +       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
>> +       bool running = false;
>> +
>> +       /* check if emac is running */
>> +       if (readl_be(priv->base + ETH_CTL_REG) & ETH_CTL_ENABLE_MASK)
>> +               running = true;
>> +
>> +       /* disable emac */
>> +       if (running)
>> +               bcm6348_eth_mac_disable(priv);
>> +
>> +       /* set mac address */
>> +       writel_be((pdata->enetaddr[2] << 24) | (pdata->enetaddr[3]) << 16 |
>> +                 (pdata->enetaddr[4]) << 8 | (pdata->enetaddr[5]),
>> +                 priv->base + ETH_PML_REG(0));
>> +       writel_be((pdata->enetaddr[1]) | (pdata->enetaddr[0] << 8) |
>> +                 ETH_PMH_VALID_MASK, priv->base + ETH_PMH_REG(0));
>> +
>> +       /* enable emac */
>> +       if (running)
>> +               bcm6348_eth_mac_enable(priv);
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct eth_ops bcm6348_eth_ops = {
>> +       .free_pkt = bcm6348_eth_free_pkt,
>> +       .recv = bcm6348_eth_recv,
>> +       .send = bcm6348_eth_send,
>> +       .start = bcm6348_eth_start,
>> +       .stop = bcm6348_eth_stop,
>> +       .write_hwaddr = bcm6348_eth_write_hwaddr,
>> +};
>> +
>> +static const struct udevice_id bcm6348_eth_ids[] = {
>> +       { .compatible = "brcm,bcm6348-enet", },
>> +       { /* sentinel */ }
>> +};
>> +
>> +static int bcm6348_mdio_op(void __iomem *base, uint32_t data)
>> +{
>> +       /* make sure mii interrupt status is cleared */
>> +       writel_be(ETH_IR_MII_MASK, base + ETH_IR_REG);
>> +
>> +       /* issue mii op */
>> +       writel_be(data, base + MII_DAT_REG);
>> +
>> +       /* wait until emac is disabled */
>> +       return wait_for_bit_be32(base + ETH_IR_REG,
>> +                                ETH_IR_MII_MASK, true,
>> +                                ETH_TIMEOUT, false);
>> +}
>> +
>> +static int bcm6348_mdio_read(struct mii_dev *bus, int addr, int devaddr,
>> +                            int reg)
>> +{
>> +       void __iomem *base = bus->priv;
>> +       uint32_t val;
>> +
>> +       val = MII_DAT_OP_READ;
>> +       val |= (reg << MII_DAT_REG_SHIFT) & MII_DAT_REG_MASK;
>> +       val |= (0x2 << MII_DAT_TA_SHIFT) & MII_DAT_TA_MASK;
>> +       val |= (addr << MII_DAT_PHY_SHIFT) & MII_DAT_PHY_MASK;
>> +
>> +       if (bcm6348_mdio_op(base, val)) {
>> +               pr_err("%s: timeout\n", __func__);
>> +               return -EINVAL;
>> +       }
>> +
>> +       val = readl_be(base + MII_DAT_REG) & MII_DAT_DATA_MASK;
>> +       val >>= MII_DAT_DATA_SHIFT;
>> +
>> +       return val;
>> +}
>> +
>> +static int bcm6348_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
>> +                             int reg, u16 value)
>> +{
>> +       void __iomem *base = bus->priv;
>> +       uint32_t val;
>> +
>> +       val = MII_DAT_OP_WRITE;
>> +       val |= (reg << MII_DAT_REG_SHIFT) & MII_DAT_REG_MASK;
>> +       val |= (0x2 << MII_DAT_TA_SHIFT) & MII_DAT_TA_MASK;
>> +       val |= (addr << MII_DAT_PHY_SHIFT) & MII_DAT_PHY_MASK;
>> +       val |= (value << MII_DAT_DATA_SHIFT) & MII_DAT_DATA_MASK;
>> +
>> +       if (bcm6348_mdio_op(base, val)) {
>> +               pr_err("%s: timeout\n", __func__);
>> +               return -EINVAL;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int bcm6348_mdio_init(const char *name, void __iomem *base)
>> +{
>> +       struct mii_dev *bus;
>> +
>> +       bus = mdio_alloc();
>> +       if (!bus) {
>> +               pr_err("%s: failed to allocate MDIO bus\n", __func__);
>> +               return -ENOMEM;
>> +       }
>> +
>> +       bus->read = bcm6348_mdio_read;
>> +       bus->write = bcm6348_mdio_write;
>> +       bus->priv = base;
>> +       snprintf(bus->name, sizeof(bus->name), "%s", name);
>> +
>> +       return mdio_register(bus);
>> +}
>> +
>> +static int bcm6348_phy_init(struct udevice *dev)
>> +{
>> +       struct eth_pdata *pdata = dev_get_platdata(dev);
>> +       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
>> +       struct mii_dev *bus;
>> +
>> +       /* get mii bus */
>> +       bus = miiphy_get_dev_by_name(dev->name);
>> +
>> +       /* phy connect */
>> +       priv->phy_dev = phy_connect(bus, priv->phy_id, dev,
>> +                                   pdata->phy_interface);
>> +       if (!priv->phy_dev) {
>> +               pr_err("%s: no phy device\n", __func__);
>> +               return -ENODEV;
>> +       }
>> +
>> +       priv->phy_dev->supported = (SUPPORTED_10baseT_Half |
>> +                                   SUPPORTED_10baseT_Full |
>> +                                   SUPPORTED_100baseT_Half |
>> +                                   SUPPORTED_100baseT_Full |
>> +                                   SUPPORTED_Autoneg |
>> +                                   SUPPORTED_Pause |
>> +                                   SUPPORTED_MII);
>> +       priv->phy_dev->advertising = priv->phy_dev->supported;
>> +
>> +       /* phy config */
>> +       phy_config(priv->phy_dev);
>> +
>> +       return 0;
>> +}
>> +
>> +static int bcm6348_eth_probe(struct udevice *dev)
>> +{
>> +       struct eth_pdata *pdata = dev_get_platdata(dev);
>> +       struct bcm6348_eth_priv *priv = dev_get_priv(dev);
>> +       void *blob = (void *)gd->fdt_blob;
>> +       int node = dev_of_offset(dev);
>> +       const char *phy_mode;
>> +       fdt_addr_t addr;
>> +       int phy_node, ret, i;
>> +
>> +       /* get base address */
>> +       addr = devfdt_get_addr(dev);
>> +       if (addr == FDT_ADDR_T_NONE)
>> +               return -EINVAL;
>> +
>> +       /* get phy mode */
>> +       pdata->phy_interface = PHY_INTERFACE_MODE_NONE;
>> +       phy_mode = fdt_getprop(blob, node, "phy-mode", NULL);
>> +       if (phy_mode)
>> +               pdata->phy_interface = phy_get_interface_by_name(phy_mode);
>> +       if (pdata->phy_interface == PHY_INTERFACE_MODE_NONE)
>> +               return -ENODEV;
>> +
>> +       /* get phy */
>> +       phy_node = fdtdec_lookup_phandle(blob, node, "phy");
>> +       if (phy_node >= 0)
>> +               priv->phy_id = fdtdec_get_int(blob, phy_node, "reg", -1);
>> +       else
>> +               return -EINVAL;
>> +
>> +       /* get dma channels */
>> +       ret = dma_get_by_name(dev, "tx", &priv->tx_dma);
>> +       if (ret)
>> +               return -EINVAL;
>> +
>> +       ret = dma_get_by_name(dev, "rx", &priv->rx_dma);
>> +       if (ret)
>> +               return -EINVAL;
>> +
>> +       /* try to enable clocks */
>> +       for (i = 0; ; i++) {
>> +               struct clk clk;
>> +               int ret;
>> +
>> +               ret = clk_get_by_index(dev, i, &clk);
>> +               if (ret < 0)
>> +                       break;
>> +               if (clk_enable(&clk))
>> +                       pr_err("failed to enable clock %d\n", i);
>> +               clk_free(&clk);
>> +       }
>> +
>> +       /* try to perform resets */
>> +       for (i = 0; ; i++) {
>> +               struct reset_ctl reset;
>> +               int ret;
>> +
>> +               ret = reset_get_by_index(dev, i, &reset);
>> +               if (ret < 0)
>> +                       break;
>> +               if (reset_deassert(&reset))
>> +                       pr_err("failed to deassert reset %d\n", i);
>> +               reset_free(&reset);
>> +       }
>> +
>> +       /* get base addr */
>> +       priv->base = ioremap(addr, 0);
>> +       pdata->iobase = (phys_addr_t) priv->base;
>> +
>> +       /* disable emac */
>> +       bcm6348_eth_mac_disable(priv);
>> +
>> +       /* reset emac */
>> +       bcm6348_eth_mac_reset(priv);
>> +
>> +       /* select correct mii interface */
>> +       if (pdata->phy_interface == PHY_INTERFACE_MODE_INTERNAL)
>> +               clrbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_EPHY_MASK);
>> +       else
>> +               setbits_be32(priv->base + ETH_CTL_REG, ETH_CTL_EPHY_MASK);
>> +
>> +       /* turn on mdc clock */
>> +       writel_be((0x1f << MII_SC_MDCFREQDIV_SHIFT) |
>> +                 MII_SC_PREAMBLE_EN_MASK, priv->base + MII_SC_REG);
>> +
>> +       /* set mib counters to not clear when read */
>> +       clrbits_be32(priv->base + MIB_CTL_REG, MIB_CTL_RDCLEAR_MASK);
>> +
>> +       /* initialize perfect match registers */
>> +       for (i = 0; i < ETH_PM_CNT; i++) {
>> +               writel_be(0, priv->base + ETH_PML_REG(i));
>> +               writel_be(0, priv->base + ETH_PMH_REG(i));
>> +       }
>> +
>> +       /* init mii bus */
>> +       ret = bcm6348_mdio_init(dev->name, priv->base);
>> +       if (ret)
>> +               return ret;
>> +
>> +       /* init phy */
>> +       ret = bcm6348_phy_init(dev);
>> +       if (ret)
>> +               return ret;
>> +
>> +       return 0;
>> +}
>> +
>> +U_BOOT_DRIVER(bcm6348_eth) = {
>> +       .name = "bcm6348_eth",
>> +       .id = UCLASS_ETH,
>> +       .of_match = bcm6348_eth_ids,
>> +       .ops = &bcm6348_eth_ops,
>> +       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
>> +       .priv_auto_alloc_size = sizeof(struct bcm6348_eth_priv),
>> +       .probe = bcm6348_eth_probe,
>> +};
>> diff --git a/include/configs/bmips_common.h b/include/configs/bmips_common.h
>> index 38bf7a272b..eb66512f67 100644
>> --- a/include/configs/bmips_common.h
>> +++ b/include/configs/bmips_common.h
>> @@ -7,6 +7,9 @@
>>   #ifndef __CONFIG_BMIPS_COMMON_H
>>   #define __CONFIG_BMIPS_COMMON_H
>>
>> +/* ETH */
>> +#define CONFIG_PHY_RESET_DELAY         20
>> +
>>   /* UART */
>>   #define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200, \
>>                                            230400, 500000, 1500000 }
>> @@ -17,7 +20,7 @@
>>
>>   /* Memory usage */
>>   #define CONFIG_SYS_MAXARGS             24
>> -#define CONFIG_SYS_MALLOC_LEN          (1024 * 1024)
>> +#define CONFIG_SYS_MALLOC_LEN          (2 * 1024 * 1024)
>>   #define CONFIG_SYS_BOOTPARAMS_LEN      (128 * 1024)
>>   #define CONFIG_SYS_CBSIZE              512
>>
>> --
>> 2.11.0
>>
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot at lists.denx.de
>> https://lists.denx.de/listinfo/u-boot
~Álvaro.

  reply	other threads:[~2018-03-08 19:50 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-12 16:38 [U-Boot] [RFC 00/14] bmips: add bcm6348-enet support Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 01/14] dma: add dma channels support and improve uclass Álvaro Fernández Rojas
2018-02-20  8:24   ` Vignesh R
2018-02-12 16:38 ` [U-Boot] [RFC 02/14] dma: add bcm6348-iudma support Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 03/14] bmips: bcm6338: " Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 04/14] bmips: bcm6348: " Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 05/14] bmips: bcm6358: " Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 06/14] phy: add support for internal phys Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 07/14] net: add support for bcm6348-enet Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 08/14] bmips: bcm6338: " Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 09/14] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 10/14] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 11/14] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 12/14] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 13/14] bmips: enable hg556a enet support Álvaro Fernández Rojas
2018-02-12 16:38 ` [U-Boot] [RFC 14/14] bmips: enable nb4-ser " Álvaro Fernández Rojas
2018-02-19 17:26 ` [U-Boot] [RFC 00/14] bmips: add bcm6348-enet support Álvaro Fernández Rojas
2018-02-20 17:46 ` [U-Boot] [RFC v2 00/15] " Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 01/15] dma: move dma_ops to dma-uclass.h Álvaro Fernández Rojas
2018-02-20 18:49     ` Simon Glass
2018-02-20 18:55       ` Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 02/15] dma: add channels support Álvaro Fernández Rojas
2018-02-20 18:49     ` Simon Glass
2018-02-20 19:00       ` Álvaro Fernández Rojas
2018-02-21 15:51       ` Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 03/15] dma: add bcm6348-iudma support Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 04/15] bmips: bcm6338: " Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 05/15] bmips: bcm6348: " Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 06/15] bmips: bcm6358: " Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 07/15] phy: add support for internal phys Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 08/15] net: add support for bcm6348-enet Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 09/15] bmips: bcm6338: " Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 10/15] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 11/15] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 12/15] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 13/15] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 14/15] bmips: enable hg556a enet support Álvaro Fernández Rojas
2018-02-20 17:46   ` [U-Boot] [RFC v2 15/15] bmips: enable nb4-ser " Álvaro Fernández Rojas
2018-02-21 16:10 ` [U-Boot] [RFC v3 00/15] bmips: add bcm6348-enet support Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 01/15] dma: move dma_ops to dma-uclass.h Álvaro Fernández Rojas
2018-02-22 16:18     ` Simon Glass
2018-03-05 19:35       ` Grygorii Strashko
2018-03-05 20:06         ` Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 02/15] dma: add channels support Álvaro Fernández Rojas
2018-02-22 16:18     ` Simon Glass
2018-02-21 16:10   ` [U-Boot] [RFC v3 03/15] dma: add bcm6348-iudma support Álvaro Fernández Rojas
2018-02-22 19:50     ` Grygorii Strashko
2018-02-22 20:48       ` Álvaro Fernández Rojas
2018-02-23 16:57         ` Grygorii Strashko
2018-03-03  9:06           ` Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 04/15] bmips: bcm6338: " Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 05/15] bmips: bcm6348: " Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 06/15] bmips: bcm6358: " Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 07/15] phy: add support for internal phys Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 08/15] net: add support for bcm6348-enet Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 09/15] bmips: bcm6338: " Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 10/15] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 11/15] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 12/15] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 13/15] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 14/15] bmips: enable hg556a enet support Álvaro Fernández Rojas
2018-02-21 16:10   ` [U-Boot] [RFC v3 15/15] bmips: enable nb4-ser " Álvaro Fernández Rojas
2018-03-03  8:59 ` [U-Boot] [RFC v4 00/15] bmips: add bcm6348-enet support Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 01/15] dma: move dma_ops to dma-uclass.h Álvaro Fernández Rojas
2018-03-05 19:38     ` Grygorii Strashko
2018-03-03  8:59   ` [U-Boot] [RFC v4 02/15] dma: add channels support Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 03/15] dma: add bcm6348-iudma support Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 04/15] bmips: bcm6338: " Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 05/15] bmips: bcm6348: " Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 06/15] bmips: bcm6358: " Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 07/15] phy: add support for internal phys Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 08/15] net: add support for bcm6348-enet Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 09/15] bmips: bcm6338: " Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 10/15] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 11/15] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 12/15] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 13/15] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 14/15] bmips: enable hg556a enet support Álvaro Fernández Rojas
2018-03-03  8:59   ` [U-Boot] [RFC v4 15/15] bmips: enable nb4-ser " Álvaro Fernández Rojas
2018-03-05 20:05 ` [U-Boot] [PATCH v5 00/15] bmips: add bcm6348-enet support Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 01/15] dma: move dma_ops to dma-uclass.h Álvaro Fernández Rojas
2018-03-06 15:10     ` Grygorii Strashko
2018-03-05 20:05   ` [U-Boot] [PATCH v5 02/15] dma: add channels support Álvaro Fernández Rojas
2018-03-07 21:27     ` Joe Hershberger
2018-03-08 19:46       ` Álvaro Fernández Rojas
2018-03-08 23:07     ` Grygorii Strashko
2018-03-09 18:42       ` Álvaro Fernández Rojas
2018-03-11 19:14     ` Daniel Schwierzeck
2018-03-05 20:05   ` [U-Boot] [PATCH v5 03/15] dma: add bcm6348-iudma support Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 04/15] bmips: bcm6338: " Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 05/15] bmips: bcm6348: " Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 06/15] bmips: bcm6358: " Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 07/15] phy: add support for internal phys Álvaro Fernández Rojas
2018-03-07 20:28     ` Joe Hershberger
2018-03-08 19:38       ` Álvaro Fernández Rojas
2018-03-08 20:11         ` Joe Hershberger
2018-03-05 20:05   ` [U-Boot] [PATCH v5 08/15] net: add support for bcm6348-enet Álvaro Fernández Rojas
2018-03-07 21:46     ` Joe Hershberger
2018-03-08 19:50       ` Álvaro Fernández Rojas [this message]
2018-03-05 20:05   ` [U-Boot] [PATCH v5 09/15] bmips: bcm6338: " Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 10/15] bmips: enable f@st1704 enet support Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 11/15] bmips: bcm6348: add support for bcm6348-enet Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 12/15] bmips: enable ct-5361 enet support Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 13/15] bmips: bcm6358: add support for bcm6348-enet Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 14/15] bmips: enable hg556a enet support Álvaro Fernández Rojas
2018-03-05 20:05   ` [U-Boot] [PATCH v5 15/15] bmips: enable nb4-ser " Álvaro Fernández Rojas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=99bc7f9a-252d-25ea-e67e-a79c0c62c0f0@gmail.com \
    --to=noltari@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.