+#else /* CONFIG_DM_ETH */
+
+static int fm_eth_bind(struct udevice *dev)
+{
+ char mac_name[11];
+ u32 fm, num;
+
+ if (ofnode_read_u32(ofnode_get_parent(dev_ofnode(dev)), "cell-index", &fm)) {
+ printf("FMan node property cell-index missing\n");
+ return -EINVAL;
+ }
+
+ if (dev && dev_read_u32(dev, "cell-index", &num)) {
+ printf("FMan MAC node property cell-index missing\n");
+ return -EINVAL;
+ }
+
+ sprintf(mac_name, "fm%d-mac%d", fm + 1, num + 1);
+ device_set_name(dev, mac_name);
+
+ debug("%s - binding %s\n", __func__, mac_name);
+
+ return 0;
+}
+
+static struct udevice *fm_get_internal_mdio(struct udevice *dev)
+{
+ struct ofnode_phandle_args phandle = {.node = ofnode_null()};
+ struct udevice *mdiodev;
+
+ if (dev_read_phandle_with_args(dev, "pcsphy-handle", NULL,
+ 0, 0, &phandle) ||
+ !ofnode_valid(phandle.node)) {
+ if (dev_read_phandle_with_args(dev, "tbi-handle", NULL,
+ 0, 0, &phandle) ||
+ !ofnode_valid(phandle.node)) {
+ printf("Issue reading pcsphy-handle/tbi-handle for MAC %s\n",
+ dev->name);
+ return NULL;
+ }
+ }
+
+ if (uclass_get_device_by_ofnode(UCLASS_MDIO,
+ ofnode_get_parent(phandle.node),
+ &mdiodev)) {
+ printf("can't find MDIO bus for node %s\n",
+ ofnode_get_name(ofnode_get_parent(phandle.node)));
+ return NULL;
+ }
+ debug("Found internal MDIO bus %p\n", mdiodev);
+
+ return mdiodev;
+}
+
+static int fm_eth_probe(struct udevice *dev)
+{
+ struct fm_eth *fm_eth = (struct fm_eth *)dev_get_priv(dev);
+ struct ofnode_phandle_args args;
+ void *reg;
+ int ret, index;
+
+ debug("%s enter for dev %p fm_eth %p - %s\n", __func__, dev, fm_eth,
+ (dev) ? dev->name : "-");
+
+ if (fm_eth->dev) {
+ printf("%s already probed, exit\n", (dev) ? dev->name : "-");
+ return 0;
+ }
+
+ fm_eth->dev = dev;
+ fm_eth->fm_index = fman_id(dev->parent);
+ reg = (void *)(uintptr_t)dev_read_addr(dev);
+ fm_eth->mac_type = dev_get_driver_data(dev);
+#ifdef CONFIG_PHYLIB
+ fm_eth->enet_if = dev_read_phy_mode(dev);
+#else
+ fm_eth->enet_if = PHY_INTERFACE_MODE_SGMII;
+ printf("%s: warning - unable to determine interface type\n", __func__);
+#endif
+ switch (fm_eth->mac_type) {
+#ifndef CONFIG_SYS_FMAN_V3
+ case FM_TGEC:
+ fm_eth->type = FM_ETH_10G_E;
+ break;
+ case FM_DTSEC:
+#else
+ case FM_MEMAC:
+ /* default to 1G, 10G is indicated by port property in dts */
+#endif
+ fm_eth->type = FM_ETH_1G_E;
+ break;
+ }
+
+ if (dev_read_u32(dev, "cell-index", &fm_eth->num)) {
+ printf("FMan MAC node property cell-index missing\n");
+ return -EINVAL;
+ }
+
+ if (dev_read_phandle_with_args(dev, "fsl,fman-ports", NULL,
+ 0, 0, &args))
+ goto ports_ref_failure;
+ index = ofnode_read_u32_default(args.node, "cell-index", 0);
+ if (index <= 0)
+ goto ports_ref_failure;
+ fm_eth->rx_port = fman_port(dev->parent, index);
+
+ if (ofnode_read_bool(args.node, "fsl,fman-10g-port"))
+ fm_eth->type = FM_ETH_10G_E;
+
+ if (dev_read_phandle_with_args(dev, "fsl,fman-ports", NULL,
+ 0, 1, &args))
+ goto ports_ref_failure;
+ index = ofnode_read_u32_default(args.node, "cell-index", 0);
+ if (index <= 0)
+ goto ports_ref_failure;
+ fm_eth->tx_port = fman_port(dev->parent, index);
+
+ /* set the ethernet max receive length */
+ fm_eth->max_rx_len = MAX_RXBUF_LEN;
+
+ switch (fm_eth->enet_if) {
+ case PHY_INTERFACE_MODE_QSGMII:
+ /* all PCS blocks are accessed on one controller */
+ if (fm_eth->num != 0)
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_2500BASEX:
+ fm_eth->pcs_mdio = fm_get_internal_mdio(dev);
+ break;
+ default:
+ break;
+ }
+
+ /* init global mac structure */
+ ret = fm_eth_init_mac(fm_eth, reg);
+ if (ret)
+ return ret;
+
+ /* startup the FM im */
+ ret = fm_eth_startup(fm_eth);
+
+ if (!ret)
+ ret = init_phy(fm_eth);
+
+ return ret;
+
+ports_ref_failure:
+ printf("Issue reading fsl,fman-ports for MAC %s\n", dev->name);
+ return -ENOENT;
+}
+
+static int fm_eth_remove(struct udevice *dev)
+{
+ return 0;
+}
+
+static const struct eth_ops fm_eth_ops = {
+ .start = fm_eth_open,
+ .send = fm_eth_send,
+ .recv = fm_eth_recv,
+ .free_pkt = fm_eth_free_pkt,
+ .stop = fm_eth_halt,
+};
+
+static const struct udevice_id fm_eth_ids[] = {
+#ifdef CONFIG_SYS_FMAN_V3
+ { .compatible = "fsl,fman-memac", .data = FM_MEMAC },
+#else
+ { .compatible = "fsl,fman-dtsec", .data = FM_DTSEC },
+ { .compatible = "fsl,fman-xgec", .data = FM_TGEC },
+#endif
+ {}
+};
+
+U_BOOT_DRIVER(eth_fman) = {
+ .name = "eth_fman",
+ .id = UCLASS_ETH,
+ .of_match = fm_eth_ids,
+ .bind = fm_eth_bind,
+ .probe = fm_eth_probe,
+ .remove = fm_eth_remove,
+ .ops = &fm_eth_ops,
+ .priv_auto = sizeof(struct fm_eth),
+ .plat_auto = sizeof(struct eth_pdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif /* CONFIG_DM_ETH */