"Das U-Boot" Source Tree
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Fixed-Link phy
4 *
5 * Copyright 2017 Bernecker & Rainer Industrieelektronik GmbH
6 */
7
8#include <config.h>
9#include <malloc.h>
10#include <phy.h>
11#include <dm.h>
12#include <fdt_support.h>
13#include <asm/global_data.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
17static int fixedphy_probe(struct phy_device *phydev)
18{
19 /* fixed-link phy must not be reset by core phy code */
20 phydev->flags |= PHY_FLAG_BROKEN_RESET;
21
22 return 0;
23}
24
25static int fixedphy_config(struct phy_device *phydev)
26{
27 ofnode node = phy_get_ofnode(phydev);
28 struct fixed_link *priv;
29 bool old_binding = false;
30 u32 old_val[5];
31 u32 val;
32
33 if (!ofnode_valid(node))
34 return -EINVAL;
35
36 /* check for mandatory properties within fixed-link node */
37 val = ofnode_read_u32_default(node, "speed", 0);
38
39 if (!val) {
40 /* try old binding */
41 old_binding = true;
42 if (ofnode_read_u32_array(node, "fixed-link", old_val,
43 ARRAY_SIZE(old_val))) {
44 printf("ERROR: no/invalid <fixed-link> property!\n");
45 return -ENOENT;
46 }
47 val = old_val[2];
48 }
49
50 if (val != SPEED_10 && val != SPEED_100 && val != SPEED_1000 &&
51 val != SPEED_2500 && val != SPEED_10000) {
52 printf("ERROR: no/invalid speed given in fixed-link node!\n");
53 return -EINVAL;
54 }
55
56 priv = malloc(sizeof(*priv));
57 if (!priv)
58 return -ENOMEM;
59 memset(priv, 0, sizeof(*priv));
60
61 phydev->priv = priv;
62
63 priv->link_speed = val;
64 if (!old_binding) {
65 priv->duplex = ofnode_read_bool(node, "full-duplex");
66 priv->pause = ofnode_read_bool(node, "pause");
67 priv->asym_pause = ofnode_read_bool(node, "asym-pause");
68 } else {
69 priv->duplex = old_val[1];
70 priv->pause = old_val[3];
71 priv->asym_pause = old_val[4];
72 }
73
74 return 0;
75}
76
77static int fixedphy_startup(struct phy_device *phydev)
78{
79 struct fixed_link *priv = phydev->priv;
80
81 phydev->asym_pause = priv->asym_pause;
82 phydev->pause = priv->pause;
83 phydev->duplex = priv->duplex;
84 phydev->speed = priv->link_speed;
85 phydev->link = 1;
86
87 return 0;
88}
89
90static int fixedphy_shutdown(struct phy_device *phydev)
91{
92 return 0;
93}
94
95U_BOOT_PHY_DRIVER(fixedphy) = {
96 .uid = PHY_FIXED_ID,
97 .mask = 0xffffffff,
98 .name = "Fixed PHY",
99 .features = PHY_GBIT_FEATURES | SUPPORTED_MII,
100 .probe = fixedphy_probe,
101 .config = fixedphy_config,
102 .startup = fixedphy_startup,
103 .shutdown = fixedphy_shutdown,
104};