uboot/drivers/net/eth-phy-uclass.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2020 NXP
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <net.h>
   9#include <dm/device-internal.h>
  10#include <dm/uclass-internal.h>
  11#include <dm/lists.h>
  12
  13struct eth_phy_device_priv {
  14        struct mii_dev *mdio_bus;
  15};
  16
  17int eth_phy_binds_nodes(struct udevice *eth_dev)
  18{
  19        ofnode mdio_node, phy_node;
  20        const char *node_name;
  21        int ret;
  22
  23        mdio_node = dev_read_subnode(eth_dev, "mdio");
  24        if (!ofnode_valid(mdio_node)) {
  25                debug("%s: %s mdio subnode not found!", __func__,
  26                      eth_dev->name);
  27                return -ENXIO;
  28        }
  29
  30        ofnode_for_each_subnode(phy_node, mdio_node) {
  31                node_name = ofnode_get_name(phy_node);
  32
  33                debug("* Found child node: '%s'\n", node_name);
  34
  35                ret = device_bind_driver_to_node(eth_dev,
  36                                                 "eth_phy_generic_drv",
  37                                                 node_name, phy_node, NULL);
  38                if (ret) {
  39                        debug("  - Eth phy binding error: %d\n", ret);
  40                        continue;
  41                }
  42
  43                debug("  - bound phy device: '%s'\n", node_name);
  44        }
  45
  46        return 0;
  47}
  48
  49int eth_phy_set_mdio_bus(struct udevice *eth_dev, struct mii_dev *mdio_bus)
  50{
  51        struct udevice *dev;
  52        struct eth_phy_device_priv *uc_priv;
  53
  54        for (uclass_first_device(UCLASS_ETH_PHY, &dev); dev;
  55             uclass_next_device(&dev)) {
  56                if (dev->parent == eth_dev) {
  57                        uc_priv = (struct eth_phy_device_priv *)(dev_get_uclass_priv(dev));
  58
  59                        if (!uc_priv->mdio_bus)
  60                                uc_priv->mdio_bus = mdio_bus;
  61                }
  62        }
  63
  64        return 0;
  65}
  66
  67struct mii_dev *eth_phy_get_mdio_bus(struct udevice *eth_dev)
  68{
  69        int ret;
  70        struct udevice *phy_dev;
  71        struct eth_phy_device_priv *uc_priv;
  72
  73        /* Will probe the parent of phy device, then phy device */
  74        ret = uclass_get_device_by_phandle(UCLASS_ETH_PHY, eth_dev,
  75                                           "phy-handle", &phy_dev);
  76        if (!ret) {
  77                if (eth_dev != phy_dev->parent) {
  78                        /*
  79                         * phy_dev is shared and controlled by
  80                         * other eth controller
  81                         */
  82                        uc_priv = (struct eth_phy_device_priv *)(dev_get_uclass_priv(phy_dev));
  83                        if (uc_priv->mdio_bus)
  84                                printf("Get shared mii bus on %s\n", eth_dev->name);
  85                        else
  86                                printf("Can't get shared mii bus on %s\n", eth_dev->name);
  87
  88                        return uc_priv->mdio_bus;
  89                }
  90        } else {
  91                printf("FEC: can't find phy-handle\n");
  92        }
  93
  94        return NULL;
  95}
  96
  97int eth_phy_get_addr(struct udevice *dev)
  98{
  99        struct ofnode_phandle_args phandle_args;
 100        int reg;
 101
 102        if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
 103                                       &phandle_args)) {
 104                debug("Failed to find phy-handle");
 105                return -ENODEV;
 106        }
 107
 108        reg = ofnode_read_u32_default(phandle_args.node, "reg", 0);
 109
 110        return reg;
 111}
 112
 113UCLASS_DRIVER(eth_phy_generic) = {
 114        .id             = UCLASS_ETH_PHY,
 115        .name           = "eth_phy_generic",
 116        .per_device_auto        = sizeof(struct eth_phy_device_priv),
 117};
 118
 119U_BOOT_DRIVER(eth_phy_generic_drv) = {
 120        .name           = "eth_phy_generic_drv",
 121        .id             = UCLASS_ETH_PHY,
 122};
 123