This patch adds support for having a "fixed-link" to some other MAC (like some embedded switch-device). For this purpose we introduce a new phy-driver, called "Fixed PHY". Fixed PHY works only with CONFIG_DM_ETH enabled, since the fixed-link is described with a subnode below ethernet interface. Most ethernet drivers (unfortunately not all are following same scheme for searching/attaching phys) are calling "phy_connect(...)" for getting a phy-device. At this point we link in, we search here for a subnode called "fixed- link", once found we start phy_device_create(...) with the special phy- id PHY_FIXED_ID (0xa5a55a5a). During init the "Fixed PHY" driver has registered with this id and now gets probed, during probe we get all the details about fixed-link out of dts, later on the phy reports this values. Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com> Signed-off-by: Hannes Schmelzer <oe5hpm@oevsv.at> Acked-by: Joe Hershberger <joe.hershberger@ni.com> Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>master
parent
f8e57c650d
commit
db40c1aa1c
@ -0,0 +1,30 @@ |
||||
Fixed link Device Tree binding |
||||
------------------------------ |
||||
|
||||
Some Ethernet MACs have a "fixed link", and are not connected to a |
||||
normal MDIO-managed PHY device. For those situations, a Device Tree |
||||
binding allows to describe a "fixed link". |
||||
|
||||
Such a fixed link situation is described by creating a 'fixed-link' |
||||
sub-node of the Ethernet MAC device node, with the following |
||||
properties: |
||||
|
||||
* 'speed' (integer, mandatory), to indicate the link speed. Accepted |
||||
values are 10, 100 and 1000 |
||||
* 'full-duplex' (boolean, optional), to indicate that full duplex is |
||||
used. When absent, half duplex is assumed. |
||||
* 'pause' (boolean, optional), to indicate that pause should be |
||||
enabled. |
||||
* 'asym-pause' (boolean, optional), to indicate that asym_pause should |
||||
be enabled. |
||||
|
||||
Examples: |
||||
|
||||
ethernet@0 { |
||||
... |
||||
fixed-link { |
||||
speed = <1000>; |
||||
full-duplex; |
||||
}; |
||||
... |
||||
}; |
@ -0,0 +1,82 @@ |
||||
/*
|
||||
* Fixed-Link phy |
||||
* |
||||
* Copyright 2017 Bernecker & Rainer Industrieelektronik GmbH |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <config.h> |
||||
#include <common.h> |
||||
#include <phy.h> |
||||
#include <dm.h> |
||||
#include <fdt_support.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
int fixedphy_probe(struct phy_device *phydev) |
||||
{ |
||||
struct fixed_link *priv; |
||||
int ofnode = phydev->addr; |
||||
u32 val; |
||||
|
||||
/* check for mandatory properties within fixed-link node */ |
||||
val = fdt_getprop_u32_default_node(gd->fdt_blob, |
||||
ofnode, 0, "speed", 0); |
||||
if (val != SPEED_10 && val != SPEED_100 && val != SPEED_1000) { |
||||
printf("ERROR: no/invalid speed given in fixed-link node!"); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
priv = malloc(sizeof(*priv)); |
||||
if (!priv) |
||||
return -ENOMEM; |
||||
memset(priv, 0, sizeof(*priv)); |
||||
|
||||
phydev->priv = priv; |
||||
phydev->addr = 0; |
||||
|
||||
priv->link_speed = val; |
||||
priv->duplex = fdtdec_get_bool(gd->fdt_blob, ofnode, "full-duplex"); |
||||
priv->pause = fdtdec_get_bool(gd->fdt_blob, ofnode, "pause"); |
||||
priv->asym_pause = fdtdec_get_bool(gd->fdt_blob, ofnode, "asym-pause"); |
||||
|
||||
/* fixed-link phy must not be reset by core phy code */ |
||||
phydev->flags |= PHY_FLAG_BROKEN_RESET; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int fixedphy_startup(struct phy_device *phydev) |
||||
{ |
||||
struct fixed_link *priv = phydev->priv; |
||||
|
||||
phydev->asym_pause = priv->asym_pause; |
||||
phydev->pause = priv->pause; |
||||
phydev->duplex = priv->duplex; |
||||
phydev->speed = priv->link_speed; |
||||
phydev->link = 1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int fixedphy_shutdown(struct phy_device *phydev) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
static struct phy_driver fixedphy_driver = { |
||||
.uid = PHY_FIXED_ID, |
||||
.mask = 0xffffffff, |
||||
.name = "Fixed PHY", |
||||
.features = PHY_GBIT_FEATURES | SUPPORTED_MII, |
||||
.probe = fixedphy_probe, |
||||
.startup = fixedphy_startup, |
||||
.shutdown = fixedphy_shutdown, |
||||
}; |
||||
|
||||
int phy_fixed_init(void) |
||||
{ |
||||
phy_register(&fixedphy_driver); |
||||
return 0; |
||||
} |
Loading…
Reference in new issue