Merge branch 'explicit-inbound-link-state'
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>
This commit is contained in:
commit
67b2914b9c
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue