From 2f63715138233db9f1c2afff33f7d8192a29ff91 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 19 Sep 2014 13:07:49 -0700 Subject: of: mdio: honor flags passed to of_phy_connect Commit f9a8f83b04e0 ("net: phy: remove flags argument from phy_{attach, connect, connect_direct}") removed the flags argument to the PHY library calls to: phy_{attach,connect,connect_direct}. Most Device Tree aware drivers call of_phy_connect() with the flag argument set to 0, but some of them might want to set a different value there in order for the PHY driver to key a specific behavior based on the phy_device::phy_flags value. Allow such drivers to set custom phy_flags as part of the of_phy_connect() call since of_phy_connect() does start the PHY state machine, it will call into the PHY driver config_init() callback which is usually where a specific phy_flags value is important. Fixes: f9a8f83b04e0 ("net: phy: remove flags argument from phy_{attach, connect, connect_direct}") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/of/of_mdio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 401b245..a85d800 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -224,6 +224,8 @@ struct phy_device *of_phy_connect(struct net_device *dev, if (!phy) return NULL; + phy->dev_flags = flags; + return phy_connect_direct(dev, phy, hndlr, iface) ? NULL : phy; } EXPORT_SYMBOL(of_phy_connect); -- cgit v1.1 From e18556ee3bd83ed58f9fd77f66f05d17213a95f9 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 19 Sep 2014 13:07:51 -0700 Subject: net: phy: bcm7xxx: do not use PHY_BRCM_100MBPS_WAR There is no need for the PHY driver to check PHY_BRCM_100MBPS_WAR since that is redundant with checking the PHY device supported features. Get rid of that workaround flag. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/bcm7xxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c index 09dd6e1..be3a591 100644 --- a/drivers/net/phy/bcm7xxx.c +++ b/drivers/net/phy/bcm7xxx.c @@ -257,8 +257,8 @@ static int bcm7xxx_config_init(struct phy_device *phydev) phy_write(phydev, MII_BCM7XXX_AUX_MODE, MII_BCM7XX_64CLK_MDIO); phy_read(phydev, MII_BCM7XXX_AUX_MODE); - /* Workaround only required for 100Mbits/sec */ - if (!(phydev->dev_flags & PHY_BRCM_100MBPS_WAR)) + /* Workaround only required for 100Mbits/sec capable PHYs */ + if (phydev->supported & PHY_GBIT_FEATURES) return 0; /* set shadow mode 2 */ -- cgit v1.1 From 80780a54ecded1647e661ababde13554a149f7f3 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 19 Sep 2014 13:07:52 -0700 Subject: net: bcmgenet: remove PHY_BRCM_100MBPS_WAR Now that we have removed the need for the PHY_BRCM_100MBPS_WAR flag, we can remove it from the GENET driver and the broadcom shared header file. The PHY driver checks the PHY supported bitmask instead. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmmii.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index c88f7ae..71f2ef7 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -296,7 +296,6 @@ static int bcmgenet_mii_probe(struct net_device *dev) struct bcmgenet_priv *priv = netdev_priv(dev); struct device_node *dn = priv->pdev->dev.of_node; struct phy_device *phydev; - unsigned int phy_flags; int ret; if (priv->phydev) { @@ -338,15 +337,6 @@ static int bcmgenet_mii_probe(struct net_device *dev) return ret; } - phy_flags = PHY_BRCM_100MBPS_WAR; - - /* workarounds are only needed for 100Mpbs PHYs, and - * never on GENET V1 hardware - */ - if ((phydev->supported & PHY_GBIT_FEATURES) || GENET_IS_V1(priv)) - phy_flags = 0; - - phydev->dev_flags |= phy_flags; phydev->advertising = phydev->supported; /* The internal PHY has its link interrupts routed to the -- cgit v1.1 From 487320c541430a7a45eda668a26423e06eb32ad5 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 19 Sep 2014 13:07:53 -0700 Subject: net: bcmgenet: communicate integrated PHY revision to PHY driver The integrated BCM7xxx PHY contains no useful revision information in its MII_PHYSID2 bits 3:0, that information is instead contained in the GENET hardware block. We already read the GENET 32-bit revision register, so store the integrated PHY revision in the driver private structure, and then communicate this revision value to the PHY driver by overriding the phy_flags value. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 7 +++++++ drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + drivers/net/ethernet/broadcom/genet/bcmmii.c | 8 ++++++-- 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 3f9d4de..a12c656 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2432,6 +2432,13 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv) dev_info(&priv->pdev->dev, "GENET " GENET_VER_FMT, major, (reg >> 16) & 0x0f, reg & 0xffff); + /* Store the integrated PHY revision for the MDIO probing function + * to pass this information to the PHY driver. The PHY driver expects + * to find the PHY major revision in bits 15:8 while the GENET register + * stores that information in bits 7:0, account for that. + */ + priv->gphy_rev = (reg & 0xffff) << 8; + #ifdef CONFIG_PHYS_ADDR_T_64BIT if (!(params->flags & GENET_HAS_40BITS)) pr_warn("GENET does not support 40-bits PA\n"); diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index c862d06..ad95fe5 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -545,6 +545,7 @@ struct bcmgenet_priv { struct phy_device *phydev; struct device_node *phy_dn; struct mii_bus *mii_bus; + u16 gphy_rev; /* PHY device variables */ int old_duplex; diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 71f2ef7..75b26cba 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -296,6 +296,7 @@ static int bcmgenet_mii_probe(struct net_device *dev) struct bcmgenet_priv *priv = netdev_priv(dev); struct device_node *dn = priv->pdev->dev.of_node; struct phy_device *phydev; + u32 phy_flags; int ret; if (priv->phydev) { @@ -314,8 +315,11 @@ static int bcmgenet_mii_probe(struct net_device *dev) priv->phy_dn = of_node_get(dn); } - phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup, 0, - priv->phy_interface); + /* Communicate the integrated PHY revision */ + phy_flags = priv->gphy_rev; + + phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup, + phy_flags, priv->phy_interface); if (!phydev) { pr_err("could not attach to PHY\n"); return -ENODEV; -- cgit v1.1 From aa9aef77c76113725d9dbf124c4dab414326b0a3 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 19 Sep 2014 13:07:55 -0700 Subject: net: dsa: bcm_sf2: communicate integrated PHY revision to PHY driver The integrated BCM7xxx PHY contains no useful revision information in its MII_PHYSID2 bits 3:0, that information is instead contained in the SWITCH_REG_PHY_REVISION register. Read this register, store its value, and return it by implementing the dsa_switch::get_phy_flags() callback accordingly. The register layout is already matching what the BCM7xxx PHY driver is expecting to find. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/dsa/bcm_sf2.c | 16 ++++++++++++++++ drivers/net/dsa/bcm_sf2.h | 1 + drivers/net/dsa/bcm_sf2_regs.h | 1 + 3 files changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index 02d7db3..a97ba25 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -376,6 +376,9 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds) SWITCH_TOP_REV_MASK; priv->hw_params.core_rev = (rev & SF2_REV_MASK); + rev = reg_readl(priv, REG_PHY_REVISION); + priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK; + pr_info("Starfighter 2 top: %x.%02x, core: %x.%02x base: 0x%p, IRQs: %d, %d\n", priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff, priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff, @@ -399,6 +402,18 @@ static int bcm_sf2_sw_set_addr(struct dsa_switch *ds, u8 *addr) return 0; } +static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port) +{ + struct bcm_sf2_priv *priv = ds_to_priv(ds); + + /* The BCM7xxx PHY driver expects to find the integrated PHY revision + * in bits 15:8 and the patch level in bits 7:0 which is exactly what + * the REG_PHY_REVISION register layout is. + */ + + return priv->hw_params.gphy_rev; +} + static int bcm_sf2_sw_indir_rw(struct dsa_switch *ds, int op, int addr, int regnum, u16 val) { @@ -597,6 +612,7 @@ static struct dsa_switch_driver bcm_sf2_switch_driver = { .probe = bcm_sf2_sw_probe, .setup = bcm_sf2_sw_setup, .set_addr = bcm_sf2_sw_set_addr, + .get_phy_flags = bcm_sf2_sw_get_phy_flags, .phy_read = bcm_sf2_sw_phy_read, .phy_write = bcm_sf2_sw_phy_write, .get_strings = bcm_sf2_sw_get_strings, diff --git a/drivers/net/dsa/bcm_sf2.h b/drivers/net/dsa/bcm_sf2.h index 260bab3..d3bd52d 100644 --- a/drivers/net/dsa/bcm_sf2.h +++ b/drivers/net/dsa/bcm_sf2.h @@ -26,6 +26,7 @@ struct bcm_sf2_hw_params { u16 top_rev; u16 core_rev; + u16 gphy_rev; u32 num_gphy; u8 num_acb_queue; u8 num_rgmii; diff --git a/drivers/net/dsa/bcm_sf2_regs.h b/drivers/net/dsa/bcm_sf2_regs.h index 885c231..c65f138 100644 --- a/drivers/net/dsa/bcm_sf2_regs.h +++ b/drivers/net/dsa/bcm_sf2_regs.h @@ -25,6 +25,7 @@ #define SWITCH_TOP_REV_MASK 0xffff #define REG_PHY_REVISION 0x1C +#define PHY_REVISION_MASK 0xffff #define REG_SPHY_CNTRL 0x2C #define IDDQ_BIAS (1 << 0) -- cgit v1.1 From d8ebfed3f11b62ebc192af3cab64d835ff047e74 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 19 Sep 2014 13:07:56 -0700 Subject: net: phy: bcm7xxx: utilize PHY revision in config_init Now that the GENET and SF2 drivers have been updated to communicate us what is the revision of the BCM7xxx integrated PHY, utilize that information in the config_init() callback to call into the appropriate workaround function based on our revision. While at it, we also print the revision and patch level to help debug new chips. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/bcm7xxx.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c index be3a591..daae699 100644 --- a/drivers/net/phy/bcm7xxx.c +++ b/drivers/net/phy/bcm7xxx.c @@ -196,13 +196,22 @@ static int bcm7xxx_eee_enable(struct phy_device *phydev) static int bcm7xxx_28nm_config_init(struct phy_device *phydev) { - int ret; - - ret = bcm7445_config_init(phydev); - if (ret) - return ret; + u8 rev = PHY_BRCM_7XXX_REV(phydev->dev_flags); + u8 patch = PHY_BRCM_7XXX_PATCH(phydev->dev_flags); + int ret = 0; + + dev_info(&phydev->dev, "PHY revision: 0x%02x, patch: %d\n", rev, patch); + + switch (rev) { + case 0xa0: + case 0xb0: + ret = bcm7445_config_init(phydev); + break; + default: + ret = bcm7xxx_28nm_afe_config_init(phydev); + break; + } - ret = bcm7xxx_28nm_afe_config_init(phydev); if (ret) return ret; -- cgit v1.1