* [PATCH net-next v2 0/2] net: phy: sfp: Add single-byte SMBus SFP access
@ 2025-02-25 11:20 Maxime Chevallier
2025-02-25 11:20 ` [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access Maxime Chevallier
2025-02-25 11:20 ` [PATCH net-next v2 2/2] net: mdio: mdio-i2c: Add support for single-byte SMBus operations Maxime Chevallier
0 siblings, 2 replies; 13+ messages in thread
From: Maxime Chevallier @ 2025-02-25 11:20 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Florian Fainelli, Köry Maincent, Simon Horman,
Romain Gantois, Antoine Tenart, Marek Behún, Sean Anderson,
Bjørn Mork
Hello everyone,
This is V2 for the single-byte SMBus support for SFP cages as well as
embedded PHYs accessed over mdio-i2c.
Discussions in V1 [1] with Russell and Andrew showed that we should be mor
conservative with SMBus access, as it is either stated as non-compliant
with SFF-8472 for diag data, or simply blurry as to how well this will work
with Copper modules.
Tests on a variety of modules show that it looks OK however this is
really not enough to guarantee that it will work with all modules, so in
this V2 we :
- Disable hwmon
- Print a big warning indicating that it may not work as expected, but
more importantly that the kernel isn't to blame, but rather the HW
design.
I've added Sean's tested-by tags, I hope that's OK given I've added the
new flag to disable hwmon.
V1 ([1]): https://lore.kernel.org/netdev/20250223172848.1098621-1-maxime.chevallier@bootlin.com/#t
Maxime Chevallier (2):
net: phy: sfp: Add support for SMBus module access
net: mdio: mdio-i2c: Add support for single-byte SMBus operations
drivers/net/mdio/mdio-i2c.c | 79 ++++++++++++++++++++++++++++++++++++-
drivers/net/phy/sfp.c | 79 ++++++++++++++++++++++++++++++++++---
2 files changed, 151 insertions(+), 7 deletions(-)
--
2.48.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 11:20 [PATCH net-next v2 0/2] net: phy: sfp: Add single-byte SMBus SFP access Maxime Chevallier
@ 2025-02-25 11:20 ` Maxime Chevallier
2025-02-25 13:41 ` Andrew Lunn
` (2 more replies)
2025-02-25 11:20 ` [PATCH net-next v2 2/2] net: mdio: mdio-i2c: Add support for single-byte SMBus operations Maxime Chevallier
1 sibling, 3 replies; 13+ messages in thread
From: Maxime Chevallier @ 2025-02-25 11:20 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Florian Fainelli, Köry Maincent, Simon Horman,
Romain Gantois, Antoine Tenart, Marek Behún, Sean Anderson,
Bjørn Mork
The SFP module's eeprom and internals are accessible through an i2c bus.
However, all the i2c transfers that are performed are SMBus-style
transfers for read and write operations.
It is possible that the SFP might be connected to an SMBus-only
controller, such as the one found in some PHY devices in the VSC85xx
family.
Introduce a set of sfp read/write ops that are going to be used if the
i2c bus is only capable of doing smbus byte accesses.
As Single-byte SMBus transaction go against SFF-8472 and breaks the
atomicity for diagnostics data access, hwmon is disabled in the case
of SMBus access.
Moreover, as this may cause other instabilities, print a warning at
probe time to indicate that the setup may be unreliable because of the
hardware design.
Tested-by: Sean Anderson <sean.anderson@linux.dev>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V2: - Added Sean's tested-by
- Added a warning indicating that operations won't be reliable, from
Russell and Andrew's reviews
- Also added a flag saying we're under a single-byte-access bus, to
both print the warning and disable hwmon.
drivers/net/phy/sfp.c | 79 +++++++++++++++++++++++++++++++++++++++----
1 file changed, 73 insertions(+), 6 deletions(-)
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 9369f5297769..6e9d3d95eb95 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -282,6 +282,7 @@ struct sfp {
unsigned int rs_state_mask;
bool have_a2;
+ bool single_byte_access;
const struct sfp_quirk *quirk;
@@ -690,14 +691,70 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
return ret == ARRAY_SIZE(msgs) ? len : 0;
}
-static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
+static int sfp_smbus_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
+ size_t len)
{
- if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
- return -EINVAL;
+ u8 bus_addr = a2 ? 0x51 : 0x50;
+ union i2c_smbus_data smbus_data;
+ u8 *data = buf;
+ int ret;
+
+ while (len) {
+ ret = i2c_smbus_xfer(sfp->i2c, bus_addr, 0,
+ I2C_SMBUS_READ, dev_addr,
+ I2C_SMBUS_BYTE_DATA, &smbus_data);
+ if (ret < 0)
+ return ret;
+
+ *data = smbus_data.byte;
+
+ len--;
+ data++;
+ dev_addr++;
+ }
+
+ return data - (u8 *)buf;
+}
+
+static int sfp_smbus_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
+ size_t len)
+{
+ u8 bus_addr = a2 ? 0x51 : 0x50;
+ union i2c_smbus_data smbus_data;
+ u8 *data = buf;
+ int ret;
+ while (len) {
+ smbus_data.byte = *data;
+ ret = i2c_smbus_xfer(sfp->i2c, bus_addr, 0,
+ I2C_SMBUS_WRITE, dev_addr,
+ I2C_SMBUS_BYTE_DATA, &smbus_data);
+ if (ret)
+ return ret;
+
+ len--;
+ data++;
+ dev_addr++;
+ }
+
+ return 0;
+}
+
+static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
+{
sfp->i2c = i2c;
- sfp->read = sfp_i2c_read;
- sfp->write = sfp_i2c_write;
+
+ if (i2c_check_functionality(i2c, I2C_FUNC_I2C)) {
+ sfp->read = sfp_i2c_read;
+ sfp->write = sfp_i2c_write;
+ } else if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ sfp->read = sfp_smbus_read;
+ sfp->write = sfp_smbus_write;
+ sfp->single_byte_access = true;
+ } else {
+ sfp->i2c = NULL;
+ return -EINVAL;
+ }
return 0;
}
@@ -1628,7 +1685,8 @@ static void sfp_hwmon_probe(struct work_struct *work)
static int sfp_hwmon_insert(struct sfp *sfp)
{
- if (sfp->have_a2 && sfp->id.ext.diagmon & SFP_DIAGMON_DDM) {
+ if (sfp->have_a2 && sfp->id.ext.diagmon & SFP_DIAGMON_DDM &&
+ !sfp->single_byte_access) {
mod_delayed_work(system_wq, &sfp->hwmon_probe, 1);
sfp->hwmon_tries = R_PROBE_RETRY_SLOW;
}
@@ -3114,6 +3172,15 @@ static int sfp_probe(struct platform_device *pdev)
if (!sfp->sfp_bus)
return -ENOMEM;
+ if (sfp->single_byte_access)
+ dev_warn(sfp->dev,
+ "Please note:\n"
+ "This SFP cage is accessed via an SMBus only capable of single byte\n"
+ "transactions. Some features are disabled, other may be unreliable or\n"
+ "sporadically fail. Use with caution. There is nothing that the kernel\n"
+ "or community can do to fix it, the kernel will try best efforts. Please\n"
+ "verify any problems on hardware that supports multi-byte I2C transactions.\n");
+
sfp_debugfs_init(sfp);
return 0;
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v2 2/2] net: mdio: mdio-i2c: Add support for single-byte SMBus operations
2025-02-25 11:20 [PATCH net-next v2 0/2] net: phy: sfp: Add single-byte SMBus SFP access Maxime Chevallier
2025-02-25 11:20 ` [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access Maxime Chevallier
@ 2025-02-25 11:20 ` Maxime Chevallier
1 sibling, 0 replies; 13+ messages in thread
From: Maxime Chevallier @ 2025-02-25 11:20 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Heiner Kallweit
Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
Florian Fainelli, Köry Maincent, Simon Horman,
Romain Gantois, Antoine Tenart, Marek Behún, Sean Anderson,
Bjørn Mork
PHYs that are within copper SFP modules have their MDIO bus accessible
through address 0x56 (usually) on the i2c bus. The MDIO-I2C bridge is
desgned for 16 bits accesses, but we can also perform 8bits accesses by
reading/writing the high and low bytes sequentially.
This commit adds support for this type of accesses, thus supporting
smbus controllers such as the one in the VSC8552.
This was only tested on Copper SFP modules that embed a Marvell 88e1111
PHY.
Tested-by: Sean Anderson <sean.anderson@linux.dev>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
V2: No changes
drivers/net/mdio/mdio-i2c.c | 79 ++++++++++++++++++++++++++++++++++++-
1 file changed, 78 insertions(+), 1 deletion(-)
diff --git a/drivers/net/mdio/mdio-i2c.c b/drivers/net/mdio/mdio-i2c.c
index da2001ea1f99..202f486e71f1 100644
--- a/drivers/net/mdio/mdio-i2c.c
+++ b/drivers/net/mdio/mdio-i2c.c
@@ -106,6 +106,62 @@ static int i2c_mii_write_default_c22(struct mii_bus *bus, int phy_id, int reg,
return i2c_mii_write_default_c45(bus, phy_id, -1, reg, val);
}
+static int smbus_byte_mii_read_default_c22(struct mii_bus *bus, int phy_id,
+ int reg)
+{
+ struct i2c_adapter *i2c = bus->priv;
+ union i2c_smbus_data smbus_data;
+ int val = 0, ret;
+
+ if (!i2c_mii_valid_phy_id(phy_id))
+ return 0;
+
+ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0,
+ I2C_SMBUS_READ, reg,
+ I2C_SMBUS_BYTE_DATA, &smbus_data);
+ if (ret < 0)
+ return ret;
+
+ val = ((smbus_data.byte & 0xff) << 8);
+
+ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0,
+ I2C_SMBUS_READ, reg,
+ I2C_SMBUS_BYTE_DATA, &smbus_data);
+ if (ret < 0)
+ return ret;
+
+ val |= (smbus_data.byte & 0xff);
+
+ return val;
+}
+
+static int smbus_byte_mii_write_default_c22(struct mii_bus *bus, int phy_id,
+ int reg, u16 val)
+{
+ struct i2c_adapter *i2c = bus->priv;
+ union i2c_smbus_data smbus_data;
+ int ret;
+
+ if (!i2c_mii_valid_phy_id(phy_id))
+ return 0;
+
+ smbus_data.byte = ((val & 0xff00) >> 8);
+
+ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0,
+ I2C_SMBUS_WRITE, reg,
+ I2C_SMBUS_BYTE_DATA, &smbus_data);
+ if (ret < 0)
+ return ret;
+
+ smbus_data.byte = val & 0xff;
+
+ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0,
+ I2C_SMBUS_WRITE, reg,
+ I2C_SMBUS_BYTE_DATA, &smbus_data);
+
+ return ret < 0 ? ret : 0;
+}
+
/* RollBall SFPs do not access internal PHY via I2C address 0x56, but
* instead via address 0x51, when SFP page is set to 0x03 and password to
* 0xffffffff.
@@ -378,13 +434,26 @@ static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
return 0;
}
+static bool mdio_i2c_check_functionality(struct i2c_adapter *i2c,
+ enum mdio_i2c_proto protocol)
+{
+ if (i2c_check_functionality(i2c, I2C_FUNC_I2C))
+ return true;
+
+ if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA) &&
+ protocol == MDIO_I2C_MARVELL_C22)
+ return true;
+
+ return false;
+}
+
struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
enum mdio_i2c_proto protocol)
{
struct mii_bus *mii;
int ret;
- if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
+ if (!mdio_i2c_check_functionality(i2c, protocol))
return ERR_PTR(-EINVAL);
mii = mdiobus_alloc();
@@ -395,6 +464,14 @@ struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
mii->parent = parent;
mii->priv = i2c;
+ /* Only use SMBus if we have no other choice */
+ if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA) &&
+ !i2c_check_functionality(i2c, I2C_FUNC_I2C)) {
+ mii->read = smbus_byte_mii_read_default_c22;
+ mii->write = smbus_byte_mii_write_default_c22;
+ return mii;
+ }
+
switch (protocol) {
case MDIO_I2C_ROLLBALL:
ret = i2c_mii_init_rollball(i2c);
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 11:20 ` [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access Maxime Chevallier
@ 2025-02-25 13:41 ` Andrew Lunn
2025-02-25 13:56 ` Maxime Chevallier
2025-02-25 18:04 ` Russell King (Oracle)
2025-03-08 18:42 ` Maxime Chevallier
2 siblings, 1 reply; 13+ messages in thread
From: Andrew Lunn @ 2025-02-25 13:41 UTC (permalink / raw)
To: Maxime Chevallier
Cc: davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
Heiner Kallweit, netdev, linux-kernel, thomas.petazzoni,
Florian Fainelli, Köry Maincent, Simon Horman,
Romain Gantois, Antoine Tenart, Marek Behún, Sean Anderson,
Bjørn Mork
On Tue, Feb 25, 2025 at 12:20:39PM +0100, Maxime Chevallier wrote:
> The SFP module's eeprom and internals are accessible through an i2c bus.
> However, all the i2c transfers that are performed are SMBus-style
> transfers for read and write operations.
>
> It is possible that the SFP might be connected to an SMBus-only
> controller, such as the one found in some PHY devices in the VSC85xx
> family.
>
> Introduce a set of sfp read/write ops that are going to be used if the
> i2c bus is only capable of doing smbus byte accesses.
>
> As Single-byte SMBus transaction go against SFF-8472 and breaks the
> atomicity for diagnostics data access, hwmon is disabled in the case
> of SMBus access.
>
> Moreover, as this may cause other instabilities, print a warning at
> probe time to indicate that the setup may be unreliable because of the
> hardware design.
>
> Tested-by: Sean Anderson <sean.anderson@linux.dev>
> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
> ---
>
> V2: - Added Sean's tested-by
> - Added a warning indicating that operations won't be reliable, from
> Russell and Andrew's reviews
> - Also added a flag saying we're under a single-byte-access bus, to
> both print the warning and disable hwmon.
>
> drivers/net/phy/sfp.c | 79 +++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 73 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
> index 9369f5297769..6e9d3d95eb95 100644
> --- a/drivers/net/phy/sfp.c
> +++ b/drivers/net/phy/sfp.c
> @@ -282,6 +282,7 @@ struct sfp {
> unsigned int rs_state_mask;
>
> bool have_a2;
> + bool single_byte_access;
>
> const struct sfp_quirk *quirk;
>
> @@ -690,14 +691,70 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
> return ret == ARRAY_SIZE(msgs) ? len : 0;
> }
>
> -static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
> +static int sfp_smbus_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
Maybe call this sfp_smbus_byte_read(), leaving space for
sfp_smbus_word_read() in the future.
> + size_t len)
> {
> - if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
> - return -EINVAL;
> + u8 bus_addr = a2 ? 0x51 : 0x50;
> + union i2c_smbus_data smbus_data;
> + u8 *data = buf;
> + int ret;
> +
> + while (len) {
> + ret = i2c_smbus_xfer(sfp->i2c, bus_addr, 0,
> + I2C_SMBUS_READ, dev_addr,
> + I2C_SMBUS_BYTE_DATA, &smbus_data);
> + if (ret < 0)
> + return ret;
Isn't this the wrong order? You should do the upper byte first, then
the lower?
Andrew
---
pw-bot: cr
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 13:41 ` Andrew Lunn
@ 2025-02-25 13:56 ` Maxime Chevallier
2025-02-25 14:58 ` Andrew Lunn
2025-02-25 18:06 ` Russell King (Oracle)
0 siblings, 2 replies; 13+ messages in thread
From: Maxime Chevallier @ 2025-02-25 13:56 UTC (permalink / raw)
To: Andrew Lunn
Cc: davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
Heiner Kallweit, netdev, linux-kernel, thomas.petazzoni,
Florian Fainelli, Köry Maincent, Simon Horman,
Romain Gantois, Antoine Tenart, Marek Behún, Sean Anderson,
Bjørn Mork
Hi Andrew,
> > -static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
> > +static int sfp_smbus_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
>
> Maybe call this sfp_smbus_byte_read(), leaving space for
> sfp_smbus_word_read() in the future.
Good idea, I'll do that :)
> > + size_t len)
> > {
> > - if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
> > - return -EINVAL;
> > + u8 bus_addr = a2 ? 0x51 : 0x50;
> > + union i2c_smbus_data smbus_data;
> > + u8 *data = buf;
> > + int ret;
> > +
> > + while (len) {
> > + ret = i2c_smbus_xfer(sfp->i2c, bus_addr, 0,
> > + I2C_SMBUS_READ, dev_addr,
> > + I2C_SMBUS_BYTE_DATA, &smbus_data);
> > + if (ret < 0)
> > + return ret;
>
> Isn't this the wrong order? You should do the upper byte first, then
> the lower?
You might be correct. As I have been running that code out-of-tree for
a while, I was thinking that surely I'd have noticed if this was
wrong, however there are only a few cases where we actually write to
SFP :
- sfp_modify_u8(...) => one-byte write
- in sfp_cotsworks_fixup_check(...) there are 2 writes : one 1-byte
write and a 3-bytes write.
As I don't have any cotsworks SFP, then it looks like having the writes
mis-ordered would have stayed un-noticed on my side as I only
stressed the 1 byte write path...
So, good catch :) Let me triple-check and see if I can find any
conceivable way of testing that...
Thanks,
Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 13:56 ` Maxime Chevallier
@ 2025-02-25 14:58 ` Andrew Lunn
2025-02-25 18:23 ` Russell King (Oracle)
2025-02-25 18:06 ` Russell King (Oracle)
1 sibling, 1 reply; 13+ messages in thread
From: Andrew Lunn @ 2025-02-25 14:58 UTC (permalink / raw)
To: Maxime Chevallier
Cc: davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni, Russell King,
Heiner Kallweit, netdev, linux-kernel, thomas.petazzoni,
Florian Fainelli, Köry Maincent, Simon Horman,
Romain Gantois, Antoine Tenart, Marek Behún, Sean Anderson,
Bjørn Mork
> You might be correct. As I have been running that code out-of-tree for
> a while, I was thinking that surely I'd have noticed if this was
> wrong, however there are only a few cases where we actually write to
> SFP :
>
> - sfp_modify_u8(...) => one-byte write
> - in sfp_cotsworks_fixup_check(...) there are 2 writes : one 1-byte
> write and a 3-bytes write.
>
> As I don't have any cotsworks SFP, then it looks like having the writes
> mis-ordered would have stayed un-noticed on my side as I only
> stressed the 1 byte write path...
>
> So, good catch :) Let me triple-check and see if I can find any
> conceivable way of testing that...
Read might be more important than write. This is particularly
important for the second page containing the diagnostics, and dumped
by ethtool -m. It could be the sensor values latch when you read the
higher byte, so you can read the lower byte without worrying about it
changing. This is why we don't want HWMON, if you can only do byte
access. You might be able to test this with the temperature
sensor. The value is in 1/256 degrees. So if you can get is going from
21 255/256C to 22 0/256C and see if you ever read 21 0/256 or 22
255/256C.
Andrew
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 11:20 ` [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access Maxime Chevallier
2025-02-25 13:41 ` Andrew Lunn
@ 2025-02-25 18:04 ` Russell King (Oracle)
2025-02-25 18:20 ` Maxime Chevallier
2025-02-25 18:41 ` Sean Anderson
2025-03-08 18:42 ` Maxime Chevallier
2 siblings, 2 replies; 13+ messages in thread
From: Russell King (Oracle) @ 2025-02-25 18:04 UTC (permalink / raw)
To: Maxime Chevallier
Cc: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Heiner Kallweit, netdev, linux-kernel, thomas.petazzoni,
Florian Fainelli, Köry Maincent, Simon Horman,
Romain Gantois, Antoine Tenart, Marek Behún, Sean Anderson,
Bjørn Mork
On Tue, Feb 25, 2025 at 12:20:39PM +0100, Maxime Chevallier wrote:
> The SFP module's eeprom and internals are accessible through an i2c bus.
> However, all the i2c transfers that are performed are SMBus-style
> transfers for read and write operations.
Note that there are SFPs that fail if you access them by byte - the
3FE46541AA locks the bus if you byte access the emulated EEPROM at
0x50, address 0x51. This is documented in sfp_sm_mod_probe().
So there's a very real reason for adding the warning - this module
will not work!
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 13:56 ` Maxime Chevallier
2025-02-25 14:58 ` Andrew Lunn
@ 2025-02-25 18:06 ` Russell King (Oracle)
1 sibling, 0 replies; 13+ messages in thread
From: Russell King (Oracle) @ 2025-02-25 18:06 UTC (permalink / raw)
To: Maxime Chevallier
Cc: Andrew Lunn, davem, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Heiner Kallweit, netdev, linux-kernel, thomas.petazzoni,
Florian Fainelli, Köry Maincent, Simon Horman,
Romain Gantois, Antoine Tenart, Marek Behún, Sean Anderson,
Bjørn Mork
On Tue, Feb 25, 2025 at 02:56:17PM +0100, Maxime Chevallier wrote:
> > > + while (len) {
> > > + ret = i2c_smbus_xfer(sfp->i2c, bus_addr, 0,
> > > + I2C_SMBUS_READ, dev_addr,
> > > + I2C_SMBUS_BYTE_DATA, &smbus_data);
> > > + if (ret < 0)
> > > + return ret;
> >
> > Isn't this the wrong order? You should do the upper byte first, then
> > the lower?
>
> You might be correct. As I have been running that code out-of-tree for
> a while, I was thinking that surely I'd have noticed if this was
> wrong, however there are only a few cases where we actually write to
> SFP :
>
> - sfp_modify_u8(...) => one-byte write
> - in sfp_cotsworks_fixup_check(...) there are 2 writes : one 1-byte
> write and a 3-bytes write.
>
> As I don't have any cotsworks SFP, then it looks like having the writes
> mis-ordered would have stayed un-noticed on my side as I only
> stressed the 1 byte write path...
This Cotsworks module is not a SFP. It's a solder-on SFF module.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 18:04 ` Russell King (Oracle)
@ 2025-02-25 18:20 ` Maxime Chevallier
2025-02-25 18:41 ` Sean Anderson
1 sibling, 0 replies; 13+ messages in thread
From: Maxime Chevallier @ 2025-02-25 18:20 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Heiner Kallweit, netdev, linux-kernel, thomas.petazzoni,
Florian Fainelli, Köry Maincent, Simon Horman,
Romain Gantois, Antoine Tenart, Marek Behún, Sean Anderson,
Bjørn Mork
On Tue, 25 Feb 2025 18:04:29 +0000
"Russell King (Oracle)" <linux@armlinux.org.uk> wrote:
> On Tue, Feb 25, 2025 at 12:20:39PM +0100, Maxime Chevallier wrote:
> > The SFP module's eeprom and internals are accessible through an i2c bus.
> > However, all the i2c transfers that are performed are SMBus-style
> > transfers for read and write operations.
>
> Note that there are SFPs that fail if you access them by byte - the
> 3FE46541AA locks the bus if you byte access the emulated EEPROM at
> 0x50, address 0x51. This is documented in sfp_sm_mod_probe().
>
> So there's a very real reason for adding the warning - this module
> will not work!
That's indeed pretty serious and since we can't even read the
eeprom, there's not even a chance to have, say, a list of modules that
will break with 1-byte io. So indeed the warning is needed...
Thanks
Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 14:58 ` Andrew Lunn
@ 2025-02-25 18:23 ` Russell King (Oracle)
0 siblings, 0 replies; 13+ messages in thread
From: Russell King (Oracle) @ 2025-02-25 18:23 UTC (permalink / raw)
To: Andrew Lunn
Cc: Maxime Chevallier, davem, Jakub Kicinski, Eric Dumazet,
Paolo Abeni, Heiner Kallweit, netdev, linux-kernel,
thomas.petazzoni, Florian Fainelli, Köry Maincent,
Simon Horman, Romain Gantois, Antoine Tenart, Marek Behún,
Sean Anderson, Bjørn Mork
On Tue, Feb 25, 2025 at 03:58:31PM +0100, Andrew Lunn wrote:
> > You might be correct. As I have been running that code out-of-tree for
> > a while, I was thinking that surely I'd have noticed if this was
> > wrong, however there are only a few cases where we actually write to
> > SFP :
> >
> > - sfp_modify_u8(...) => one-byte write
> > - in sfp_cotsworks_fixup_check(...) there are 2 writes : one 1-byte
> > write and a 3-bytes write.
> >
> > As I don't have any cotsworks SFP, then it looks like having the writes
> > mis-ordered would have stayed un-noticed on my side as I only
> > stressed the 1 byte write path...
> >
> > So, good catch :) Let me triple-check and see if I can find any
> > conceivable way of testing that...
>
> Read might be more important than write. This is particularly
> important for the second page containing the diagnostics, and dumped
> by ethtool -m. It could be the sensor values latch when you read the
> higher byte, so you can read the lower byte without worrying about it
> changing. This is why we don't want HWMON, if you can only do byte
> access. You might be able to test this with the temperature
> sensor. The value is in 1/256 degrees. So if you can get is going from
> 21 255/256C to 22 0/256C and see if you ever read 21 0/256 or 22
> 255/256C.
<frustrated>
Why don't we read SFF-8472 instead of testing module specific behaviour?
Section 9.1 (Diagnostics overview) paragraphs 4 and 5 cover this.
No, it's not latched when you read the high byte. Paragraph 4 states
that multi-byte fields must be read using "a single two-byte read
sequence across the 2-wire interface".
Paragraph 5 states that "the transceiver shall not update a multi-byte
field within the structure during the transfer of that multi-byte field
to the host, such that partially updated data would be transferred to
the host."
In other words, while reading the the individual bytes of a multi-byte
field, the value will remain stable _while the bus transaction which
is required to be a multi-byte read is in progress_.
So, when the STOP condition is signalled on the bus, the transceiver
is then free to change the values. So accessing the high byte and
low byte seperately does not guarantee to be coherent.
It *might* work with some modules. It may not work with others. It
might crash or lock the I2C bus with other modules. (I already know
that at least one GPON module locks the bus with byte reads of
0xA0 EEPROM offset 0x51.)
We've had this before. We have a byte-mode fallback in the SFP code,
and we've had to be *very* careful when enabling this only for
modules that need it.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 18:04 ` Russell King (Oracle)
2025-02-25 18:20 ` Maxime Chevallier
@ 2025-02-25 18:41 ` Sean Anderson
2025-02-25 18:48 ` Maxime Chevallier
1 sibling, 1 reply; 13+ messages in thread
From: Sean Anderson @ 2025-02-25 18:41 UTC (permalink / raw)
To: Russell King (Oracle), Maxime Chevallier
Cc: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Heiner Kallweit, netdev, linux-kernel, thomas.petazzoni,
Florian Fainelli, Köry Maincent, Simon Horman,
Romain Gantois, Antoine Tenart, Marek Behún, Bjørn Mork
On 2/25/25 13:04, Russell King (Oracle) wrote:
> On Tue, Feb 25, 2025 at 12:20:39PM +0100, Maxime Chevallier wrote:
>> The SFP module's eeprom and internals are accessible through an i2c bus.
>> However, all the i2c transfers that are performed are SMBus-style
>> transfers for read and write operations.
>
> Note that there are SFPs that fail if you access them by byte - the
> 3FE46541AA locks the bus if you byte access the emulated EEPROM at
> 0x50, address 0x51. This is documented in sfp_sm_mod_probe().
>
> So there's a very real reason for adding the warning - this module
> will not work!
>
I had a look at sfp_sm_mod_probe, and from what I can tell the SFP that
I was having issues with should have been fixed by commit 426c6cbc409c
("net: sfp: add workaround for Realtek RTL8672 and RTL9601C chips"). I
re-tested without this series applied, and the SFP still worked. So I
guess I don't have an SFP module with the issue this series is trying to
address after all.
--Sean
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 18:41 ` Sean Anderson
@ 2025-02-25 18:48 ` Maxime Chevallier
0 siblings, 0 replies; 13+ messages in thread
From: Maxime Chevallier @ 2025-02-25 18:48 UTC (permalink / raw)
To: Sean Anderson
Cc: Russell King (Oracle), davem, Andrew Lunn, Jakub Kicinski,
Eric Dumazet, Paolo Abeni, Heiner Kallweit, netdev, linux-kernel,
thomas.petazzoni, Florian Fainelli, Köry Maincent,
Simon Horman, Romain Gantois, Antoine Tenart, Marek Behún,
Bjørn Mork
Hi Sean,
On Tue, 25 Feb 2025 13:41:57 -0500
Sean Anderson <sean.anderson@linux.dev> wrote:
> On 2/25/25 13:04, Russell King (Oracle) wrote:
> > On Tue, Feb 25, 2025 at 12:20:39PM +0100, Maxime Chevallier wrote:
> >> The SFP module's eeprom and internals are accessible through an i2c bus.
> >> However, all the i2c transfers that are performed are SMBus-style
> >> transfers for read and write operations.
> >
> > Note that there are SFPs that fail if you access them by byte - the
> > 3FE46541AA locks the bus if you byte access the emulated EEPROM at
> > 0x50, address 0x51. This is documented in sfp_sm_mod_probe().
> >
> > So there's a very real reason for adding the warning - this module
> > will not work!
> >
>
> I had a look at sfp_sm_mod_probe, and from what I can tell the SFP that
> I was having issues with should have been fixed by commit 426c6cbc409c
> ("net: sfp: add workaround for Realtek RTL8672 and RTL9601C chips"). I
> re-tested without this series applied, and the SFP still worked. So I
> guess I don't have an SFP module with the issue this series is trying to
> address after all.
I see, this series actually wasn't supposed to solve that at all (but
it's true that the solution was to fallback to 1-byte access, as
Russell explains on that thread) :)
The use-case for that series is to deal with situations where the Host
(i2c master) is only capable of 1-byte transactions (it's not a true
i2c controller, but rather a very limited smbus controller) :)
Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access
2025-02-25 11:20 ` [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access Maxime Chevallier
2025-02-25 13:41 ` Andrew Lunn
2025-02-25 18:04 ` Russell King (Oracle)
@ 2025-03-08 18:42 ` Maxime Chevallier
2 siblings, 0 replies; 13+ messages in thread
From: Maxime Chevallier @ 2025-03-08 18:42 UTC (permalink / raw)
To: davem, Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Russell King, Heiner Kallweit
Cc: netdev, linux-kernel, thomas.petazzoni, Florian Fainelli,
Köry Maincent, Simon Horman, Romain Gantois, Antoine Tenart,
Marek Behún, Sean Anderson, Bjørn Mork
Hi,
On Tue, 25 Feb 2025 12:20:39 +0100
Maxime Chevallier <maxime.chevallier@bootlin.com> wrote:
> The SFP module's eeprom and internals are accessible through an i2c bus.
> However, all the i2c transfers that are performed are SMBus-style
> transfers for read and write operations.
>
> It is possible that the SFP might be connected to an SMBus-only
> controller, such as the one found in some PHY devices in the VSC85xx
> family.
>
> Introduce a set of sfp read/write ops that are going to be used if the
> i2c bus is only capable of doing smbus byte accesses.
>
> As Single-byte SMBus transaction go against SFF-8472 and breaks the
> atomicity for diagnostics data access, hwmon is disabled in the case
> of SMBus access.
>
> Moreover, as this may cause other instabilities, print a warning at
> probe time to indicate that the setup may be unreliable because of the
> hardware design.
>
> Tested-by: Sean Anderson <sean.anderson@linux.dev>
> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
> ---
>
> V2: - Added Sean's tested-by
> - Added a warning indicating that operations won't be reliable, from
> Russell and Andrew's reviews
> - Also added a flag saying we're under a single-byte-access bus, to
> both print the warning and disable hwmon.
>
> drivers/net/phy/sfp.c | 79 +++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 73 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
> index 9369f5297769..6e9d3d95eb95 100644
> --- a/drivers/net/phy/sfp.c
> +++ b/drivers/net/phy/sfp.c
> @@ -282,6 +282,7 @@ struct sfp {
> unsigned int rs_state_mask;
>
> bool have_a2;
> + bool single_byte_access;
Looking back at that code and our discussions, struct sfp already has an
"i2c_block_size", that is set to 1 for modules with broken emulated
eeprom, and there's already some logging and all the logic to disable
hwmon in such case.
So I think V3 will ditch that "single_byte_access" bool, and rather add
a "i2c_max_block_size" member, set depending on the bus capabilities,
that we'll use to clamp the i2c_block_size.
Of course the big warning to say that the design is inherently broken
because we're on a bus that's limited will stay, but that should make
our life easier for proper non-single-byte smbus support, and also
keep the code flow cleaner.
Let me know what you think,
Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-03-08 18:42 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-25 11:20 [PATCH net-next v2 0/2] net: phy: sfp: Add single-byte SMBus SFP access Maxime Chevallier
2025-02-25 11:20 ` [PATCH net-next v2 1/2] net: phy: sfp: Add support for SMBus module access Maxime Chevallier
2025-02-25 13:41 ` Andrew Lunn
2025-02-25 13:56 ` Maxime Chevallier
2025-02-25 14:58 ` Andrew Lunn
2025-02-25 18:23 ` Russell King (Oracle)
2025-02-25 18:06 ` Russell King (Oracle)
2025-02-25 18:04 ` Russell King (Oracle)
2025-02-25 18:20 ` Maxime Chevallier
2025-02-25 18:41 ` Sean Anderson
2025-02-25 18:48 ` Maxime Chevallier
2025-03-08 18:42 ` Maxime Chevallier
2025-02-25 11:20 ` [PATCH net-next v2 2/2] net: mdio: mdio-i2c: Add support for single-byte SMBus operations Maxime Chevallier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).