of_mdio: add new DT property 'managed' to specify the PHY management type

Currently the PHY management type is selected by the MAC driver arbitrary.
The decision is based on the presence of the "fixed-link" node and on a
will of the driver's authors.
This caused a regression recently, when mvneta driver suddenly started
to use the in-band status for auto-negotiation on fixed links.
It appears the auto-negotiation may not work when expected by the MAC driver.
Sebastien Rannou explains:
<< Yes, I confirm that my HW does not generate an in-band status. AFAIK, it's
a PHY that aggregates 4xSGMIIs to 1xQSGMII ; the MAC side of the PHY (with
inband status) is connected to the switch through QSGMII, and in this context
we are on the media side of the PHY. >>
https://lkml.org/lkml/2015/7/10/206

This patch introduces the new string property 'managed' that allows
the user to set the management type explicitly.
The supported values are:
"auto" - default. Uses either MDIO or nothing, depending on the presence
of the fixed-link node
"in-band-status" - use in-band status

Signed-off-by: Stas Sergeev <[email protected]>

CC: Rob Herring <[email protected]>
CC: Pawel Moll <[email protected]>
CC: Mark Rutland <[email protected]>
CC: Ian Campbell <[email protected]>
CC: Kumar Gala <[email protected]>
CC: Florian Fainelli <[email protected]>
CC: Grant Likely <[email protected]>
CC: [email protected]
CC: [email protected]
CC: [email protected]
Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
Stas Sergeev 2015-07-20 17:49:57 -07:00 • committed by David S. Miller
commit 4cba5c2103
2 changed files with 21 additions and 2 deletions

View file

@ -266,7 +266,8 @@ EXPORT_SYMBOL(of_phy_attach);
bool of_phy_is_fixed_link(struct device_node *np)
{
struct device_node *dn;
int len;
int len, err;
const char *managed;
/* New binding */
dn = of_get_child_by_name(np, "fixed-link");
@ -275,6 +276,10 @@ bool of_phy_is_fixed_link(struct device_node *np)
return true;
}
err = of_property_read_string(np, "managed", &managed);
if (err == 0 && strcmp(managed, "auto") != 0)
return true;
/* Old binding */
if (of_get_property(np, "fixed-link", &len) &&
len == (5 * sizeof(__be32)))
@ -289,8 +294,18 @@ int of_phy_register_fixed_link(struct device_node *np)
struct fixed_phy_status status = {};
struct device_node *fixed_link_node;
const __be32 *fixed_link_prop;
int len;
int len, err;
struct phy_device *phy;
const char *managed;
err = of_property_read_string(np, "managed", &managed);
if (err == 0) {
if (strcmp(managed, "in-band-status") == 0) {
/* status is zeroed, namely its .link member */
phy = fixed_phy_register(PHY_POLL, &status, np);
return IS_ERR(phy) ? PTR_ERR(phy) : 0;
}
}
/* New binding */
fixed_link_node = of_get_child_by_name(np, "fixed-link");