net: mpc8xx_fec: Migrate to DM_ETH

Migrate mpc8xx_fec driver to DM_ETH.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
This commit is contained in:
Christophe Leroy 2022-05-12 15:48:51 +02:00 committed by Tom Rini
parent c62b74652a
commit 81844aced3
6 changed files with 103 additions and 103 deletions

View file

@ -266,15 +266,3 @@ unsigned long get_tbclk(void)
return oscclk / 16; return oscclk / 16;
} }
/*
* Initializes on-chip ethernet controllers.
* to override, implement board_eth_init()
*/
int cpu_eth_init(struct bd_info *bis)
{
#if defined(CONFIG_MPC8XX_FEC)
fec_initialize(bis);
#endif
return 0;
}

View file

@ -16,6 +16,10 @@
compatible = "fsl,pq1-smc"; compatible = "fsl,pq1-smc";
}; };
FEC: fec@0 {
compatible = "fsl,pq1-fec1";
};
chosen { chosen {
stdout-path = &SERIAL; stdout-path = &SERIAL;
}; };

View file

@ -91,3 +91,4 @@ CONFIG_DM_SERIAL=y
CONFIG_WDT=y CONFIG_WDT=y
CONFIG_SHA256=y CONFIG_SHA256=y
CONFIG_LZMA=y CONFIG_LZMA=y
CONFIG_DM_ETH=y

View file

@ -744,6 +744,7 @@ config RENESAS_RAVB
config MPC8XX_FEC config MPC8XX_FEC
bool "Fast Ethernet Controller on MPC8XX" bool "Fast Ethernet Controller on MPC8XX"
depends on MPC8xx depends on MPC8xx
depends on DM_ETH
select MII select MII
select SYS_DISCOVER_PHY select SYS_DISCOVER_PHY
help help

View file

@ -41,7 +41,7 @@ DECLARE_GLOBAL_DATA_PTR;
#endif #endif
#ifdef CONFIG_SYS_DISCOVER_PHY #ifdef CONFIG_SYS_DISCOVER_PHY
static int mii_discover_phy(struct eth_device *dev); static int mii_discover_phy(struct udevice *dev);
#endif #endif
int fec8xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg); int fec8xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg);
@ -111,50 +111,24 @@ struct common_buf_desc {
static struct common_buf_desc __iomem *rtx; static struct common_buf_desc __iomem *rtx;
static int fec_send(struct eth_device *dev, void *packet, int length);
static int fec_recv(struct eth_device *dev);
static int fec_init(struct eth_device *dev, struct bd_info *bd);
static void fec_halt(struct eth_device *dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
static void __mii_init(void); static void __mii_init(void);
#endif #endif
int fec_initialize(struct bd_info *bis) static int fec_probe(struct udevice *dev)
{ {
struct eth_device *dev; struct ether_fcc_info_s *efis = dev_get_priv(dev);
struct ether_fcc_info_s *efis; int index = dev_get_driver_data(dev);
int i; int i;
for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++) { for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++) {
dev = malloc(sizeof(*dev)); if (ether_fcc_info[i].ether_index != index)
if (dev == NULL) continue;
hang();
memset(dev, 0, sizeof(*dev)); memcpy(efis, &ether_fcc_info[i], sizeof(*efis));
/* for FEC1 make sure that the name of the interface is the same
as the old one for compatibility reasons */
if (i == 0)
strcpy(dev->name, "FEC");
else
sprintf(dev->name, "FEC%d",
ether_fcc_info[i].ether_index + 1);
efis = &ether_fcc_info[i];
/*
* reset actual phy addr
*/
efis->actual_phy_addr = -1; efis->actual_phy_addr = -1;
dev->priv = efis;
dev->init = fec_init;
dev->halt = fec_halt;
dev->send = fec_send;
dev->recv = fec_recv;
eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
int retval; int retval;
struct mii_dev *mdiodev = mdio_alloc(); struct mii_dev *mdiodev = mdio_alloc();
@ -169,13 +143,13 @@ int fec_initialize(struct bd_info *bis)
return retval; return retval;
#endif #endif
} }
return 1; return 0;
} }
static int fec_send(struct eth_device *dev, void *packet, int length) static int fec_send(struct udevice *dev, void *packet, int length)
{ {
int j, rc; int j, rc;
struct ether_fcc_info_s *efis = dev->priv; struct ether_fcc_info_s *efis = dev_get_priv(dev);
fec_t __iomem *fecp = fec_t __iomem *fecp =
(fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset); (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
@ -217,59 +191,57 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
return rc; return rc;
} }
static int fec_recv(struct eth_device *dev) static int fec_recv(struct udevice *dev, int flags, uchar **packetp)
{ {
struct ether_fcc_info_s *efis = dev->priv;
fec_t __iomem *fecp =
(fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
int length; int length;
for (;;) { /* section 16.9.23.2 */
/* section 16.9.23.2 */ if (in_be16(&rtx->rxbd[rxIdx].cbd_sc) & BD_ENET_RX_EMPTY)
if (in_be16(&rtx->rxbd[rxIdx].cbd_sc) & BD_ENET_RX_EMPTY) { return -EAGAIN;
length = -1;
break; /* nothing received - leave for() loop */
}
length = in_be16(&rtx->rxbd[rxIdx].cbd_datlen); length = in_be16(&rtx->rxbd[rxIdx].cbd_datlen);
if (!(in_be16(&rtx->rxbd[rxIdx].cbd_sc) & 0x003f)) { if (!(in_be16(&rtx->rxbd[rxIdx].cbd_sc) & 0x003f)) {
uchar *rx = net_rx_packets[rxIdx]; uchar *rx = net_rx_packets[rxIdx];
length -= 4;
#if defined(CONFIG_CMD_CDP) #if defined(CONFIG_CMD_CDP)
if ((rx[0] & 1) != 0 && if ((rx[0] & 1) != 0 &&
memcmp((uchar *)rx, net_bcast_ethaddr, 6) != 0 && memcmp((uchar *)rx, net_bcast_ethaddr, 6) != 0 &&
!is_cdp_packet((uchar *)rx)) !is_cdp_packet((uchar *)rx))
rx = NULL; return 0;
#endif #endif
/* *packetp = rx;
* Pass the packet up to the protocol layers.
*/
if (rx != NULL)
net_process_received_packet(rx, length);
}
/* Give the buffer back to the FEC. */ return length - 4;
out_be16(&rtx->rxbd[rxIdx].cbd_datlen, 0); } else {
return 0;
}
}
/* wrap around buffer index when necessary */ static int fec_free_pkt(struct udevice *dev, uchar *packet, int length)
if ((rxIdx + 1) >= PKTBUFSRX) { {
out_be16(&rtx->rxbd[PKTBUFSRX - 1].cbd_sc, struct ether_fcc_info_s *efis = dev_get_priv(dev);
BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY); fec_t __iomem *fecp =
rxIdx = 0; (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
} else {
out_be16(&rtx->rxbd[rxIdx].cbd_sc, BD_ENET_RX_EMPTY);
rxIdx++;
}
/* Try to fill Buffer Descriptors */ /* Give the buffer back to the FEC. */
/* Descriptor polling active */ out_be16(&rtx->rxbd[rxIdx].cbd_datlen, 0);
out_be32(&fecp->fec_r_des_active, 0x01000000);
/* wrap around buffer index when necessary */
if ((rxIdx + 1) >= PKTBUFSRX) {
out_be16(&rtx->rxbd[PKTBUFSRX - 1].cbd_sc,
BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
rxIdx = 0;
} else {
out_be16(&rtx->rxbd[rxIdx].cbd_sc, BD_ENET_RX_EMPTY);
rxIdx++;
} }
return length; /* Try to fill Buffer Descriptors */
/* Descriptor polling active */
out_be32(&fecp->fec_r_des_active, 0x01000000);
return 0;
} }
/************************************************************** /**************************************************************
@ -296,9 +268,9 @@ static int fec_recv(struct eth_device *dev)
#if defined(CONFIG_RMII) #if defined(CONFIG_RMII)
static inline void fec_10Mbps(struct eth_device *dev) static inline void fec_10Mbps(struct udevice *dev)
{ {
struct ether_fcc_info_s *efis = dev->priv; struct ether_fcc_info_s *efis = dev_get_priv(dev);
int fecidx = efis->ether_index; int fecidx = efis->ether_index;
uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008; uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008;
immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR; immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
@ -309,9 +281,9 @@ static inline void fec_10Mbps(struct eth_device *dev)
setbits_be32(&immr->im_cpm.cp_cptr, mask); setbits_be32(&immr->im_cpm.cp_cptr, mask);
} }
static inline void fec_100Mbps(struct eth_device *dev) static inline void fec_100Mbps(struct udevice *dev)
{ {
struct ether_fcc_info_s *efis = dev->priv; struct ether_fcc_info_s *efis = dev_get_priv(dev);
int fecidx = efis->ether_index; int fecidx = efis->ether_index;
uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008; uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008;
immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR; immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
@ -324,9 +296,9 @@ static inline void fec_100Mbps(struct eth_device *dev)
#endif #endif
static inline void fec_full_duplex(struct eth_device *dev) static inline void fec_full_duplex(struct udevice *dev)
{ {
struct ether_fcc_info_s *efis = dev->priv; struct ether_fcc_info_s *efis = dev_get_priv(dev);
fec_t __iomem *fecp = fec_t __iomem *fecp =
(fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset); (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
@ -334,9 +306,9 @@ static inline void fec_full_duplex(struct eth_device *dev)
setbits_be32(&fecp->fec_x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */ setbits_be32(&fecp->fec_x_cntrl, FEC_TCNTRL_FDEN); /* FD enable */
} }
static inline void fec_half_duplex(struct eth_device *dev) static inline void fec_half_duplex(struct udevice *dev)
{ {
struct ether_fcc_info_s *efis = dev->priv; struct ether_fcc_info_s *efis = dev_get_priv(dev);
fec_t __iomem *fecp = fec_t __iomem *fecp =
(fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset); (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
@ -497,9 +469,10 @@ static int fec_reset(fec_t __iomem *fecp)
return 0; return 0;
} }
static int fec_init(struct eth_device *dev, struct bd_info *bd) static int fec_start(struct udevice *dev)
{ {
struct ether_fcc_info_s *efis = dev->priv; struct eth_pdata *plat = dev_get_plat(dev);
struct ether_fcc_info_s *efis = dev_get_priv(dev);
immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR; immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
fec_t __iomem *fecp = fec_t __iomem *fecp =
(fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset); (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
@ -529,7 +502,7 @@ static int fec_init(struct eth_device *dev, struct bd_info *bd)
/* Set station address /* Set station address
*/ */
#define ea dev->enetaddr #define ea plat->enetaddr
out_be32(&fecp->fec_addr_low, (ea[0] << 24) | (ea[1] << 16) | out_be32(&fecp->fec_addr_low, (ea[0] << 24) | (ea[1] << 16) |
(ea[2] << 8) | ea[3]); (ea[2] << 8) | ea[3]);
out_be16(&fecp->fec_addr_high, (ea[4] << 8) | ea[5]); out_be16(&fecp->fec_addr_high, (ea[4] << 8) | ea[5]);
@ -665,9 +638,9 @@ static int fec_init(struct eth_device *dev, struct bd_info *bd)
} }
static void fec_halt(struct eth_device *dev) static void fec_stop(struct udevice *dev)
{ {
struct ether_fcc_info_s *efis = dev->priv; struct ether_fcc_info_s *efis = dev_get_priv(dev);
fec_t __iomem *fecp = fec_t __iomem *fecp =
(fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset); (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset);
int i; int i;
@ -750,7 +723,7 @@ mii_send(uint mii_cmd)
#endif #endif
#if defined(CONFIG_SYS_DISCOVER_PHY) #if defined(CONFIG_SYS_DISCOVER_PHY)
static int mii_discover_phy(struct eth_device *dev) static int mii_discover_phy(struct udevice *dev)
{ {
#define MAX_PHY_PASSES 11 #define MAX_PHY_PASSES 11
uint phyno; uint phyno;
@ -854,3 +827,37 @@ int fec8xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
return 0; return 0;
} }
#endif #endif
static const struct eth_ops fec_ops = {
.start = fec_start,
.send = fec_send,
.recv = fec_recv,
.stop = fec_stop,
.free_pkt = fec_free_pkt,
};
static const struct udevice_id fec_ids[] = {
#ifdef CONFIG_ETHER_ON_FEC1
{
.compatible = "fsl,pq1-fec1",
.data = 0,
},
#endif
#ifdef CONFIG_ETHER_ON_FEC2
{
.compatible = "fsl,pq1-fec2",
.data = 1,
},
#endif
{ }
};
U_BOOT_DRIVER(fec) = {
.name = "fec",
.id = UCLASS_ETH,
.of_match = fec_ids,
.probe = fec_probe,
.ops = &fec_ops,
.priv_auto = sizeof(struct ether_fcc_info_s),
.plat_auto = sizeof(struct eth_pdata),
};

View file

@ -42,7 +42,6 @@ int eepro100_initialize(struct bd_info *bis);
int ep93xx_eth_initialize(u8 dev_num, int base_addr); int ep93xx_eth_initialize(u8 dev_num, int base_addr);
int eth_3com_initialize (struct bd_info * bis); int eth_3com_initialize (struct bd_info * bis);
int ethoc_initialize(u8 dev_num, int base_addr); int ethoc_initialize(u8 dev_num, int base_addr);
int fec_initialize (struct bd_info *bis);
int fecmxc_initialize(struct bd_info *bis); int fecmxc_initialize(struct bd_info *bis);
int fecmxc_initialize_multi(struct bd_info *bis, int dev_id, int phy_id, int fecmxc_initialize_multi(struct bd_info *bis, int dev_id, int phy_id,
uint32_t addr); uint32_t addr);