From: "Marek Behún" <kabel@kernel•org>
To: netdev@vger•kernel.org, "David S. Miller" <davem@davemloft•net>,
Jakub Kicinski <kuba@kernel•org>
Cc: "Russell King" <rmk+kernel@armlinux•org.uk>,
"Andrew Lunn" <andrew@lunn•ch>,
"Vladimir Oltean" <vladimir.oltean@nxp•com>,
"Marek Behún" <kabel@kernel•org>
Subject: [PATCH net-next 10/12] net: sfp: create/destroy I2C mdiobus before PHY probe/after PHY release
Date: Fri, 30 Sep 2022 16:21:08 +0200 [thread overview]
Message-ID: <20220930142110.15372-11-kabel@kernel.org> (raw)
In-Reply-To: <20220930142110.15372-1-kabel@kernel.org>
Instead of configuring the I2C mdiobus when SFP driver is probed,
create/destroy the mdiobus before the PHY is probed for/after it is
released.
This way we can tell the mdio-i2c code which protocol to use for each
SFP transceiver.
Move the code that determines MDIO I2C protocol from
sfp_sm_probe_for_phy() to sfp_sm_mod_probe(), where most of the SFP ID
parsing is done. Don't allocate I2C bus if no PHY is expected.
Signed-off-by: Marek Behún <kabel@kernel•org>
---
drivers/net/phy/sfp.c | 64 ++++++++++++++++++++++++++++-------
include/linux/mdio/mdio-i2c.h | 6 ++++
2 files changed, 57 insertions(+), 13 deletions(-)
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 3201e2726e61..ccd7710685f2 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -218,6 +218,7 @@ struct sfp {
struct i2c_adapter *i2c;
struct mii_bus *i2c_mii;
struct sfp_bus *sfp_bus;
+ enum mdio_i2c_proto mdio_protocol;
struct phy_device *mod_phy;
const struct sff_data *type;
size_t i2c_block_size;
@@ -530,9 +531,6 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
{
- struct mii_bus *i2c_mii;
- int ret;
-
if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
return -EINVAL;
@@ -540,7 +538,15 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
sfp->read = sfp_i2c_read;
sfp->write = sfp_i2c_write;
- i2c_mii = mdio_i2c_alloc(sfp->dev, i2c);
+ return 0;
+}
+
+static int sfp_i2c_mdiobus_create(struct sfp *sfp)
+{
+ struct mii_bus *i2c_mii;
+ int ret;
+
+ i2c_mii = mdio_i2c_alloc(sfp->dev, sfp->i2c);
if (IS_ERR(i2c_mii))
return PTR_ERR(i2c_mii);
@@ -558,6 +564,12 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
return 0;
}
+static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
+{
+ mdiobus_unregister(sfp->i2c_mii);
+ sfp->i2c_mii = NULL;
+}
+
/* Interface */
static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
{
@@ -1674,6 +1686,14 @@ static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
}
}
+static int sfp_sm_add_mdio_bus(struct sfp *sfp)
+{
+ if (sfp->mdio_protocol != MDIO_I2C_NONE)
+ return sfp_i2c_mdiobus_create(sfp);
+
+ return 0;
+}
+
/* 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.
@@ -1689,19 +1709,19 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp)
{
int err = 0;
- 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:
- err = sfp_sm_probe_phy(sfp, true);
+ switch (sfp->mdio_protocol) {
+ case MDIO_I2C_NONE:
break;
- default:
- if (sfp->id.base.e1000_base_t)
- err = sfp_sm_probe_phy(sfp, false);
+ case MDIO_I2C_MARVELL_C22:
+ err = sfp_sm_probe_phy(sfp, false);
+ break;
+
+ case MDIO_I2C_C45:
+ err = sfp_sm_probe_phy(sfp, true);
break;
}
+
return err;
}
@@ -2028,6 +2048,16 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
sfp->tx_fault_ignore = false;
+ if (sfp->id.base.extended_cc == SFF8024_ECC_10GBASE_T_SFI ||
+ sfp->id.base.extended_cc == SFF8024_ECC_10GBASE_T_SR ||
+ sfp->id.base.extended_cc == SFF8024_ECC_5GBASE_T ||
+ sfp->id.base.extended_cc == SFF8024_ECC_2_5GBASE_T)
+ sfp->mdio_protocol = MDIO_I2C_C45;
+ else if (sfp->id.base.e1000_base_t)
+ sfp->mdio_protocol = MDIO_I2C_MARVELL_C22;
+ else
+ sfp->mdio_protocol = MDIO_I2C_NONE;
+
sfp->quirk = sfp_lookup_quirk(&id);
if (sfp->quirk && sfp->quirk->fixup)
sfp->quirk->fixup(sfp);
@@ -2204,6 +2234,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
sfp_module_stop(sfp->sfp_bus);
if (sfp->mod_phy)
sfp_sm_phy_detach(sfp);
+ if (sfp->i2c_mii)
+ sfp_i2c_mdiobus_destroy(sfp);
sfp_module_tx_disable(sfp);
sfp_soft_stop_poll(sfp);
sfp_sm_next(sfp, SFP_S_DOWN, 0);
@@ -2266,6 +2298,12 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
sfp->sm_fault_retries == N_FAULT_INIT);
} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
init_done:
+ /* Create mdiobus and start trying for PHY */
+ ret = sfp_sm_add_mdio_bus(sfp);
+ if (ret < 0) {
+ sfp_sm_next(sfp, SFP_S_FAIL, 0);
+ break;
+ }
sfp->sm_phy_retries = R_PHY_RETRY;
goto phy_probe;
}
diff --git a/include/linux/mdio/mdio-i2c.h b/include/linux/mdio/mdio-i2c.h
index b1d27f7cd23f..3bde1a555a49 100644
--- a/include/linux/mdio/mdio-i2c.h
+++ b/include/linux/mdio/mdio-i2c.h
@@ -11,6 +11,12 @@ struct device;
struct i2c_adapter;
struct mii_bus;
+enum mdio_i2c_proto {
+ MDIO_I2C_NONE,
+ MDIO_I2C_MARVELL_C22,
+ MDIO_I2C_C45,
+};
+
struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c);
#endif
--
2.35.1
next prev parent reply other threads:[~2022-09-30 14:22 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-30 14:20 [PATCH net-next 00/12] RollBall / Hilink / Turris 10G copper SFP support Marek Behún
2022-09-30 14:20 ` [PATCH net-next 01/12] net: phylink: add ability to validate a set of interface modes Marek Behún
2022-09-30 14:21 ` [PATCH net-next 02/12] net: sfp: augment SFP parsing with phy_interface_t bitmap Marek Behún
2022-09-30 14:21 ` [PATCH net-next 03/12] net: phylink: use phy_interface_t bitmaps for optical modules Marek Behún
2022-09-30 14:21 ` [PATCH net-next 04/12] net: phylink: rename phylink_sfp_config() Marek Behún
2022-09-30 14:21 ` [PATCH net-next 05/12] net: phylink: pass supported host PHY interface modes to phylib for SFP's PHYs Marek Behún
2022-09-30 14:21 ` [PATCH net-next 06/12] net: phy: marvell10g: Use tabs instead of spaces for indentation Marek Behún
2022-09-30 14:21 ` [PATCH net-next 07/12] net: phy: marvell10g: select host interface configuration Marek Behún
2022-09-30 14:21 ` [PATCH net-next 08/12] net: phylink: allow attaching phy for SFP modules on 802.3z mode Marek Behún
2022-09-30 14:21 ` [PATCH net-next 09/12] net: sfp: Add and use macros for SFP quirks definitions Marek Behún
2022-09-30 14:21 ` Marek Behún [this message]
2022-09-30 14:21 ` [PATCH net-next 11/12] net: phy: mdio-i2c: support I2C MDIO protocol for RollBall SFP modules Marek Behún
2022-09-30 14:21 ` [PATCH net-next 12/12] net: sfp: add support for multigig RollBall transceivers Marek Behún
2022-10-03 10:20 ` [PATCH net-next 00/12] RollBall / Hilink / Turris 10G copper SFP support patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220930142110.15372-11-kabel@kernel.org \
--to=kabel@kernel$(echo .)org \
--cc=andrew@lunn$(echo .)ch \
--cc=davem@davemloft$(echo .)net \
--cc=kuba@kernel$(echo .)org \
--cc=netdev@vger$(echo .)kernel.org \
--cc=rmk+kernel@armlinux$(echo .)org.uk \
--cc=vladimir.oltean@nxp$(echo .)com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox