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 <common.h>
10 #include <malloc.h>
11 #include <phy.h>
12 #include <dm.h>
13 #include <fdt_support.h>
14 #include <asm/global_data.h>
15 
16 DECLARE_GLOBAL_DATA_PTR;
17 
fixedphy_probe(struct phy_device * phydev)18 int fixedphy_probe(struct phy_device *phydev)
19 {
20 	struct fixed_link *priv;
21 	int ofnode = phydev->addr;
22 	u32 val;
23 
24 	/* check for mandatory properties within fixed-link node */
25 	val = fdt_getprop_u32_default_node(gd->fdt_blob,
26 					   ofnode, 0, "speed", 0);
27 	if (val != SPEED_10 && val != SPEED_100 && val != SPEED_1000 &&
28 	    val != SPEED_2500 && val != SPEED_10000) {
29 		printf("ERROR: no/invalid speed given in fixed-link node!");
30 		return -EINVAL;
31 	}
32 
33 	priv = malloc(sizeof(*priv));
34 	if (!priv)
35 		return -ENOMEM;
36 	memset(priv, 0, sizeof(*priv));
37 
38 	phydev->priv = priv;
39 
40 	priv->link_speed = val;
41 	priv->duplex = fdtdec_get_bool(gd->fdt_blob, ofnode, "full-duplex");
42 	priv->pause = fdtdec_get_bool(gd->fdt_blob, ofnode, "pause");
43 	priv->asym_pause = fdtdec_get_bool(gd->fdt_blob, ofnode, "asym-pause");
44 
45 	/* fixed-link phy must not be reset by core phy code */
46 	phydev->flags |= PHY_FLAG_BROKEN_RESET;
47 
48 	return 0;
49 }
50 
fixedphy_startup(struct phy_device * phydev)51 int fixedphy_startup(struct phy_device *phydev)
52 {
53 	struct fixed_link *priv = phydev->priv;
54 
55 	phydev->asym_pause = priv->asym_pause;
56 	phydev->pause = priv->pause;
57 	phydev->duplex = priv->duplex;
58 	phydev->speed = priv->link_speed;
59 	phydev->link = 1;
60 
61 	return 0;
62 }
63 
fixedphy_shutdown(struct phy_device * phydev)64 int fixedphy_shutdown(struct phy_device *phydev)
65 {
66 	return 0;
67 }
68 
69 static struct phy_driver fixedphy_driver = {
70 	.uid		= PHY_FIXED_ID,
71 	.mask		= 0xffffffff,
72 	.name		= "Fixed PHY",
73 	.features	= PHY_GBIT_FEATURES | SUPPORTED_MII,
74 	.probe		= fixedphy_probe,
75 	.startup	= fixedphy_startup,
76 	.shutdown	= fixedphy_shutdown,
77 };
78 
phy_fixed_init(void)79 int phy_fixed_init(void)
80 {
81 	phy_register(&fixedphy_driver);
82 	return 0;
83 }
84