| From 6df6709dc3d00e0bc948d45dfa8d8f18ba379c48 Mon Sep 17 00:00:00 2001 |
| From: Russell King <rmk+kernel@armlinux.org.uk> |
| Date: Tue, 5 Nov 2019 11:56:18 +0000 |
| Subject: [PATCH 656/660] net: sfp: add support for Clause 45 PHYs |
| |
| Some SFP+ modules have a Clause 45 PHY onboard, which is accessible via |
| the normal I2C address. Detect 10G BASE-T PHYs which may have an |
| accessible PHY and probe for it. |
| |
| Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> |
| --- |
| drivers/net/phy/sfp.c | 44 +++++++++++++++++++++++++++++++++++++++---- |
| 1 file changed, 40 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/net/phy/sfp.c |
| +++ b/drivers/net/phy/sfp.c |
| @@ -1418,12 +1418,12 @@ static void sfp_sm_phy_detach(struct sfp |
| sfp->mod_phy = NULL; |
| } |
| |
| -static void sfp_sm_probe_phy(struct sfp *sfp) |
| +static void sfp_sm_probe_phy(struct sfp *sfp, bool is_c45) |
| { |
| struct phy_device *phy; |
| int err; |
| |
| - phy = mdiobus_scan(sfp->i2c_mii, SFP_PHY_ADDR); |
| + phy = get_phy_device(sfp->i2c_mii, SFP_PHY_ADDR, is_c45); |
| if (phy == ERR_PTR(-ENODEV)) { |
| dev_info(sfp->dev, "no PHY detected\n"); |
| return; |
| @@ -1433,6 +1433,13 @@ static void sfp_sm_probe_phy(struct sfp |
| return; |
| } |
| |
| + err = phy_device_register(phy); |
| + if (err) { |
| + phy_device_free(phy); |
| + dev_err(sfp->dev, "phy_device_register failed: %d\n", err); |
| + return; |
| + } |
| + |
| err = sfp_add_phy(sfp->sfp_bus, phy); |
| if (err) { |
| phy_device_remove(phy); |
| @@ -1511,10 +1518,32 @@ static void sfp_sm_fault(struct sfp *sfp |
| } |
| } |
| |
| +/* Probe a SFP for a PHY device if the module supports copper - the PHY |
| + * normally sits at I2C bus address 0x56, and may either be a clause 22 |
| + * or clause 45 PHY. |
| + * |
| + * Clause 22 copper SFP modules normally operate in Cisco SGMII mode with |
| + * negotiation enabled, but some may be in 1000base-X - which is for the |
| + * PHY driver to determine. |
| + * |
| + * Clause 45 copper SFP+ modules (10G) appear to switch their interface |
| + * mode according to the negotiated line speed. |
| + */ |
| static void sfp_sm_probe_for_phy(struct sfp *sfp) |
| { |
| - if (sfp->id.base.e1000_base_t) |
| - sfp_sm_probe_phy(sfp); |
| + switch (sfp->id.base.extended_cc) { |
| + case SFF8024_ECC_10GBASE_T_SFI: |
| + case SFF8024_ECC_10GBASE_T_SR: |
| + case SFF8024_ECC_5GBASE_T: |
| + case SFF8024_ECC_2_5GBASE_T: |
| + sfp_sm_probe_phy(sfp, true); |
| + break; |
| + |
| + default: |
| + if (sfp->id.base.e1000_base_t) |
| + sfp_sm_probe_phy(sfp, false); |
| + break; |
| + } |
| } |
| |
| static int sfp_module_parse_power(struct sfp *sfp) |
| @@ -1574,6 +1603,13 @@ static int sfp_sm_mod_hpower(struct sfp |
| return -EAGAIN; |
| } |
| |
| + /* DM7052 reports as a high power module, responds to reads (with |
| + * all bytes 0xff) at 0x51 but does not accept writes. In any case, |
| + * if the bit is already set, we're already in high power mode. |
| + */ |
| + if (!!(val & BIT(0)) == enable) |
| + return 0; |
| + |
| if (enable) |
| val |= BIT(0); |
| else |