mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-27 23:20:26 +09:00
net: mvgbe: convert to DM
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> Tested-by: Michael Walle <michael@walle.cc> Acked-by: Joe Hershberger <joe.hershberger@ni.com>
This commit is contained in:
parent
e9bf75c9d3
commit
fb73107698
@ -181,6 +181,7 @@ config FTMAC100
|
|||||||
config MVGBE
|
config MVGBE
|
||||||
bool "Marvell Orion5x/Kirkwood network interface support"
|
bool "Marvell Orion5x/Kirkwood network interface support"
|
||||||
depends on KIRKWOOD || ORION5X
|
depends on KIRKWOOD || ORION5X
|
||||||
|
select PHYLIB if DM_ETH
|
||||||
help
|
help
|
||||||
This driver supports the network interface units in the
|
This driver supports the network interface units in the
|
||||||
Marvell Orion5x and Kirkwood SoCs
|
Marvell Orion5x and Kirkwood SoCs
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <miiphy.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,
|
static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
|
||||||
int reg_ofs)
|
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 eth_device *dev = eth_get_dev_by_name(bus->name);
|
||||||
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
||||||
|
#endif
|
||||||
|
|
||||||
return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs);
|
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,
|
static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
|
||||||
int reg_ofs, u16 data)
|
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 eth_device *dev = eth_get_dev_by_name(bus->name);
|
||||||
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
||||||
|
#endif
|
||||||
|
|
||||||
return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
|
return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
|
||||||
}
|
}
|
||||||
@ -415,11 +424,13 @@ static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe)
|
|||||||
dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
|
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,
|
||||||
|
const char *name)
|
||||||
{
|
{
|
||||||
struct mvgbe_registers *regs = dmvgbe->regs;
|
struct mvgbe_registers *regs = dmvgbe->regs;
|
||||||
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
|
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
|
||||||
!defined(CONFIG_PHYLIB) && \
|
!defined(CONFIG_PHYLIB) && \
|
||||||
|
!defined(CONFIG_DM_ETH) && \
|
||||||
defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
|
defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
|
||||||
int i;
|
int i;
|
||||||
#endif
|
#endif
|
||||||
@ -436,7 +447,7 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
|
|||||||
|
|
||||||
set_dram_access(regs);
|
set_dram_access(regs);
|
||||||
port_init_mac_tables(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. */
|
/* Assign port configuration and command. */
|
||||||
MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
|
MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
|
||||||
@ -473,31 +484,34 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe)
|
|||||||
|
|
||||||
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
|
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
|
||||||
!defined(CONFIG_PHYLIB) && \
|
!defined(CONFIG_PHYLIB) && \
|
||||||
|
!defined(CONFIG_DM_ETH) && \
|
||||||
defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
|
defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
|
||||||
/* Wait up to 5s for the link status */
|
/* Wait up to 5s for the link status */
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
u16 phyadr;
|
u16 phyadr;
|
||||||
|
|
||||||
miiphy_read(dmvgbe->dev.name, MV_PHY_ADR_REQUEST,
|
miiphy_read(name, MV_PHY_ADR_REQUEST,
|
||||||
MV_PHY_ADR_REQUEST, &phyadr);
|
MV_PHY_ADR_REQUEST, &phyadr);
|
||||||
/* Return if we get link up */
|
/* Return if we get link up */
|
||||||
if (miiphy_link(dmvgbe->dev.name, phyadr))
|
if (miiphy_link(name, phyadr))
|
||||||
return 0;
|
return 0;
|
||||||
udelay(1000000);
|
udelay(1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("No link on %s\n", dmvgbe->dev.name);
|
printf("No link on %s\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_DM_ETH
|
||||||
static int mvgbe_init(struct eth_device *dev)
|
static int mvgbe_init(struct eth_device *dev)
|
||||||
{
|
{
|
||||||
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
||||||
|
|
||||||
return __mvgbe_init(dmvgbe);
|
return __mvgbe_init(dmvgbe, dmvgbe->dev.enetaddr, dmvgbe->dev.name);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
|
static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
|
||||||
{
|
{
|
||||||
@ -524,6 +538,7 @@ static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
|
|||||||
MVGBE_REG_WR(regs->peim, 0);
|
MVGBE_REG_WR(regs->peim, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_DM_ETH
|
||||||
static int mvgbe_halt(struct eth_device *dev)
|
static int mvgbe_halt(struct eth_device *dev)
|
||||||
{
|
{
|
||||||
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
||||||
@ -532,7 +547,18 @@ static int mvgbe_halt(struct eth_device *dev)
|
|||||||
|
|
||||||
return 0;
|
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)
|
static int mvgbe_write_hwaddr(struct eth_device *dev)
|
||||||
{
|
{
|
||||||
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
||||||
@ -541,6 +567,7 @@ static int mvgbe_write_hwaddr(struct eth_device *dev)
|
|||||||
port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
|
port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
|
static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
|
||||||
int datasize)
|
int datasize)
|
||||||
@ -597,12 +624,14 @@ static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_DM_ETH
|
||||||
static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
|
static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
|
||||||
{
|
{
|
||||||
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
||||||
|
|
||||||
return __mvgbe_send(dmvgbe, dataptr, datasize);
|
return __mvgbe_send(dmvgbe, dataptr, datasize);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
|
static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
|
||||||
{
|
{
|
||||||
@ -677,6 +706,7 @@ static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
|
|||||||
return rx_bytes;
|
return rx_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_DM_ETH
|
||||||
static int mvgbe_recv(struct eth_device *dev)
|
static int mvgbe_recv(struct eth_device *dev)
|
||||||
{
|
{
|
||||||
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
|
||||||
@ -691,8 +721,41 @@ static int mvgbe_recv(struct eth_device *dev)
|
|||||||
|
|
||||||
return 0;
|
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)
|
int mvgbe_phylib_init(struct eth_device *dev, int phyid)
|
||||||
{
|
{
|
||||||
struct mii_dev *bus;
|
struct mii_dev *bus;
|
||||||
@ -715,27 +778,53 @@ int mvgbe_phylib_init(struct eth_device *dev, int phyid)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set phy address of the port */
|
phydev = __mvgbe_phy_init(dev, bus, PHY_INTERFACE_MODE_RGMII, phyid);
|
||||||
smi_reg_write(bus, MV_PHY_ADR_REQUEST, 0, MV_PHY_ADR_REQUEST, phyid);
|
if (!phydev)
|
||||||
|
|
||||||
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RGMII);
|
|
||||||
if (!phydev) {
|
|
||||||
printf("phy_connect failed\n");
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
|
||||||
|
|
||||||
phy_config(phydev);
|
|
||||||
phy_startup(phydev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
int mvgbe_initialize(bd_t *bis)
|
||||||
{
|
{
|
||||||
struct mvgbe_device *dmvgbe;
|
struct mvgbe_device *dmvgbe;
|
||||||
struct eth_device *dev;
|
struct eth_device *dev;
|
||||||
int devnum;
|
int devnum;
|
||||||
|
int ret;
|
||||||
u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS;
|
u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS;
|
||||||
|
|
||||||
for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) {
|
for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) {
|
||||||
@ -744,45 +833,16 @@ int mvgbe_initialize(bd_t *bis)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
dmvgbe = malloc(sizeof(struct mvgbe_device));
|
dmvgbe = malloc(sizeof(struct mvgbe_device));
|
||||||
|
|
||||||
if (!dmvgbe)
|
if (!dmvgbe)
|
||||||
goto error1;
|
return -ENOMEM;
|
||||||
|
|
||||||
memset(dmvgbe, 0, sizeof(struct mvgbe_device));
|
memset(dmvgbe, 0, sizeof(struct mvgbe_device));
|
||||||
|
ret = mvgbe_alloc_buffers(dmvgbe);
|
||||||
dmvgbe->p_rxdesc =
|
if (ret) {
|
||||||
(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:
|
|
||||||
printf("Err.. %s Failed to allocate memory\n",
|
printf("Err.. %s Failed to allocate memory\n",
|
||||||
__func__);
|
__func__);
|
||||||
return -1;
|
free(dmvgbe);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = &dmvgbe->dev;
|
dev = &dmvgbe->dev;
|
||||||
@ -834,3 +894,154 @@ error1:
|
|||||||
}
|
}
|
||||||
return 0;
|
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, dev->name);
|
||||||
|
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;
|
||||||
|
int pnode;
|
||||||
|
unsigned long addr;
|
||||||
|
|
||||||
|
pdata->iobase = devfdt_get_addr(dev);
|
||||||
|
pdata->phy_interface = -1;
|
||||||
|
|
||||||
|
pnode = fdt_node_offset_by_compatible(blob, node,
|
||||||
|
"marvell,kirkwood-eth-port");
|
||||||
|
|
||||||
|
/* Get phy-mode / phy_interface from DT */
|
||||||
|
phy_mode = fdt_getprop(gd->fdt_blob, pnode, "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, pnode, "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_lookup_phandle(blob, pnode, "phy-handle");
|
||||||
|
if (addr > 0)
|
||||||
|
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 */
|
||||||
|
@ -30,7 +30,9 @@
|
|||||||
#define RXUQ 0 /* Used Rx queue */
|
#define RXUQ 0 /* Used Rx queue */
|
||||||
#define TXUQ 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)
|
#define to_mvgbe(_d) container_of(_d, struct mvgbe_device, dev)
|
||||||
|
#endif
|
||||||
#define MVGBE_REG_WR(adr, val) writel(val, &adr)
|
#define MVGBE_REG_WR(adr, val) writel(val, &adr)
|
||||||
#define MVGBE_REG_RD(adr) readl(&adr)
|
#define MVGBE_REG_RD(adr) readl(&adr)
|
||||||
#define MVGBE_REG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr)
|
#define MVGBE_REG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr)
|
||||||
@ -479,13 +481,27 @@ struct mvgbe_txdesc {
|
|||||||
|
|
||||||
/* port device data struct */
|
/* port device data struct */
|
||||||
struct mvgbe_device {
|
struct mvgbe_device {
|
||||||
|
#ifndef CONFIG_DM_ETH
|
||||||
struct eth_device dev;
|
struct eth_device dev;
|
||||||
|
#endif
|
||||||
struct mvgbe_registers *regs;
|
struct mvgbe_registers *regs;
|
||||||
struct mvgbe_txdesc *p_txdesc;
|
struct mvgbe_txdesc *p_txdesc;
|
||||||
struct mvgbe_rxdesc *p_rxdesc;
|
struct mvgbe_rxdesc *p_rxdesc;
|
||||||
struct mvgbe_rxdesc *p_rxdesc_curr;
|
struct mvgbe_rxdesc *p_rxdesc_curr;
|
||||||
u8 *p_rxbuf;
|
u8 *p_rxbuf;
|
||||||
u8 *p_aligned_txbuf;
|
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__ */
|
#endif /* __MVGBE_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user