[U-Boot] [PATCH 2/7] net: mvpp2: Replace SMI implementation with marvell MDIO API
Joe Hershberger
joe.hershberger at gmail.com
Wed Aug 14 15:39:49 UTC 2019
On Fri, Aug 2, 2019 at 12:54 PM <nhed+uboot at starry.com> wrote:
>
> From: Ken Ma <make at marvell.com>
>
> Since marvell MDIO driver is added, SMI function implementation in
> mvpp2 driver can be removed and NETA driver can use marvell MDIO API
> directly.
> This replacement also fixes 2 old issues:
> 1. Each pp2 port device should have its own mdio bus field member since
> some pp2 ports may use SMI mdio bus while some other pp2 ports may
> use XSMI mdio bus, but the old mvpp2_base device has a shared bus
> for its all pp2 ports; this patch moves mdio bus field member from
> struct mvpp2 to struct mvpp2_port;
> 2. Old code uses mvpp2_base device name as mdio bus name, but for
> Armada80x0, cp0 ethernet device and cp1 ethernet device have the
> same device name - "ethernet at 0"; and because mdio_register() checks
> unique name, then the second probed mvpp2_base device fails to
> register mdio bus; since new marvell MDIO driver has resolved the
> unique name issue - different mdio names can be set in fdt and if
> a mdio name is not set, the default mdio name will be generated from
> the mdio bus base address, so this issue is fixed by this
> replacement.
>
> Signed-off-by: Ken Ma <make at marvell.com>
> Reviewed-by: Igal Liberman <igall at marvell.com>
> Tested-by: Igal Liberman <igall at marvell.com>
> Signed-off-by: Nevo Hed <nhed+github at starry.com>
> ---
>
> drivers/net/Kconfig | 1 +
> drivers/net/mvpp2.c | 158 ++++----------------------------------------
> 2 files changed, 13 insertions(+), 146 deletions(-)
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 5fd31b03cf..d8c4dd6f4d 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -297,6 +297,7 @@ config MVPP2
> bool "Marvell Armada 375/7K/8K network interface support"
> depends on ARMADA_375 || ARMADA_8K
> select PHYLIB
> + select MVMDIO
> help
> This driver supports the network interface units in the
> Marvell ARMADA 375, 7K and 8K SoCs.
> diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
> index f36c8236b1..b6dfed5c54 100644
> --- a/drivers/net/mvpp2.c
> +++ b/drivers/net/mvpp2.c
> @@ -32,6 +32,7 @@
> #include <linux/mbus.h>
> #include <asm-generic/gpio.h>
> #include <fdt_support.h>
> +#include <mdio.h>
>
> DECLARE_GLOBAL_DATA_PTR;
>
> @@ -62,8 +63,6 @@ do { \
> #define MTU 1500
> #define RX_BUFFER_SIZE (ALIGN(MTU + WRAP, ARCH_DMA_MINALIGN))
>
> -#define MVPP2_SMI_TIMEOUT 10000
> -
> /* RX Fifo Registers */
> #define MVPP2_RX_DATA_FIFO_SIZE_REG(port) (0x00 + 4 * (port))
> #define MVPP2_RX_ATTR_FIFO_SIZE_REG(port) (0x20 + 4 * (port))
> @@ -490,23 +489,8 @@ do { \
> #define MVPP2_QUEUE_NEXT_DESC(q, index) \
> (((index) < (q)->last_desc) ? ((index) + 1) : 0)
>
> -/* SMI: 0xc0054 -> offset 0x54 to lms_base */
> -#define MVPP21_SMI 0x0054
> /* PP2.2: SMI: 0x12a200 -> offset 0x1200 to iface_base */
> #define MVPP22_SMI 0x1200
> -#define MVPP2_PHY_REG_MASK 0x1f
> -/* SMI register fields */
> -#define MVPP2_SMI_DATA_OFFS 0 /* Data */
> -#define MVPP2_SMI_DATA_MASK (0xffff << MVPP2_SMI_DATA_OFFS)
> -#define MVPP2_SMI_DEV_ADDR_OFFS 16 /* PHY device address */
> -#define MVPP2_SMI_REG_ADDR_OFFS 21 /* PHY device reg addr*/
> -#define MVPP2_SMI_OPCODE_OFFS 26 /* Write/Read opcode */
> -#define MVPP2_SMI_OPCODE_READ (1 << MVPP2_SMI_OPCODE_OFFS)
> -#define MVPP2_SMI_READ_VALID (1 << 27) /* Read Valid */
> -#define MVPP2_SMI_BUSY (1 << 28) /* Busy */
> -
> -#define MVPP2_PHY_ADDR_MASK 0x1f
> -#define MVPP2_PHY_REG_MASK 0x1f
>
> /* Additional PPv2.2 offsets */
> #define MVPP22_MPCS 0x007000
> @@ -973,7 +957,6 @@ struct mvpp2_port {
>
> struct phy_device *phy_dev;
> phy_interface_t phy_interface;
> - int phy_node;
> int phyaddr;
> struct mii_dev *bus;
> #ifdef CONFIG_DM_GPIO
> @@ -4562,7 +4545,7 @@ static int mvpp2_open(struct udevice *dev, struct mvpp2_port *port)
> return err;
> }
>
> - if (port->phy_node) {
> + if (port->phyaddr < PHY_MAX_ADDR) {
> mvpp2_phy_connect(dev, port);
> mvpp2_link_event(port);
> } else {
> @@ -4701,6 +4684,7 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)
> u32 id;
> u32 phyaddr = 0;
> int phy_mode = -1;
> + int ret;
>
> /* Default mdio_base from the same eth base */
> if (port->priv->hw_version == MVPP21)
> @@ -4719,17 +4703,12 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)
> dev_err(&pdev->dev, "could not find phy address\n");
> return -1;
> }
> -
> - phy_ofnode = ofnode_get_parent(offset_to_ofnode(phy_node));
> - phy_base = ofnode_get_addr(phy_ofnode);
> - port->mdio_base = (void *)phy_base;
> -
> - if (port->mdio_base < 0) {
> - dev_err(&pdev->dev, "could not find mdio base address\n");
> - return -1;
> - }
> + ret = mdio_mii_bus_get_from_phy(phy_node, &port->bus);
> + if (ret)
> + return ret;
> } else {
> - phy_node = 0;
> + /* phy_addr is set to invalid value */
> + phyaddr = PHY_MAX_ADDR;
> }
>
> phy_mode_str = fdt_getprop(gd->fdt_blob, port_node, "phy-mode", NULL);
> @@ -4767,7 +4746,6 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)
> port->first_rxq = port->id * rxq_number;
> else
> port->first_rxq = port->id * port->priv->max_port_rxqs;
> - port->phy_node = phy_node;
> port->phy_interface = phy_mode;
> port->phyaddr = phyaddr;
>
> @@ -5044,119 +5022,7 @@ static int mvpp2_init(struct udevice *dev, struct mvpp2 *priv)
> return 0;
> }
>
> -/* SMI / MDIO functions */
> -
> -static int smi_wait_ready(struct mvpp2_port *priv)
> -{
> - u32 timeout = MVPP2_SMI_TIMEOUT;
> - u32 smi_reg;
> -
> - /* wait till the SMI is not busy */
> - do {
> - /* read smi register */
> - smi_reg = readl(priv->mdio_base);
> - if (timeout-- == 0) {
> - printf("Error: SMI busy timeout\n");
> - return -EFAULT;
> - }
> - } while (smi_reg & MVPP2_SMI_BUSY);
> -
> - return 0;
> -}
> -
> -/*
> - * mpp2_mdio_read - miiphy_read callback function.
> - *
> - * Returns 16bit phy register value, or 0xffff on error
> - */
> -static int mpp2_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
> -{
> - struct mvpp2_port *priv = bus->priv;
> - u32 smi_reg;
> - u32 timeout;
> -
> - /* check parameters */
> - if (addr > MVPP2_PHY_ADDR_MASK) {
> - printf("Error: Invalid PHY address %d\n", addr);
> - return -EFAULT;
> - }
> -
> - if (reg > MVPP2_PHY_REG_MASK) {
> - printf("Err: Invalid register offset %d\n", reg);
> - return -EFAULT;
> - }
> -
> - /* wait till the SMI is not busy */
> - if (smi_wait_ready(priv) < 0)
> - return -EFAULT;
> -
> - /* fill the phy address and regiser offset and read opcode */
> - smi_reg = (addr << MVPP2_SMI_DEV_ADDR_OFFS)
> - | (reg << MVPP2_SMI_REG_ADDR_OFFS)
> - | MVPP2_SMI_OPCODE_READ;
> -
> - /* write the smi register */
> - writel(smi_reg, priv->mdio_base);
> -
> - /* wait till read value is ready */
> - timeout = MVPP2_SMI_TIMEOUT;
> -
> - do {
> - /* read smi register */
> - smi_reg = readl(priv->mdio_base);
> - if (timeout-- == 0) {
> - printf("Err: SMI read ready timeout\n");
> - return -EFAULT;
> - }
> - } while (!(smi_reg & MVPP2_SMI_READ_VALID));
> -
> - /* Wait for the data to update in the SMI register */
> - for (timeout = 0; timeout < MVPP2_SMI_TIMEOUT; timeout++)
> - ;
> -
> - return readl(priv->mdio_base) & MVPP2_SMI_DATA_MASK;
> -}
> -
> -/*
> - * mpp2_mdio_write - miiphy_write callback function.
> - *
> - * Returns 0 if write succeed, -EINVAL on bad parameters
> - * -ETIME on timeout
> - */
> -static int mpp2_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
> - u16 value)
> -{
> - struct mvpp2_port *priv = bus->priv;
> - u32 smi_reg;
> -
> - /* check parameters */
> - if (addr > MVPP2_PHY_ADDR_MASK) {
> - printf("Error: Invalid PHY address %d\n", addr);
> - return -EFAULT;
> - }
> -
> - if (reg > MVPP2_PHY_REG_MASK) {
> - printf("Err: Invalid register offset %d\n", reg);
> - return -EFAULT;
> - }
> -
> - /* wait till the SMI is not busy */
> - if (smi_wait_ready(priv) < 0)
> - return -EFAULT;
> -
> - /* fill the phy addr and reg offset and write opcode and data */
> - smi_reg = value << MVPP2_SMI_DATA_OFFS;
> - smi_reg |= (addr << MVPP2_SMI_DEV_ADDR_OFFS)
> - | (reg << MVPP2_SMI_REG_ADDR_OFFS);
> - smi_reg &= ~MVPP2_SMI_OPCODE_READ;
> -
> - /* write the smi register */
> - writel(smi_reg, priv->mdio_base);
> -
> - return 0;
> -}
> -
> -static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp)
> +int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp)
Why does this need to be visible outside of this translation unit?
> {
> struct mvpp2_port *port = dev_get_priv(dev);
> struct mvpp2_rx_desc *rx_desc;
> @@ -5168,7 +5034,7 @@ static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp)
> struct mvpp2_rx_queue *rxq;
> u8 *data;
>
> - if (port->phy_node)
> + if (port->phyaddr < PHY_MAX_ADDR)
> if (!port->phy_dev->link)
> return 0;
>
> @@ -5237,7 +5103,7 @@ static int mvpp2_send(struct udevice *dev, void *packet, int length)
> int tx_done;
> int timeout;
>
> - if (port->phy_node)
> + if (port->phyaddr < PHY_MAX_ADDR)
> if (!port->phy_dev->link)
> return 0;
>
> @@ -5474,7 +5340,7 @@ static int mvpp2_probe(struct udevice *dev)
> port->gop_id * MVPP22_PORT_OFFSET;
>
> /* Set phy address of the port */
> - if(port->phy_node)
> + if (port->phyaddr < PHY_MAX_ADDR)
> mvpp22_smi_phy_addr_cfg(port);
>
> /* GoP Init */
> --
> 2.21.0
>
More information about the U-Boot
mailing list