* [U-Boot] [PATCH v2 1/2] net: mvgbe: prepare for conversion to driver model
@ 2018-07-07 10:05 Chris Packham
2018-07-07 10:05 ` [U-Boot] [PATCH v2 2/2] net: mvgbe: convert to DM Chris Packham
0 siblings, 1 reply; 4+ messages in thread
From: Chris Packham @ 2018-07-07 10:05 UTC (permalink / raw)
To: u-boot
Extract some function bodies to helper functions that can be reused in
the DM/non-DM implementations.
Signed-off-by: Chris Packham <judge.packham@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
---
Changes in v2: None
drivers/net/mvgbe.c | 109 ++++++++++++++++++++++++++++++++------------
1 file changed, 80 insertions(+), 29 deletions(-)
diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c
index e6585ef8b3e7..96ca35512f01 100644
--- a/drivers/net/mvgbe.c
+++ b/drivers/net/mvgbe.c
@@ -55,20 +55,13 @@ static int smi_wait_ready(struct mvgbe_device *dmvgbe)
return 0;
}
-/*
- * smi_reg_read - miiphy_read callback function.
- *
- * Returns 16bit phy register value, or -EFAULT on error
- */
-static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
- int reg_ofs)
+static int __mvgbe_mdio_read(struct mvgbe_device *dmvgbe, int phy_adr,
+ int devad, int reg_ofs)
{
- u16 data = 0;
- struct eth_device *dev = eth_get_dev_by_name(bus->name);
- struct mvgbe_device *dmvgbe = to_mvgbe(dev);
struct mvgbe_registers *regs = dmvgbe->regs;
u32 smi_reg;
u32 timeout;
+ u16 data = 0;
/* Phyadr read request */
if (phy_adr == MV_PHY_ADR_REQUEST &&
@@ -127,15 +120,22 @@ static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
}
/*
- * smi_reg_write - miiphy_write callback function.
+ * smi_reg_read - miiphy_read callback function.
*
- * Returns 0 if write succeed, -EFAULT on error
+ * Returns 16bit phy register value, or -EFAULT on error
*/
-static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
- int reg_ofs, u16 data)
+static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
+ int reg_ofs)
{
struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+
+ return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs);
+}
+
+static int __mvgbe_mdio_write(struct mvgbe_device *dmvgbe, int phy_adr,
+ int devad, int reg_ofs, u16 data)
+{
struct mvgbe_registers *regs = dmvgbe->regs;
u32 smi_reg;
@@ -171,6 +171,20 @@ static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
return 0;
}
+
+/*
+ * smi_reg_write - miiphy_write callback function.
+ *
+ * Returns 0 if write succeed, -EFAULT on error
+ */
+static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
+ int reg_ofs, u16 data)
+{
+ struct eth_device *dev = eth_get_dev_by_name(bus->name);
+ struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+
+ return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
+}
#endif
/* Stop and checks all queues */
@@ -357,8 +371,9 @@ static int port_uc_addr(struct mvgbe_registers *regs, u8 uc_nibble,
/*
* port_uc_addr_set - This function Set the port Unicast address.
*/
-static void port_uc_addr_set(struct mvgbe_registers *regs, u8 * p_addr)
+static void port_uc_addr_set(struct mvgbe_device *dmvgbe, u8 *p_addr)
{
+ struct mvgbe_registers *regs = dmvgbe->regs;
u32 mac_h;
u32 mac_l;
@@ -400,9 +415,8 @@ static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe)
dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
}
-static int mvgbe_init(struct eth_device *dev)
+static int __mvgbe_init(struct mvgbe_device *dmvgbe)
{
- struct mvgbe_device *dmvgbe = to_mvgbe(dev);
struct mvgbe_registers *regs = dmvgbe->regs;
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
!defined(CONFIG_PHYLIB) && \
@@ -422,7 +436,7 @@ static int mvgbe_init(struct eth_device *dev)
set_dram_access(regs);
port_init_mac_tables(regs);
- port_uc_addr_set(regs, dmvgbe->dev.enetaddr);
+ port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
/* Assign port configuration and command. */
MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
@@ -478,9 +492,15 @@ static int mvgbe_init(struct eth_device *dev)
return 0;
}
-static int mvgbe_halt(struct eth_device *dev)
+static int mvgbe_init(struct eth_device *dev)
{
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+
+ return __mvgbe_init(dmvgbe);
+}
+
+static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
+{
struct mvgbe_registers *regs = dmvgbe->regs;
/* Disable all gigE address decoder */
@@ -502,6 +522,13 @@ static int mvgbe_halt(struct eth_device *dev)
MVGBE_REG_WR(regs->ice, 0);
MVGBE_REG_WR(regs->pim, 0);
MVGBE_REG_WR(regs->peim, 0);
+}
+
+static int mvgbe_halt(struct eth_device *dev)
+{
+ struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+
+ __mvgbe_halt(dmvgbe);
return 0;
}
@@ -509,16 +536,15 @@ static int mvgbe_halt(struct eth_device *dev)
static int mvgbe_write_hwaddr(struct eth_device *dev)
{
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
- struct mvgbe_registers *regs = dmvgbe->regs;
/* Programs net device MAC address after initialization */
- port_uc_addr_set(regs, dmvgbe->dev.enetaddr);
+ port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
return 0;
}
-static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
+static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
+ int datasize)
{
- struct mvgbe_device *dmvgbe = to_mvgbe(dev);
struct mvgbe_registers *regs = dmvgbe->regs;
struct mvgbe_txdesc *p_txdesc = dmvgbe->p_txdesc;
void *p = (void *)dataptr;
@@ -571,13 +597,23 @@ static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
return 0;
}
-static int mvgbe_recv(struct eth_device *dev)
+static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
{
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+
+ return __mvgbe_send(dmvgbe, dataptr, datasize);
+}
+
+static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
+{
struct mvgbe_rxdesc *p_rxdesc_curr = dmvgbe->p_rxdesc_curr;
u32 cmd_sts;
u32 timeout = 0;
u32 rxdesc_curr_addr;
+ unsigned char *data;
+ int rx_bytes = 0;
+
+ *packetp = NULL;
/* wait untill rx packet available or timeout */
do {
@@ -621,11 +657,11 @@ static int mvgbe_recv(struct eth_device *dev)
" upper layer (net_process_received_packet)\n",
__func__);
- /* let the upper layer handle the packet */
- net_process_received_packet((p_rxdesc_curr->buf_ptr +
- RX_BUF_OFFSET),
- (int)(p_rxdesc_curr->byte_cnt -
- RX_BUF_OFFSET));
+ data = (p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET);
+ rx_bytes = (int)(p_rxdesc_curr->byte_cnt -
+ RX_BUF_OFFSET);
+
+ *packetp = data;
}
/*
* free these descriptors and point next in the ring
@@ -638,6 +674,21 @@ static int mvgbe_recv(struct eth_device *dev)
rxdesc_curr_addr = (u32)&dmvgbe->p_rxdesc_curr;
writel((unsigned)p_rxdesc_curr->nxtdesc_p, rxdesc_curr_addr);
+ return rx_bytes;
+}
+
+static int mvgbe_recv(struct eth_device *dev)
+{
+ struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+ uchar *packet;
+ int ret;
+
+ ret = __mvgbe_recv(dmvgbe, &packet);
+ if (ret < 0)
+ return ret;
+
+ net_process_received_packet(packet, ret);
+
return 0;
}
--
2.18.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH v2 2/2] net: mvgbe: convert to DM
2018-07-07 10:05 [U-Boot] [PATCH v2 1/2] net: mvgbe: prepare for conversion to driver model Chris Packham
@ 2018-07-07 10:05 ` Chris Packham
2018-07-08 21:05 ` Michael Walle
0 siblings, 1 reply; 4+ messages in thread
From: Chris Packham @ 2018-07-07 10:05 UTC (permalink / raw)
To: u-boot
Add driver model support to the mvgbe driver. As a temporary measure
both DM and non-DM uses are supported. Once all the users have been
converted the non-DM support can be dropped.
Signed-off-by: Chris Packham <judge.packham@gmail.com>
---
Changes in v2:
- create __mvgbe_phy_init and mvgbe_alloc_buffers helper functions
- move device tree reads to mvgbe_ofdata_to_platdata
drivers/net/mvgbe.c | 303 +++++++++++++++++++++++++++++++++++++-------
drivers/net/mvgbe.h | 16 +++
2 files changed, 271 insertions(+), 48 deletions(-)
diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c
index 96ca35512f01..82508e43fdf5 100644
--- a/drivers/net/mvgbe.c
+++ b/drivers/net/mvgbe.c
@@ -12,6 +12,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <net.h>
#include <malloc.h>
#include <miiphy.h>
@@ -127,8 +128,12 @@ static int __mvgbe_mdio_read(struct mvgbe_device *dmvgbe, int phy_adr,
static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
int reg_ofs)
{
+#ifdef CONFIG_DM_ETH
+ struct mvgbe_device *dmvgbe = bus->priv;
+#else
struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+#endif
return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs);
}
@@ -180,8 +185,12 @@ static int __mvgbe_mdio_write(struct mvgbe_device *dmvgbe, int phy_adr,
static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
int reg_ofs, u16 data)
{
+#ifdef CONFIG_DM_ETH
+ struct mvgbe_device *dmvgbe = bus->priv;
+#else
struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+#endif
return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
}
@@ -415,11 +424,12 @@ static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe)
dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
}
-static int __mvgbe_init(struct mvgbe_device *dmvgbe)
+static int __mvgbe_init(struct mvgbe_device *dmvgbe, u8 *enetaddr)
{
struct mvgbe_registers *regs = dmvgbe->regs;
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
!defined(CONFIG_PHYLIB) && \
+ !defined(CONFIG_DM_ETH) && \
defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
int i;
#endif
@@ -436,7 +446,7 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
set_dram_access(regs);
port_init_mac_tables(regs);
- port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
+ port_uc_addr_set(dmvgbe, enetaddr);
/* Assign port configuration and command. */
MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
@@ -473,6 +483,7 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
!defined(CONFIG_PHYLIB) && \
+ !defined(CONFIG_DM_ETH) && \
defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
/* Wait up to 5s for the link status */
for (i = 0; i < 5; i++) {
@@ -492,12 +503,14 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
return 0;
}
+#ifndef CONFIG_DM_ETH
static int mvgbe_init(struct eth_device *dev)
{
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
- return __mvgbe_init(dmvgbe);
+ return __mvgbe_init(dmvgbe, dmvgbe->dev.enetaddr);
}
+#endif
static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
{
@@ -524,6 +537,7 @@ static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
MVGBE_REG_WR(regs->peim, 0);
}
+#ifndef CONFIG_DM_ETH
static int mvgbe_halt(struct eth_device *dev)
{
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
@@ -532,7 +546,18 @@ static int mvgbe_halt(struct eth_device *dev)
return 0;
}
+#endif
+#ifdef CONFIG_DM_ETH
+static int mvgbe_write_hwaddr(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ port_uc_addr_set(dev_get_priv(dev), pdata->enetaddr);
+
+ return 0;
+}
+#else
static int mvgbe_write_hwaddr(struct eth_device *dev)
{
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
@@ -541,6 +566,7 @@ static int mvgbe_write_hwaddr(struct eth_device *dev)
port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
return 0;
}
+#endif
static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
int datasize)
@@ -597,12 +623,14 @@ static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
return 0;
}
+#ifndef CONFIG_DM_ETH
static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
{
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
return __mvgbe_send(dmvgbe, dataptr, datasize);
}
+#endif
static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
{
@@ -677,6 +705,7 @@ static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
return rx_bytes;
}
+#ifndef CONFIG_DM_ETH
static int mvgbe_recv(struct eth_device *dev)
{
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
@@ -691,8 +720,41 @@ static int mvgbe_recv(struct eth_device *dev)
return 0;
}
+#endif
-#if defined(CONFIG_PHYLIB)
+#if defined(CONFIG_PHYLIB) || defined(CONFIG_DM_ETH)
+#if defined(CONFIG_DM_ETH)
+static struct phy_device *__mvgbe_phy_init(struct udevice *dev,
+ struct mii_dev *bus,
+ phy_interface_t phy_interface,
+ int phyid)
+#else
+static struct phy_device *__mvgbe_phy_init(struct eth_device *dev,
+ struct mii_dev *bus,
+ phy_interface_t phy_interface,
+ int phyid)
+#endif
+{
+ struct phy_device *phydev;
+
+ /* Set phy address of the port */
+ miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST,
+ phyid);
+
+ phydev = phy_connect(bus, phyid, dev, phy_interface);
+ if (!phydev) {
+ printf("phy_connect failed\n");
+ return NULL;
+ }
+
+ phy_config(phydev);
+ phy_startup(phydev);
+
+ return phydev;
+}
+#endif /* CONFIG_PHYLIB || CONFIG_DM_ETH */
+
+#if defined(CONFIG_PHYLIB) && !defined(CONFIG_DM_ETH)
int mvgbe_phylib_init(struct eth_device *dev, int phyid)
{
struct mii_dev *bus;
@@ -715,27 +777,53 @@ int mvgbe_phylib_init(struct eth_device *dev, int phyid)
return -ENOMEM;
}
- /* Set phy address of the port */
- smi_reg_write(bus, MV_PHY_ADR_REQUEST, 0, MV_PHY_ADR_REQUEST, phyid);
-
- phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RGMII);
- if (!phydev) {
- printf("phy_connect failed\n");
+ phydev = __mvgbe_phy_init(dev, bus, PHY_INTERFACE_MODE_RGMII, phyid);
+ if (!phydev)
return -ENODEV;
- }
-
- phy_config(phydev);
- phy_startup(phydev);
return 0;
}
#endif
+static int mvgbe_alloc_buffers(struct mvgbe_device *dmvgbe)
+{
+ dmvgbe->p_rxdesc = memalign(PKTALIGN,
+ MV_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);
+ if (!dmvgbe->p_rxdesc)
+ goto error1;
+
+ dmvgbe->p_rxbuf = memalign(PKTALIGN,
+ RINGSZ * PKTSIZE_ALIGN + 1);
+ if (!dmvgbe->p_rxbuf)
+ goto error2;
+
+ dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
+ if (!dmvgbe->p_aligned_txbuf)
+ goto error3;
+
+ dmvgbe->p_txdesc = memalign(PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);
+ if (!dmvgbe->p_txdesc)
+ goto error4;
+
+ return 0;
+
+error4:
+ free(dmvgbe->p_aligned_txbuf);
+error3:
+ free(dmvgbe->p_rxbuf);
+error2:
+ free(dmvgbe->p_rxdesc);
+error1:
+ return -ENOMEM;
+}
+
+#ifndef CONFIG_DM_ETH
int mvgbe_initialize(bd_t *bis)
{
struct mvgbe_device *dmvgbe;
struct eth_device *dev;
int devnum;
+ int ret;
u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS;
for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) {
@@ -744,45 +832,16 @@ int mvgbe_initialize(bd_t *bis)
continue;
dmvgbe = malloc(sizeof(struct mvgbe_device));
-
if (!dmvgbe)
- goto error1;
+ return -ENOMEM;
memset(dmvgbe, 0, sizeof(struct mvgbe_device));
-
- dmvgbe->p_rxdesc =
- (struct mvgbe_rxdesc *)memalign(PKTALIGN,
- MV_RXQ_DESC_ALIGNED_SIZE*RINGSZ + 1);
-
- if (!dmvgbe->p_rxdesc)
- goto error2;
-
- dmvgbe->p_rxbuf = (u8 *) memalign(PKTALIGN,
- RINGSZ*PKTSIZE_ALIGN + 1);
-
- if (!dmvgbe->p_rxbuf)
- goto error3;
-
- dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
-
- if (!dmvgbe->p_aligned_txbuf)
- goto error4;
-
- dmvgbe->p_txdesc = (struct mvgbe_txdesc *) memalign(
- PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);
-
- if (!dmvgbe->p_txdesc) {
- free(dmvgbe->p_aligned_txbuf);
-error4:
- free(dmvgbe->p_rxbuf);
-error3:
- free(dmvgbe->p_rxdesc);
-error2:
- free(dmvgbe);
-error1:
+ ret = mvgbe_alloc_buffers(dmvgbe);
+ if (ret) {
printf("Err.. %s Failed to allocate memory\n",
__func__);
- return -1;
+ free(dmvgbe);
+ return ret;
}
dev = &dmvgbe->dev;
@@ -834,3 +893,151 @@ error1:
}
return 0;
}
+#endif
+
+#ifdef CONFIG_DM_ETH
+static int mvgbe_port_is_fixed_link(struct mvgbe_device *dmvgbe)
+{
+ return dmvgbe->phyaddr > PHY_MAX_ADDR;
+}
+
+static int mvgbe_start(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+ int ret;
+
+ ret = __mvgbe_init(dmvgbe, pdata->enetaddr);
+ if (ret)
+ return ret;
+
+ if (!mvgbe_port_is_fixed_link(dmvgbe)) {
+ dmvgbe->phydev = __mvgbe_phy_init(dev, dmvgbe->bus,
+ dmvgbe->phy_interface,
+ dmvgbe->phyaddr);
+ if (!dmvgbe->phydev)
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int mvgbe_send(struct udevice *dev, void *packet, int length)
+{
+ struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+
+ return __mvgbe_send(dmvgbe, packet, length);
+}
+
+static int mvgbe_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+
+ return __mvgbe_recv(dmvgbe, packetp);
+}
+
+static void mvgbe_stop(struct udevice *dev)
+{
+ struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+
+ __mvgbe_halt(dmvgbe);
+}
+
+static int mvgbe_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+ struct mii_dev *bus;
+ int ret;
+
+ ret = mvgbe_alloc_buffers(dmvgbe);
+ if (ret)
+ return ret;
+
+ dmvgbe->regs = (void __iomem *)pdata->iobase;
+
+ bus = mdio_alloc();
+ if (!bus) {
+ printf("Failed to allocate MDIO bus\n");
+ return -ENOMEM;
+ }
+
+ bus->read = smi_reg_read;
+ bus->write = smi_reg_write;
+ snprintf(bus->name, sizeof(bus->name), dev->name);
+ bus->priv = dmvgbe;
+ dmvgbe->bus = bus;
+
+ ret = mdio_register(bus);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static const struct eth_ops mvgbe_ops = {
+ .start = mvgbe_start,
+ .send = mvgbe_send,
+ .recv = mvgbe_recv,
+ .stop = mvgbe_stop,
+ .write_hwaddr = mvgbe_write_hwaddr,
+};
+
+static int mvgbe_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct mvgbe_device *dmvgbe = dev_get_priv(dev);
+ void *blob = (void *)gd->fdt_blob;
+ int node = dev_of_offset(dev);
+ const char *phy_mode;
+ int fl_node;
+ unsigned long addr;
+
+ pdata->iobase = devfdt_get_addr(dev);
+
+ /* Get phy-mode / phy_interface from DT */
+ pdata->phy_interface = -1;
+ phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
+ NULL);
+ if (phy_mode)
+ pdata->phy_interface = phy_get_interface_by_name(phy_mode);
+ if (pdata->phy_interface == -1) {
+ debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
+ return -EINVAL;
+ }
+
+ dmvgbe->phy_interface = pdata->phy_interface;
+
+ /* fetch 'fixed-link' property */
+ fl_node = fdt_subnode_offset(blob, node, "fixed-link");
+ if (fl_node != -FDT_ERR_NOTFOUND) {
+ /* set phy_addr to invalid value for fixed link */
+ dmvgbe->phyaddr = PHY_MAX_ADDR + 1;
+ dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
+ dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
+ } else {
+ /* Now read phyaddr from DT */
+ addr = fdtdec_get_int(blob, node, "phy", 0);
+ addr = fdt_node_offset_by_phandle(blob, addr);
+ dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
+ }
+
+ return 0;
+}
+
+static const struct udevice_id mvgbe_ids[] = {
+ { .compatible = "marvell,kirkwood-eth" },
+ { }
+};
+
+U_BOOT_DRIVER(mvgbe) = {
+ .name = "mvgbe",
+ .id = UCLASS_ETH,
+ .of_match = mvgbe_ids,
+ .ofdata_to_platdata = mvgbe_ofdata_to_platdata,
+ .probe = mvgbe_probe,
+ .ops = &mvgbe_ops,
+ .priv_auto_alloc_size = sizeof(struct mvgbe_device),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
+#endif /* CONFIG_DM_ETH */
diff --git a/drivers/net/mvgbe.h b/drivers/net/mvgbe.h
index 1dc9bbea2f42..44541c0a85e3 100644
--- a/drivers/net/mvgbe.h
+++ b/drivers/net/mvgbe.h
@@ -30,7 +30,9 @@
#define RXUQ 0 /* Used Rx queue */
#define TXUQ 0 /* Used Rx queue */
+#ifndef CONFIG_DM_ETH
#define to_mvgbe(_d) container_of(_d, struct mvgbe_device, dev)
+#endif
#define MVGBE_REG_WR(adr, val) writel(val, &adr)
#define MVGBE_REG_RD(adr) readl(&adr)
#define MVGBE_REG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr)
@@ -479,13 +481,27 @@ struct mvgbe_txdesc {
/* port device data struct */
struct mvgbe_device {
+#ifndef CONFIG_DM_ETH
struct eth_device dev;
+#endif
struct mvgbe_registers *regs;
struct mvgbe_txdesc *p_txdesc;
struct mvgbe_rxdesc *p_rxdesc;
struct mvgbe_rxdesc *p_rxdesc_curr;
u8 *p_rxbuf;
u8 *p_aligned_txbuf;
+
+#ifdef CONFIG_DM_ETH
+ phy_interface_t phy_interface;
+ unsigned int link;
+ unsigned int duplex;
+ unsigned int speed;
+
+ int init;
+ int phyaddr;
+ struct phy_device *phydev;
+ struct mii_dev *bus;
+#endif
};
#endif /* __MVGBE_H__ */
--
2.18.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH v2 2/2] net: mvgbe: convert to DM
2018-07-07 10:05 ` [U-Boot] [PATCH v2 2/2] net: mvgbe: convert to DM Chris Packham
@ 2018-07-08 21:05 ` Michael Walle
2018-07-09 8:03 ` Chris Packham
0 siblings, 1 reply; 4+ messages in thread
From: Michael Walle @ 2018-07-08 21:05 UTC (permalink / raw)
To: u-boot
Hi Chris,
thanks for your efforts. This basically works for me on my Kirkwood
LSCHLv2 board. So you may add
Tested-by: Michael Walle <michael@walle.cc>
But there are some issues. See below.
[snip]
> -#if defined(CONFIG_PHYLIB)
> +#if defined(CONFIG_PHYLIB) || defined(CONFIG_DM_ETH)
> +#if defined(CONFIG_DM_ETH)
> +static struct phy_device *__mvgbe_phy_init(struct udevice *dev,
> + struct mii_dev *bus,
> + phy_interface_t phy_interface,
> + int phyid)
> +#else
> +static struct phy_device *__mvgbe_phy_init(struct eth_device *dev,
> + struct mii_dev *bus,
> + phy_interface_t phy_interface,
> + int phyid)
> +#endif
> +{
> + struct phy_device *phydev;
> +
> + /* Set phy address of the port */
> + miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST,
> + phyid);
> +
> + phydev = phy_connect(bus, phyid, dev, phy_interface);
So CONFIG_PHYLIB is required if CONFIG_DM_ETH is enabled? If so, then
can we add
selects PHYLIB if DM_ETH
to the CONFIG_MVGBE Kconfig part?
> + if (!phydev) {
> + printf("phy_connect failed\n");
> + return NULL;
> + }
> +
> + phy_config(phydev);
> + phy_startup(phydev);
> +
> + return phydev;
> +}
> +#endif /* CONFIG_PHYLIB || CONFIG_DM_ETH */
> +
[snip]
> +static int mvgbe_ofdata_to_platdata(struct udevice *dev)
> +{
> + struct eth_pdata *pdata = dev_get_platdata(dev);
> + struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> + void *blob = (void *)gd->fdt_blob;
> + int node = dev_of_offset(dev);
> + const char *phy_mode;
> + int fl_node;
> + unsigned long addr;
> +
> + pdata->iobase = devfdt_get_addr(dev);
> +
> + /* Get phy-mode / phy_interface from DT */
> + pdata->phy_interface = -1;
> + phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
> + NULL);
> + if (phy_mode)
> + pdata->phy_interface = phy_get_interface_by_name(phy_mode);
> + if (pdata->phy_interface == -1) {
> + debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
> + return -EINVAL;
> + }
> +
> + dmvgbe->phy_interface = pdata->phy_interface;
> +
> + /* fetch 'fixed-link' property */
> + fl_node = fdt_subnode_offset(blob, node, "fixed-link");
> + if (fl_node != -FDT_ERR_NOTFOUND) {
> + /* set phy_addr to invalid value for fixed link */
> + dmvgbe->phyaddr = PHY_MAX_ADDR + 1;
> + dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
> + dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
> + } else {
> + /* Now read phyaddr from DT */
> + addr = fdtdec_get_int(blob, node, "phy", 0);
Should be "phy-handle", shouldn't it? And isn't there already function
for this which gets the phy address? Also, the phy-handle is on the port
subnode in the device tree. I guess, this applies to phy-mode, too.
> + addr = fdt_node_offset_by_phandle(blob, addr);
> + dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
> + }
> +
> + return 0;
> +}
-michael
^ permalink raw reply [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH v2 2/2] net: mvgbe: convert to DM
2018-07-08 21:05 ` Michael Walle
@ 2018-07-09 8:03 ` Chris Packham
0 siblings, 0 replies; 4+ messages in thread
From: Chris Packham @ 2018-07-09 8:03 UTC (permalink / raw)
To: u-boot
On Mon, Jul 9, 2018 at 9:05 AM Michael Walle <michael@walle.cc> wrote:
>
>
> Hi Chris,
>
> thanks for your efforts. This basically works for me on my Kirkwood
> LSCHLv2 board. So you may add
>
> Tested-by: Michael Walle <michael@walle.cc>
>
> But there are some issues. See below.
>
>
> [snip]
>
> > -#if defined(CONFIG_PHYLIB)
> > +#if defined(CONFIG_PHYLIB) || defined(CONFIG_DM_ETH)
> > +#if defined(CONFIG_DM_ETH)
> > +static struct phy_device *__mvgbe_phy_init(struct udevice *dev,
> > + struct mii_dev *bus,
> > + phy_interface_t phy_interface,
> > + int phyid)
> > +#else
> > +static struct phy_device *__mvgbe_phy_init(struct eth_device *dev,
> > + struct mii_dev *bus,
> > + phy_interface_t phy_interface,
> > + int phyid)
> > +#endif
> > +{
> > + struct phy_device *phydev;
> > +
> > + /* Set phy address of the port */
> > + miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST,
> > + phyid);
> > +
> > + phydev = phy_connect(bus, phyid, dev, phy_interface);
>
> So CONFIG_PHYLIB is required if CONFIG_DM_ETH is enabled? If so, then
> can we add
>
> selects PHYLIB if DM_ETH
>
> to the CONFIG_MVGBE Kconfig part?
>
Yes will do. I even erroneously added it at one point (without the if DM_ETH).
> > + if (!phydev) {
> > + printf("phy_connect failed\n");
> > + return NULL;
> > + }
> > +
> > + phy_config(phydev);
> > + phy_startup(phydev);
> > +
> > + return phydev;
> > +}
> > +#endif /* CONFIG_PHYLIB || CONFIG_DM_ETH */
> > +
>
> [snip]
>
> > +static int mvgbe_ofdata_to_platdata(struct udevice *dev)
> > +{
> > + struct eth_pdata *pdata = dev_get_platdata(dev);
> > + struct mvgbe_device *dmvgbe = dev_get_priv(dev);
> > + void *blob = (void *)gd->fdt_blob;
> > + int node = dev_of_offset(dev);
> > + const char *phy_mode;
> > + int fl_node;
> > + unsigned long addr;
> > +
> > + pdata->iobase = devfdt_get_addr(dev);
> > +
> > + /* Get phy-mode / phy_interface from DT */
> > + pdata->phy_interface = -1;
> > + phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
> > + NULL);
> > + if (phy_mode)
> > + pdata->phy_interface = phy_get_interface_by_name(phy_mode);
> > + if (pdata->phy_interface == -1) {
> > + debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
> > + return -EINVAL;
> > + }
> > +
> > + dmvgbe->phy_interface = pdata->phy_interface;
> > +
> > + /* fetch 'fixed-link' property */
> > + fl_node = fdt_subnode_offset(blob, node, "fixed-link");
> > + if (fl_node != -FDT_ERR_NOTFOUND) {
> > + /* set phy_addr to invalid value for fixed link */
> > + dmvgbe->phyaddr = PHY_MAX_ADDR + 1;
> > + dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
> > + dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
> > + } else {
> > + /* Now read phyaddr from DT */
> > + addr = fdtdec_get_int(blob, node, "phy", 0);
>
> Should be "phy-handle", shouldn't it? And isn't there already function
> for this which gets the phy address? Also, the phy-handle is on the port
> subnode in the device tree. I guess, this applies to phy-mode, too.
>
Hmm my hacky dts for testing this called it "phy" and attached it to
the eth node. I'll look at a couple of proper boards and code to them.
> > + addr = fdt_node_offset_by_phandle(blob, addr);
> > + dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
> > + }
> > +
> > + return 0;
> > +}
>
>
> -michael
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-07-09 8:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-07 10:05 [U-Boot] [PATCH v2 1/2] net: mvgbe: prepare for conversion to driver model Chris Packham
2018-07-07 10:05 ` [U-Boot] [PATCH v2 2/2] net: mvgbe: convert to DM Chris Packham
2018-07-08 21:05 ` Michael Walle
2018-07-09 8:03 ` Chris Packham
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox