Skip to content

Commit

Permalink
Merge branch 'explicit-inbound-link-state'
Browse files Browse the repository at this point in the history
Florian Fainelli says:

====================
net: enable inband link state negotiation only when explicitly requested

Changes in v5:

- removed an invalid use of the link_update callback in the SF2 driver
  was appeared after merging "net: phy: fixed_phy: handle link-down case"

- reworded the commit message for patch 2 to make it clear what it fixes and
  why this is required

Initial cover letter from Stas:

Hello.

Currently the link status auto-negotiation is enabled
for any SGMII link with fixed-link DT binding.
The regression was reported:
https://lkml.org/lkml/2015/7/8/865
Apparently not all HW that implements SGMII protocol, generates the
inband status for the auto-negotiation to work.
More details here:
https://lkml.org/lkml/2015/7/10/206

The following patches reverts to the old behavior by default,
which is to not enable the auto-negotiation for fixed-link.
The new DT property is added that allows to explicitly request
the auto-negotiation.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 21, 2015
2 parents e181a54 + f8af8e6 commit 67b2914
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 26 deletions.
4 changes: 4 additions & 0 deletions Documentation/devicetree/bindings/net/ethernet.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ The following properties are common to the Ethernet controllers:
flow control thresholds.
- tx-fifo-depth: the size of the controller's transmit fifo in bytes. This
is used for components that can have configurable fifo sizes.
- managed: string, specifies the PHY management type. Supported values are:
"auto", "in-band-status". "auto" is the default, it usess MDIO for
management if fixed-link is not specified.

Child nodes of the Ethernet controller are typically the individual PHY devices
connected via the MDIO bus (sometimes the MDIO bus controller is separate).
They are described in the phy.txt file in this same directory.
For non-MDIO PHY management see fixed-link.txt.
18 changes: 1 addition & 17 deletions drivers/net/dsa/bcm_sf2.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,15 +890,11 @@ static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port,
struct fixed_phy_status *status)
{
struct bcm_sf2_priv *priv = ds_to_priv(ds);
u32 duplex, pause, speed;
u32 duplex, pause;
u32 reg;

duplex = core_readl(priv, CORE_DUPSTS);
pause = core_readl(priv, CORE_PAUSESTS);
speed = core_readl(priv, CORE_SPDSTS);

speed >>= (port * SPDSTS_SHIFT);
speed &= SPDSTS_MASK;

status->link = 0;

Expand Down Expand Up @@ -933,18 +929,6 @@ static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port,
reg &= ~LINK_STS;
core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port));

switch (speed) {
case SPDSTS_10:
status->speed = SPEED_10;
break;
case SPDSTS_100:
status->speed = SPEED_100;
break;
case SPDSTS_1000:
status->speed = SPEED_1000;
break;
}

if ((pause & (1 << port)) &&
(pause & (1 << (port + PAUSESTS_TX_PAUSE_SHIFT)))) {
status->asym_pause = 1;
Expand Down
9 changes: 5 additions & 4 deletions drivers/net/ethernet/marvell/mvneta.c
Original file line number Diff line number Diff line change
Expand Up @@ -3029,8 +3029,8 @@ static int mvneta_probe(struct platform_device *pdev)
const char *dt_mac_addr;
char hw_mac_addr[ETH_ALEN];
const char *mac_from;
const char *managed;
int phy_mode;
int fixed_phy = 0;
int err;

/* Our multiqueue support is not complete, so for now, only
Expand Down Expand Up @@ -3064,7 +3064,6 @@ static int mvneta_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "cannot register fixed PHY\n");
goto err_free_irq;
}
fixed_phy = 1;

/* In the case of a fixed PHY, the DT node associated
* to the PHY is the Ethernet MAC DT node.
Expand All @@ -3088,8 +3087,10 @@ static int mvneta_probe(struct platform_device *pdev)
pp = netdev_priv(dev);
pp->phy_node = phy_node;
pp->phy_interface = phy_mode;
pp->use_inband_status = (phy_mode == PHY_INTERFACE_MODE_SGMII) &&
fixed_phy;

err = of_property_read_string(dn, "managed", &managed);
pp->use_inband_status = (err == 0 &&
strcmp(managed, "in-band-status") == 0);

pp->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(pp->clk)) {
Expand Down
8 changes: 5 additions & 3 deletions drivers/net/phy/fixed_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ static int fixed_phy_update_regs(struct fixed_phy *fp)
u16 lpagb = 0;
u16 lpa = 0;

if (!fp->status.link)
goto done;
bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;

if (fp->status.duplex) {
bmcr |= BMCR_FULLDPLX;

Expand Down Expand Up @@ -96,15 +100,13 @@ static int fixed_phy_update_regs(struct fixed_phy *fp)
}
}

if (fp->status.link)
bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;

if (fp->status.pause)
lpa |= LPA_PAUSE_CAP;

if (fp->status.asym_pause)
lpa |= LPA_PAUSE_ASYM;

done:
fp->regs[MII_PHYSID1] = 0;
fp->regs[MII_PHYSID2] = 0;

Expand Down
19 changes: 17 additions & 2 deletions drivers/of/of_mdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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)))
Expand All @@ -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");
Expand Down

0 comments on commit 67b2914

Please sign in to comment.