drivers: mcffec: conversion to dm

Full conversion to dm for all boards, legacy code removed.

Signed-off-by: Angelo Durgehello <angelo.dureghello@timesys.com>
This commit is contained in:
Angelo Durgehello
2019-11-15 23:54:18 +01:00
committed by Tom Rini
parent 080bcc5cc1
commit a7bcace28a
2 changed files with 323 additions and 302 deletions

View File

@@ -0,0 +1,22 @@
* Freescale ColdFire FEC ethernet controller
Required properties:
- compatible: should be "fsl,mcf-fec"
- reg: address and length of the register set for the device.
Optional properties:
- mii-base: index of FEC reg area, 0 for FEC0, 1 for FEC1
- max-speed: max speedm Mbits/sec
- phy-addr: phy address
- timeout-loop: integer value for driver loops time out
Example:
fec0: ethernet@fc030000 {
compatible = "fsl,mcf-fec";
reg = <0xfc030000 0x400>;
mii-base = <0>;
phy-addr = <0>;
timeout-loop = <5000>;
};

View File

@@ -5,17 +5,17 @@
*
* (C) Copyright 2007 Freescale Semiconductor, Inc.
* TsiChung Liew (Tsi-Chung.Liew@freescale.com)
*
* Conversion to DM
* (C) 2019 Angelo Dureghello <angelo.dureghello@timesys.com>
*/
#include <common.h>
#include <env.h>
#include <malloc.h>
#include <command.h>
#include <net.h>
#include <netdev.h>
#include <miiphy.h>
#include <asm/fec.h>
#include <asm/immap.h>
#include <linux/mii.h>
@@ -27,64 +27,68 @@
#define DBUF_LENGTH 1520
#define TX_BUF_CNT 2
#define PKT_MAXBUF_SIZE 1518
#define PKT_MINBUF_SIZE 64
#define PKT_MAXBLR_SIZE 1520
#define LAST_PKTBUFSRX PKTBUFSRX - 1
#define BD_ENET_RX_W_E (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY)
#define BD_ENET_TX_RDY_LST (BD_ENET_TX_READY | BD_ENET_TX_LAST)
struct fec_info_s fec_info[] = {
#ifdef CONFIG_SYS_FEC0_IOBASE
{
0, /* index */
CONFIG_SYS_FEC0_IOBASE, /* io base */
CONFIG_SYS_FEC0_PINMUX, /* gpio pin muxing */
CONFIG_SYS_FEC0_MIIBASE, /* mii base */
-1, /* phy_addr */
0, /* duplex and speed */
0, /* phy name */
0, /* phyname init */
0, /* RX BD */
0, /* TX BD */
0, /* rx Index */
0, /* tx Index */
0, /* tx buffer */
0, /* initialized flag */
(struct fec_info_s *)-1,
},
#endif
#ifdef CONFIG_SYS_FEC1_IOBASE
{
1, /* index */
CONFIG_SYS_FEC1_IOBASE, /* io base */
CONFIG_SYS_FEC1_PINMUX, /* gpio pin muxing */
CONFIG_SYS_FEC1_MIIBASE, /* mii base */
-1, /* phy_addr */
0, /* duplex and speed */
0, /* phy name */
0, /* phy name init */
#ifdef CONFIG_SYS_FEC_BUF_USE_SRAM
(cbd_t *)DBUF_LENGTH, /* RX BD */
#else
0, /* RX BD */
#endif
0, /* TX BD */
0, /* rx Index */
0, /* tx Index */
0, /* tx buffer */
0, /* initialized flag */
(struct fec_info_s *)-1,
}
#endif
};
DECLARE_GLOBAL_DATA_PTR;
int fec_recv(struct eth_device *dev);
int fec_init(struct eth_device *dev, bd_t * bd);
void fec_halt(struct eth_device *dev);
void fec_reset(struct eth_device *dev);
void setFecDuplexSpeed(volatile fec_t * fecp, bd_t * bd, int dup_spd)
static void init_eth_info(struct fec_info_s *info)
{
#ifdef CONFIG_SYS_FEC_BUF_USE_SRAM
static u32 tmp;
if (info->index == 0)
tmp = CONFIG_SYS_INIT_RAM_ADDR + 0x1000;
else
info->rxbd = (cbd_t *)DBUF_LENGTH;
/* setup Receive and Transmit buffer descriptor */
info->rxbd = (cbd_t *)((u32)info->rxbd + tmp);
tmp = (u32)info->rxbd;
info->txbd =
(cbd_t *)((u32)info->txbd + tmp +
(PKTBUFSRX * sizeof(cbd_t)));
tmp = (u32)info->txbd;
info->txbuf =
(char *)((u32)info->txbuf + tmp +
(CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t)));
tmp = (u32)info->txbuf;
#else
info->rxbd =
(cbd_t *)memalign(CONFIG_SYS_CACHELINE_SIZE,
(PKTBUFSRX * sizeof(cbd_t)));
info->txbd =
(cbd_t *)memalign(CONFIG_SYS_CACHELINE_SIZE,
(TX_BUF_CNT * sizeof(cbd_t)));
info->txbuf =
(char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH);
#endif
#ifdef ET_DEBUG
printf("rxbd %x txbd %x\n", (int)info->rxbd, (int)info->txbd);
#endif
info->phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32);
}
static void fec_reset(struct fec_info_s *info)
{
volatile fec_t *fecp = (fec_t *)(info->iobase);
int i;
fecp->ecr = FEC_ECR_RESET;
for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i)
udelay(1);
if (i == FEC_RESET_DELAY)
printf("FEC_RESET_DELAY timeout\n");
}
static void set_fec_duplex_speed(volatile fec_t *fecp, int dup_spd)
{
bd_t *bd = gd->bd;
if ((dup_spd >> 16) == FULL) {
/* Set maximum frame length */
fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE |
@@ -116,138 +120,11 @@ void setFecDuplexSpeed(volatile fec_t * fecp, bd_t * bd, int dup_spd)
}
}
static int fec_send(struct eth_device *dev, void *packet, int length)
#ifdef ET_DEBUG
static void dbg_fec_regs(struct udevice *dev)
{
struct fec_info_s *info = dev->priv;
volatile fec_t *fecp = (fec_t *) (info->iobase);
int j, rc;
u16 phyStatus;
miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phyStatus);
/* section 16.9.23.3
* Wait for ready
*/
j = 0;
while ((info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_READY) &&
(j < MCFFEC_TOUT_LOOP)) {
udelay(1);
j++;
}
if (j >= MCFFEC_TOUT_LOOP) {
printf("TX not ready\n");
}
info->txbd[info->txIdx].cbd_bufaddr = (uint) packet;
info->txbd[info->txIdx].cbd_datlen = length;
info->txbd[info->txIdx].cbd_sc |= BD_ENET_TX_RDY_LST;
/* Activate transmit Buffer Descriptor polling */
fecp->tdar = 0x01000000; /* Descriptor polling active */
#ifndef CONFIG_SYS_FEC_BUF_USE_SRAM
/*
* FEC unable to initial transmit data packet.
* A nop will ensure the descriptor polling active completed.
* CF Internal RAM has shorter cycle access than DRAM. If use
* DRAM as Buffer descriptor and data, a nop is a must.
* Affect only V2 and V3.
*/
__asm__ ("nop");
#endif
#ifdef CONFIG_SYS_UNIFY_CACHE
icache_invalid();
#endif
j = 0;
while ((info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_READY) &&
(j < MCFFEC_TOUT_LOOP)) {
udelay(1);
j++;
}
if (j >= MCFFEC_TOUT_LOOP) {
printf("TX timeout\n");
}
#ifdef ET_DEBUG
printf("%s[%d] %s: cycles: %d status: %x retry cnt: %d\n",
__FILE__, __LINE__, __FUNCTION__, j,
info->txbd[info->txIdx].cbd_sc,
(info->txbd[info->txIdx].cbd_sc & 0x003C) >> 2);
#endif
/* return only status bits */
rc = (info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_STATS);
info->txIdx = (info->txIdx + 1) % TX_BUF_CNT;
return rc;
}
int fec_recv(struct eth_device *dev)
{
struct fec_info_s *info = dev->priv;
volatile fec_t *fecp = (fec_t *) (info->iobase);
int length;
for (;;) {
#ifndef CONFIG_SYS_FEC_BUF_USE_SRAM
#endif
#ifdef CONFIG_SYS_UNIFY_CACHE
icache_invalid();
#endif
/* section 16.9.23.2 */
if (info->rxbd[info->rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
length = -1;
break; /* nothing received - leave for() loop */
}
length = info->rxbd[info->rxIdx].cbd_datlen;
if (info->rxbd[info->rxIdx].cbd_sc & 0x003f) {
printf("%s[%d] err: %x\n",
__FUNCTION__, __LINE__,
info->rxbd[info->rxIdx].cbd_sc);
#ifdef ET_DEBUG
printf("%s[%d] err: %x\n",
__FUNCTION__, __LINE__,
info->rxbd[info->rxIdx].cbd_sc);
#endif
} else {
length -= 4;
/* Pass the packet up to the protocol layers. */
net_process_received_packet(net_rx_packets[info->rxIdx],
length);
fecp->eir |= FEC_EIR_RXF;
}
/* Give the buffer back to the FEC. */
info->rxbd[info->rxIdx].cbd_datlen = 0;
/* wrap around buffer index when necessary */
if (info->rxIdx == LAST_PKTBUFSRX) {
info->rxbd[PKTBUFSRX - 1].cbd_sc = BD_ENET_RX_W_E;
info->rxIdx = 0;
} else {
info->rxbd[info->rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
info->rxIdx++;
}
/* Try to fill Buffer Descriptors */
fecp->rdar = 0x01000000; /* Descriptor polling active */
}
return length;
}
#ifdef ET_DEBUG
void dbgFecRegs(struct eth_device *dev)
{
struct fec_info_s *info = dev->priv;
volatile fec_t *fecp = (fec_t *) (info->iobase);
volatile fec_t *fecp = (fec_t *)(info->iobase);
printf("=====\n");
printf("ievent %x - %x\n", (int)&fecp->eir, fecp->eir);
@@ -394,28 +271,27 @@ void dbgFecRegs(struct eth_device *dev)
}
#endif
int fec_init(struct eth_device *dev, bd_t * bd)
int mcffec_init(struct udevice *dev)
{
struct fec_info_s *info = dev->priv;
volatile fec_t *fecp = (fec_t *) (info->iobase);
int i;
int rval, i;
uchar ea[6];
fecpin_setclear(dev, 1);
fec_reset(dev);
fecpin_setclear(info, 1);
fec_reset(info);
#if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \
defined (CONFIG_SYS_DISCOVER_PHY)
mii_init();
setFecDuplexSpeed(fecp, bd, info->dup_spd);
set_fec_duplex_speed(fecp, info->dup_spd);
#else
#ifndef CONFIG_SYS_DISCOVER_PHY
setFecDuplexSpeed(fecp, bd, (FECDUPLEX << 16) | FECSPEED);
#endif /* ifndef CONFIG_SYS_DISCOVER_PHY */
#endif /* CONFIG_CMD_MII || CONFIG_MII */
set_fec_duplex_speed(fecp, (FECDUPLEX << 16) | FECSPEED);
#endif /* ifndef CONFIG_SYS_DISCOVER_PHY */
#endif /* CONFIG_CMD_MII || CONFIG_MII */
/* We use strictly polling mode only */
fecp->eimr = 0;
@@ -424,34 +300,20 @@ int fec_init(struct eth_device *dev, bd_t * bd)
fecp->eir = 0xffffffff;
/* Set station address */
if ((u32) fecp == CONFIG_SYS_FEC0_IOBASE) {
#ifdef CONFIG_SYS_FEC1_IOBASE
volatile fec_t *fecp1 = (fec_t *) (CONFIG_SYS_FEC1_IOBASE);
eth_env_get_enetaddr("eth1addr", ea);
fecp1->palr =
(ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
fecp1->paur = (ea[4] << 24) | (ea[5] << 16);
#endif
eth_env_get_enetaddr("ethaddr", ea);
fecp->palr =
(ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
fecp->paur = (ea[4] << 24) | (ea[5] << 16);
} else {
#ifdef CONFIG_SYS_FEC0_IOBASE
volatile fec_t *fecp0 = (fec_t *) (CONFIG_SYS_FEC0_IOBASE);
eth_env_get_enetaddr("ethaddr", ea);
fecp0->palr =
(ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
fecp0->paur = (ea[4] << 24) | (ea[5] << 16);
#endif
#ifdef CONFIG_SYS_FEC1_IOBASE
eth_env_get_enetaddr("eth1addr", ea);
fecp->palr =
(ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
fecp->paur = (ea[4] << 24) | (ea[5] << 16);
#endif
if (info->index == 0)
rval = eth_env_get_enetaddr("ethaddr", ea);
else
rval = eth_env_get_enetaddr("eth1addr", ea);
if (!rval) {
puts("Please set a valid MAC address\n");
return -EINVAL;
}
fecp->palr =
(ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
fecp->paur = (ea[4] << 24) | (ea[5] << 16);
/* Clear unicast address hash table */
fecp->iaur = 0;
fecp->ialr = 0;
@@ -466,8 +328,8 @@ int fec_init(struct eth_device *dev, bd_t * bd)
/*
* Setup Buffers and Buffer Descriptors
*/
info->rxIdx = 0;
info->txIdx = 0;
info->rx_idx = 0;
info->tx_idx = 0;
/*
* Setup Receiver Buffer Descriptors (13.14.24.18)
@@ -500,119 +362,256 @@ int fec_init(struct eth_device *dev, bd_t * bd)
/* Now enable the transmit and receive processing */
fecp->ecr |= FEC_ECR_ETHER_EN;
/* And last, try to fill Rx Buffer Descriptors */
fecp->rdar = 0x01000000; /* Descriptor polling active */
/* And last, try to fill Rx Buffer Descriptors
* Descriptor polling active
*/
fecp->rdar = 0x01000000;
return 1;
return 0;
}
void fec_reset(struct eth_device *dev)
static int mcffec_send(struct udevice *dev, void *packet, int length)
{
struct fec_info_s *info = dev->priv;
volatile fec_t *fecp = (fec_t *) (info->iobase);
int i;
volatile fec_t *fecp = (fec_t *)info->iobase;
int j, rc;
u16 phy_status;
fecp->ecr = FEC_ECR_RESET;
for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) {
miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phy_status);
/* section 16.9.23.3
* Wait for ready
*/
j = 0;
while ((info->txbd[info->tx_idx].cbd_sc & BD_ENET_TX_READY) &&
(j < info->to_loop)) {
udelay(1);
j++;
}
if (i == FEC_RESET_DELAY) {
printf("FEC_RESET_DELAY timeout\n");
if (j >= info->to_loop)
printf("TX not ready\n");
info->txbd[info->tx_idx].cbd_bufaddr = (uint)packet;
info->txbd[info->tx_idx].cbd_datlen = length;
info->txbd[info->tx_idx].cbd_sc |= BD_ENET_TX_RDY_LST;
/* Activate transmit Buffer Descriptor polling */
fecp->tdar = 0x01000000; /* Descriptor polling active */
#ifndef CONFIG_SYS_FEC_BUF_USE_SRAM
/*
* FEC unable to initial transmit data packet.
* A nop will ensure the descriptor polling active completed.
* CF Internal RAM has shorter cycle access than DRAM. If use
* DRAM as Buffer descriptor and data, a nop is a must.
* Affect only V2 and V3.
*/
__asm__ ("nop");
#endif
#ifdef CONFIG_SYS_UNIFY_CACHE
icache_invalid();
#endif
j = 0;
while ((info->txbd[info->tx_idx].cbd_sc & BD_ENET_TX_READY) &&
(j < info->to_loop)) {
udelay(1);
j++;
}
if (j >= info->to_loop)
printf("TX timeout\n");
#ifdef ET_DEBUG
printf("%s[%d] %s: cycles: %d status: %x retry cnt: %d\n",
__FILE__, __LINE__, __func__, j,
info->txbd[info->tx_idx].cbd_sc,
(info->txbd[info->tx_idx].cbd_sc & 0x003C) >> 2);
#endif
/* return only status bits */
rc = (info->txbd[info->tx_idx].cbd_sc & BD_ENET_TX_STATS);
info->tx_idx = (info->tx_idx + 1) % TX_BUF_CNT;
return rc;
}
void fec_halt(struct eth_device *dev)
static int mcffec_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct fec_info_s *info = dev->priv;
volatile fec_t *fecp = (fec_t *)info->iobase;
int length = -1;
for (;;) {
#ifdef CONFIG_SYS_UNIFY_CACHE
icache_invalid();
#endif
/* If nothing received - leave for() loop */
if (info->rxbd[info->rx_idx].cbd_sc & BD_ENET_RX_EMPTY)
break;
length = info->rxbd[info->rx_idx].cbd_datlen;
if (info->rxbd[info->rx_idx].cbd_sc & 0x003f) {
printf("%s[%d] err: %x\n",
__func__, __LINE__,
info->rxbd[info->rx_idx].cbd_sc);
} else {
length -= 4;
/*
* Pass the buffer ptr up to the protocol layers.
*/
*packetp = net_rx_packets[info->rx_idx];
fecp->eir |= FEC_EIR_RXF;
}
/* Give the buffer back to the FEC. */
info->rxbd[info->rx_idx].cbd_datlen = 0;
/* wrap around buffer index when necessary */
if (info->rx_idx == LAST_PKTBUFSRX) {
info->rxbd[PKTBUFSRX - 1].cbd_sc = BD_ENET_RX_W_E;
info->rx_idx = 0;
} else {
info->rxbd[info->rx_idx].cbd_sc = BD_ENET_RX_EMPTY;
info->rx_idx++;
}
/* Try to fill Buffer Descriptors
* Descriptor polling active
*/
fecp->rdar = 0x01000000;
}
return length;
}
static void mcffec_halt(struct udevice *dev)
{
struct fec_info_s *info = dev->priv;
fec_reset(dev);
fec_reset(info);
fecpin_setclear(info, 0);
fecpin_setclear(dev, 0);
info->rx_idx = 0;
info->tx_idx = 0;
info->rxIdx = info->txIdx = 0;
memset(info->rxbd, 0, PKTBUFSRX * sizeof(cbd_t));
memset(info->txbd, 0, TX_BUF_CNT * sizeof(cbd_t));
memset(info->txbuf, 0, DBUF_LENGTH);
}
int mcffec_initialize(bd_t * bis)
static const struct eth_ops mcffec_ops = {
.start = mcffec_init,
.send = mcffec_send,
.recv = mcffec_recv,
.stop = mcffec_halt,
};
/*
* Boot sequence, called just after mcffec_ofdata_to_platdata,
* as DM way, it replaces old mcffec_initialize.
*/
static int mcffec_probe(struct udevice *dev)
{
struct eth_device *dev;
int i;
#ifdef CONFIG_SYS_FEC_BUF_USE_SRAM
u32 tmp = CONFIG_SYS_INIT_RAM_ADDR + 0x1000;
#endif
struct eth_pdata *pdata = dev_get_platdata(dev);
struct fec_info_s *info = dev->priv;
int node = dev_of_offset(dev);
int retval, fec_idx;
const u32 *val;
for (i = 0; i < ARRAY_SIZE(fec_info); i++) {
info->index = dev->seq;
info->iobase = pdata->iobase;
info->phy_addr = -1;
dev =
(struct eth_device *)memalign(CONFIG_SYS_CACHELINE_SIZE,
sizeof *dev);
if (dev == NULL)
hang();
val = fdt_getprop(gd->fdt_blob, node, "mii-base", NULL);
if (val) {
u32 fec_iobase;
memset(dev, 0, sizeof(*dev));
fec_idx = fdt32_to_cpu(*val);
if (fec_idx == info->index) {
fec_iobase = info->iobase;
} else {
printf("mii base != base address, fec_idx %d\n",
fec_idx);
retval = fec_get_base_addr(fec_idx, &fec_iobase);
if (retval)
return retval;
}
info->miibase = fec_iobase;
}
sprintf(dev->name, "FEC%d", fec_info[i].index);
val = fdt_getprop(gd->fdt_blob, node, "phy-addr", NULL);
if (val)
info->phy_addr = fdt32_to_cpu(*val);
dev->priv = &fec_info[i];
dev->init = fec_init;
dev->halt = fec_halt;
dev->send = fec_send;
dev->recv = fec_recv;
val = fdt_getprop(gd->fdt_blob, node, "timeout-loop", NULL);
if (val)
info->to_loop = fdt32_to_cpu(*val);
/* setup Receive and Transmit buffer descriptor */
#ifdef CONFIG_SYS_FEC_BUF_USE_SRAM
fec_info[i].rxbd = (cbd_t *)((u32)fec_info[i].rxbd + tmp);
tmp = (u32)fec_info[i].rxbd;
fec_info[i].txbd =
(cbd_t *)((u32)fec_info[i].txbd + tmp +
(PKTBUFSRX * sizeof(cbd_t)));
tmp = (u32)fec_info[i].txbd;
fec_info[i].txbuf =
(char *)((u32)fec_info[i].txbuf + tmp +
(CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t)));
tmp = (u32)fec_info[i].txbuf;
#else
fec_info[i].rxbd =
(cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE,
(PKTBUFSRX * sizeof(cbd_t)));
fec_info[i].txbd =
(cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE,
(TX_BUF_CNT * sizeof(cbd_t)));
fec_info[i].txbuf =
(char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH);
#endif
#ifdef ET_DEBUG
printf("rxbd %x txbd %x\n",
(int)fec_info[i].rxbd, (int)fec_info[i].txbd);
#endif
fec_info[i].phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32);
eth_register(dev);
init_eth_info(info);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = mcffec_miiphy_read;
mdiodev->write = mcffec_miiphy_write;
info->bus = mdio_alloc();
if (!info->bus)
return -ENOMEM;
strcpy(info->bus->name, dev->name);
info->bus->read = mcffec_miiphy_read;
info->bus->write = mcffec_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
retval = mdio_register(info->bus);
if (retval < 0)
return retval;
#endif
if (i > 0)
fec_info[i - 1].next = &fec_info[i];
}
fec_info[i - 1].next = &fec_info[0];
/* default speed */
bis->bi_ethspeed = 10;
return 0;
}
static int mcffec_remove(struct udevice *dev)
{
struct fec_info_s *priv = dev_get_priv(dev);
mdio_unregister(priv->bus);
mdio_free(priv->bus);
return 0;
}
/*
* Boot sequence, called 1st
*/
static int mcffec_ofdata_to_platdata(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
const u32 *val;
pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
/* Default to 10Mbit/s */
pdata->max_speed = 10;
val = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
"max-speed", NULL);
if (val)
pdata->max_speed = fdt32_to_cpu(*val);
return 0;
}
static const struct udevice_id mcffec_ids[] = {
{ .compatible = "fsl,mcf-fec" },
{ }
};
U_BOOT_DRIVER(mcffec) = {
.name = "mcffec",
.id = UCLASS_ETH,
.of_match = mcffec_ids,
.ofdata_to_platdata = mcffec_ofdata_to_platdata,
.probe = mcffec_probe,
.remove = mcffec_remove,
.ops = &mcffec_ops,
.priv_auto_alloc_size = sizeof(struct fec_info_s),
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
};