From 81844aced3105af39d60efa3aed1ced9dc14f6e3 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 12 May 2022 15:48:51 +0200 Subject: [PATCH] net: mpc8xx_fec: Migrate to DM_ETH Migrate mpc8xx_fec driver to DM_ETH. Signed-off-by: Christophe Leroy Reviewed-by: Ramon Fried --- arch/powerpc/cpu/mpc8xx/cpu.c | 12 --- arch/powerpc/dts/mcr3000.dts | 4 + configs/MCR3000_defconfig | 1 + drivers/net/Kconfig | 1 + drivers/net/mpc8xx_fec.c | 189 ++++++++++++++++++---------------- include/netdev.h | 1 - 6 files changed, 104 insertions(+), 104 deletions(-) diff --git a/arch/powerpc/cpu/mpc8xx/cpu.c b/arch/powerpc/cpu/mpc8xx/cpu.c index 6d16ed084e..0ccb9f6df6 100644 --- a/arch/powerpc/cpu/mpc8xx/cpu.c +++ b/arch/powerpc/cpu/mpc8xx/cpu.c @@ -266,15 +266,3 @@ unsigned long get_tbclk(void) 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; -} diff --git a/arch/powerpc/dts/mcr3000.dts b/arch/powerpc/dts/mcr3000.dts index 5abf111dc5..5f32d8a2e5 100644 --- a/arch/powerpc/dts/mcr3000.dts +++ b/arch/powerpc/dts/mcr3000.dts @@ -16,6 +16,10 @@ compatible = "fsl,pq1-smc"; }; + FEC: fec@0 { + compatible = "fsl,pq1-fec1"; + }; + chosen { stdout-path = &SERIAL; }; diff --git a/configs/MCR3000_defconfig b/configs/MCR3000_defconfig index 086507e601..94743d69d1 100644 --- a/configs/MCR3000_defconfig +++ b/configs/MCR3000_defconfig @@ -91,3 +91,4 @@ CONFIG_DM_SERIAL=y CONFIG_WDT=y CONFIG_SHA256=y CONFIG_LZMA=y +CONFIG_DM_ETH=y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 93e7dbe976..0070ff73ea 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -744,6 +744,7 @@ config RENESAS_RAVB config MPC8XX_FEC bool "Fast Ethernet Controller on MPC8XX" depends on MPC8xx + depends on DM_ETH select MII select SYS_DISCOVER_PHY help diff --git a/drivers/net/mpc8xx_fec.c b/drivers/net/mpc8xx_fec.c index 4eb8260281..78337731e1 100644 --- a/drivers/net/mpc8xx_fec.c +++ b/drivers/net/mpc8xx_fec.c @@ -41,7 +41,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif #ifdef CONFIG_SYS_DISCOVER_PHY -static int mii_discover_phy(struct eth_device *dev); +static int mii_discover_phy(struct udevice *dev); #endif 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 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) static void __mii_init(void); #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; + struct ether_fcc_info_s *efis = dev_get_priv(dev); + int index = dev_get_driver_data(dev); int i; for (i = 0; i < ARRAY_SIZE(ether_fcc_info); i++) { - dev = malloc(sizeof(*dev)); - if (dev == NULL) - hang(); + if (ether_fcc_info[i].ether_index != index) + continue; - memset(dev, 0, sizeof(*dev)); + memcpy(efis, ðer_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 = ðer_fcc_info[i]; - - /* - * reset actual phy addr - */ 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) int retval; struct mii_dev *mdiodev = mdio_alloc(); @@ -169,13 +143,13 @@ int fec_initialize(struct bd_info *bis) return retval; #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; - 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 *)(CONFIG_SYS_IMMR + efis->fecp_offset); @@ -217,59 +191,57 @@ static int fec_send(struct eth_device *dev, void *packet, int length) 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; - for (;;) { - /* section 16.9.23.2 */ - if (in_be16(&rtx->rxbd[rxIdx].cbd_sc) & BD_ENET_RX_EMPTY) { - length = -1; - break; /* nothing received - leave for() loop */ - } - - length = in_be16(&rtx->rxbd[rxIdx].cbd_datlen); + /* section 16.9.23.2 */ + if (in_be16(&rtx->rxbd[rxIdx].cbd_sc) & BD_ENET_RX_EMPTY) + return -EAGAIN; - if (!(in_be16(&rtx->rxbd[rxIdx].cbd_sc) & 0x003f)) { - uchar *rx = net_rx_packets[rxIdx]; + length = in_be16(&rtx->rxbd[rxIdx].cbd_datlen); - length -= 4; + if (!(in_be16(&rtx->rxbd[rxIdx].cbd_sc) & 0x003f)) { + uchar *rx = net_rx_packets[rxIdx]; #if defined(CONFIG_CMD_CDP) - if ((rx[0] & 1) != 0 && - memcmp((uchar *)rx, net_bcast_ethaddr, 6) != 0 && - !is_cdp_packet((uchar *)rx)) - rx = NULL; + if ((rx[0] & 1) != 0 && + memcmp((uchar *)rx, net_bcast_ethaddr, 6) != 0 && + !is_cdp_packet((uchar *)rx)) + return 0; #endif - /* - * Pass the packet up to the protocol layers. - */ - if (rx != NULL) - net_process_received_packet(rx, length); - } + *packetp = rx; - /* Give the buffer back to the FEC. */ - out_be16(&rtx->rxbd[rxIdx].cbd_datlen, 0); - - /* 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 - 4; + } else { + return 0; + } +} - /* Try to fill Buffer Descriptors */ - /* Descriptor polling active */ - out_be32(&fecp->fec_r_des_active, 0x01000000); +static int fec_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct ether_fcc_info_s *efis = dev_get_priv(dev); + fec_t __iomem *fecp = + (fec_t __iomem *)(CONFIG_SYS_IMMR + efis->fecp_offset); + + /* Give the buffer back to the FEC. */ + out_be16(&rtx->rxbd[rxIdx].cbd_datlen, 0); + + /* 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) -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; uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008; 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); } -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; uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008; immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR; @@ -324,9 +296,9 @@ static inline void fec_100Mbps(struct eth_device *dev) #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 *)(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 */ } -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 *)(CONFIG_SYS_IMMR + efis->fecp_offset); @@ -497,9 +469,10 @@ static int fec_reset(fec_t __iomem *fecp) 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; fec_t __iomem *fecp = (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 */ -#define ea dev->enetaddr +#define ea plat->enetaddr out_be32(&fecp->fec_addr_low, (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | ea[3]); 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 *)(CONFIG_SYS_IMMR + efis->fecp_offset); int i; @@ -750,7 +723,7 @@ mii_send(uint mii_cmd) #endif #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 uint phyno; @@ -854,3 +827,37 @@ int fec8xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg, return 0; } #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), +}; diff --git a/include/netdev.h b/include/netdev.h index fb18f09893..b3f8584e90 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -42,7 +42,6 @@ int eepro100_initialize(struct bd_info *bis); int ep93xx_eth_initialize(u8 dev_num, int base_addr); int eth_3com_initialize (struct bd_info * bis); 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_multi(struct bd_info *bis, int dev_id, int phy_id, uint32_t addr); -- 2.39.5