* [PATCH v7 01/12] i2c: rtl9300: fix channel number bound check
[not found] <20250831100457.3114-1-jelonek.jonas@gmail.com>
@ 2025-08-31 10:04 ` Jonas Jelonek
2025-08-31 10:04 ` [PATCH v7 02/12] i2c: rtl9300: ensure data length is within supported range Jonas Jelonek
2025-08-31 10:04 ` [PATCH v7 03/12] i2c: rtl9300: remove broken SMBus Quick operation support Jonas Jelonek
2 siblings, 0 replies; 4+ messages in thread
From: Jonas Jelonek @ 2025-08-31 10:04 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski
Cc: linux-i2c, Conor Dooley, devicetree, linux-kernel,
Markus Stockhausen, Sven Eckelmann, Harshal Gohel, Wolfram Sang,
Jonas Jelonek, stable
Fix the current check for number of channels (child nodes in the device
tree). Before, this was:
if (device_get_child_node_count(dev) >= RTL9300_I2C_MUX_NCHAN)
RTL9300_I2C_MUX_NCHAN gives the maximum number of channels so checking
with '>=' isn't correct because it doesn't allow the last channel
number. Thus, fix it to:
if (device_get_child_node_count(dev) > RTL9300_I2C_MUX_NCHAN)
Issue occured on a TP-Link TL-ST1008F v2.0 device (8 SFP+ ports) and fix
is tested there.
Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
Cc: <stable@vger.kernel.org> # v6.13+
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Tested-by: Sven Eckelmann <sven@narfation.org>
Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/i2c/busses/i2c-rtl9300.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
index 4b215f9a24e6..19c367703eaf 100644
--- a/drivers/i2c/busses/i2c-rtl9300.c
+++ b/drivers/i2c/busses/i2c-rtl9300.c
@@ -382,7 +382,7 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, i2c);
- if (device_get_child_node_count(dev) >= RTL9300_I2C_MUX_NCHAN)
+ if (device_get_child_node_count(dev) > RTL9300_I2C_MUX_NCHAN)
return dev_err_probe(dev, -EINVAL, "Too many channels\n");
device_for_each_child_node(dev, child) {
--
2.48.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v7 02/12] i2c: rtl9300: ensure data length is within supported range
[not found] <20250831100457.3114-1-jelonek.jonas@gmail.com>
2025-08-31 10:04 ` [PATCH v7 01/12] i2c: rtl9300: fix channel number bound check Jonas Jelonek
@ 2025-08-31 10:04 ` Jonas Jelonek
2025-08-31 10:04 ` [PATCH v7 03/12] i2c: rtl9300: remove broken SMBus Quick operation support Jonas Jelonek
2 siblings, 0 replies; 4+ messages in thread
From: Jonas Jelonek @ 2025-08-31 10:04 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski
Cc: linux-i2c, Conor Dooley, devicetree, linux-kernel,
Markus Stockhausen, Sven Eckelmann, Harshal Gohel, Wolfram Sang,
Jonas Jelonek, stable
Add an explicit check for the xfer length to 'rtl9300_i2c_config_xfer'
to ensure the data length isn't within the supported range. In
particular a data length of 0 is not supported by the hardware and
causes unintended or destructive behaviour.
This limitation becomes obvious when looking at the register
documentation [1]. 4 bits are reserved for DATA_WIDTH and the value
of these 4 bits is used as N + 1, allowing a data length range of
1 <= len <= 16.
Affected by this is the SMBus Quick Operation which works with a data
length of 0. Passing 0 as the length causes an underflow of the value
due to:
(len - 1) & 0xf
and effectively specifying a transfer length of 16 via the registers.
This causes a 16-byte write operation instead of a Quick Write. For
example, on SFP modules without write-protected EEPROM this soft-bricks
them by overwriting some initial bytes.
For completeness, also add a quirk for the zero length.
[1] https://svanheule.net/realtek/longan/register/i2c_mst1_ctrl2
Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
Cc: <stable@vger.kernel.org> # v6.13+
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Tested-by: Sven Eckelmann <sven@narfation.org>
Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/i2c/busses/i2c-rtl9300.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
index 19c367703eaf..ebd4a85e1bde 100644
--- a/drivers/i2c/busses/i2c-rtl9300.c
+++ b/drivers/i2c/busses/i2c-rtl9300.c
@@ -99,6 +99,9 @@ static int rtl9300_i2c_config_xfer(struct rtl9300_i2c *i2c, struct rtl9300_i2c_c
{
u32 val, mask;
+ if (len < 1 || len > 16)
+ return -EINVAL;
+
val = chan->bus_freq << RTL9300_I2C_MST_CTRL2_SCL_FREQ_OFS;
mask = RTL9300_I2C_MST_CTRL2_SCL_FREQ_MASK;
@@ -352,7 +355,7 @@ static const struct i2c_algorithm rtl9300_i2c_algo = {
};
static struct i2c_adapter_quirks rtl9300_i2c_quirks = {
- .flags = I2C_AQ_NO_CLK_STRETCH,
+ .flags = I2C_AQ_NO_CLK_STRETCH | I2C_AQ_NO_ZERO_LEN,
.max_read_len = 16,
.max_write_len = 16,
};
--
2.48.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v7 03/12] i2c: rtl9300: remove broken SMBus Quick operation support
[not found] <20250831100457.3114-1-jelonek.jonas@gmail.com>
2025-08-31 10:04 ` [PATCH v7 01/12] i2c: rtl9300: fix channel number bound check Jonas Jelonek
2025-08-31 10:04 ` [PATCH v7 02/12] i2c: rtl9300: ensure data length is within supported range Jonas Jelonek
@ 2025-08-31 10:04 ` Jonas Jelonek
2025-09-03 22:59 ` Andi Shyti
2 siblings, 1 reply; 4+ messages in thread
From: Jonas Jelonek @ 2025-08-31 10:04 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski
Cc: linux-i2c, Conor Dooley, devicetree, linux-kernel,
Markus Stockhausen, Sven Eckelmann, Harshal Gohel, Wolfram Sang,
Jonas Jelonek, stable
Remove the SMBus Quick operation from this driver because it is not
natively supported by the hardware and is wrongly implemented in the
driver.
The I2C controllers in Realtek RTL9300 and RTL9310 are SMBus-compliant
but there doesn't seem to be native support for the SMBus Quick
operation. It is not explicitly mentioned in the documentation but
looking at the registers which configure an SMBus transaction, one can
see that the data length cannot be set to 0. This suggests that the
hardware doesn't allow any SMBus message without data bytes (except for
those it does on it's own, see SMBus Block Read).
The current implementation of SMBus Quick operation passes a length of
0 (which is actually invalid). Before the fix of a bug in a previous
commit, this led to a read operation of 16 bytes from any register (the
one of a former transaction or any other value.
This caused issues like soft-bricked SFP modules after a simple probe
with i2cdetect which uses Quick by default. Running this with SFP
modules whose EEPROM isn't write-protected, some of the initial bytes
are overwritten because a 16-byte write operation is executed instead of
a Quick Write. (This temporarily soft-bricked one of my DAC cables.)
Because SMBus Quick operation is obviously not supported on these
controllers (because a length of 0 cannot be set, even when no register
address is set), remove that instead of claiming there is support. There
also shouldn't be any kind of emulated 'Quick' which just does another
kind of operation in the background. Otherwise, specific issues occur
in case of a 'Quick' Write which actually writes unknown data to an
unknown register.
Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
Cc: <stable@vger.kernel.org> # v6.13+
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Tested-by: Sven Eckelmann <sven@narfation.org>
Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/i2c/busses/i2c-rtl9300.c | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
index ebd4a85e1bde..9e6232075137 100644
--- a/drivers/i2c/busses/i2c-rtl9300.c
+++ b/drivers/i2c/busses/i2c-rtl9300.c
@@ -235,15 +235,6 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
}
switch (size) {
- case I2C_SMBUS_QUICK:
- ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
- if (ret)
- goto out_unlock;
- ret = rtl9300_i2c_reg_addr_set(i2c, 0, 0);
- if (ret)
- goto out_unlock;
- break;
-
case I2C_SMBUS_BYTE:
if (read_write == I2C_SMBUS_WRITE) {
ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
@@ -344,9 +335,9 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
static u32 rtl9300_i2c_func(struct i2c_adapter *a)
{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
- I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_I2C_BLOCK;
+ return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
+ I2C_FUNC_SMBUS_I2C_BLOCK;
}
static const struct i2c_algorithm rtl9300_i2c_algo = {
--
2.48.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v7 03/12] i2c: rtl9300: remove broken SMBus Quick operation support
2025-08-31 10:04 ` [PATCH v7 03/12] i2c: rtl9300: remove broken SMBus Quick operation support Jonas Jelonek
@ 2025-09-03 22:59 ` Andi Shyti
0 siblings, 0 replies; 4+ messages in thread
From: Andi Shyti @ 2025-09-03 22:59 UTC (permalink / raw)
To: Jonas Jelonek
Cc: Chris Packham, Rob Herring, Krzysztof Kozlowski, linux-i2c,
Conor Dooley, devicetree, linux-kernel, Markus Stockhausen,
Sven Eckelmann, Harshal Gohel, Wolfram Sang, stable
Hi Jonas,
On Sun, Aug 31, 2025 at 10:04:48AM +0000, Jonas Jelonek wrote:
> Remove the SMBus Quick operation from this driver because it is not
> natively supported by the hardware and is wrongly implemented in the
> driver.
>
> The I2C controllers in Realtek RTL9300 and RTL9310 are SMBus-compliant
> but there doesn't seem to be native support for the SMBus Quick
> operation. It is not explicitly mentioned in the documentation but
> looking at the registers which configure an SMBus transaction, one can
> see that the data length cannot be set to 0. This suggests that the
> hardware doesn't allow any SMBus message without data bytes (except for
> those it does on it's own, see SMBus Block Read).
>
> The current implementation of SMBus Quick operation passes a length of
> 0 (which is actually invalid). Before the fix of a bug in a previous
> commit, this led to a read operation of 16 bytes from any register (the
> one of a former transaction or any other value.
>
> This caused issues like soft-bricked SFP modules after a simple probe
> with i2cdetect which uses Quick by default. Running this with SFP
> modules whose EEPROM isn't write-protected, some of the initial bytes
> are overwritten because a 16-byte write operation is executed instead of
> a Quick Write. (This temporarily soft-bricked one of my DAC cables.)
>
> Because SMBus Quick operation is obviously not supported on these
> controllers (because a length of 0 cannot be set, even when no register
> address is set), remove that instead of claiming there is support. There
> also shouldn't be any kind of emulated 'Quick' which just does another
> kind of operation in the background. Otherwise, specific issues occur
> in case of a 'Quick' Write which actually writes unknown data to an
> unknown register.
>
> Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
> Cc: <stable@vger.kernel.org> # v6.13+
> Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
> Tested-by: Sven Eckelmann <sven@narfation.org>
> Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
> Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
> Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Applied from 1-3 to i2c/i2c-host-fixes.
But...
> ---
> drivers/i2c/busses/i2c-rtl9300.c | 15 +++------------
> 1 file changed, 3 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
> index ebd4a85e1bde..9e6232075137 100644
> --- a/drivers/i2c/busses/i2c-rtl9300.c
> +++ b/drivers/i2c/busses/i2c-rtl9300.c
> @@ -235,15 +235,6 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
> }
>
> switch (size) {
> - case I2C_SMBUS_QUICK:
> - ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
> - if (ret)
> - goto out_unlock;
> - ret = rtl9300_i2c_reg_addr_set(i2c, 0, 0);
> - if (ret)
> - goto out_unlock;
> - break;
> -
> case I2C_SMBUS_BYTE:
> if (read_write == I2C_SMBUS_WRITE) {
> ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
> @@ -344,9 +335,9 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
>
> static u32 rtl9300_i2c_func(struct i2c_adapter *a)
> {
> - return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
> - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
> - I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_I2C_BLOCK;
> + return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
> + I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
> + I2C_FUNC_SMBUS_I2C_BLOCK;
this was creating a conflict with:
5090e2b3808e ("i2c: rtl9300: Implement I2C block read and write")
In the sense that I don't have this change in the fixes path, but
I have it in the non-fixes. For now, until Wolfram pulls the
fixes, I removed the patch and I will add it back next week to
avoid conflicts in the -next branch.
Next week I will apply the rest of the patches in the series, as
well.
Thanks,
Andi
> }
>
> static const struct i2c_algorithm rtl9300_i2c_algo = {
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-09-03 22:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20250831100457.3114-1-jelonek.jonas@gmail.com>
2025-08-31 10:04 ` [PATCH v7 01/12] i2c: rtl9300: fix channel number bound check Jonas Jelonek
2025-08-31 10:04 ` [PATCH v7 02/12] i2c: rtl9300: ensure data length is within supported range Jonas Jelonek
2025-08-31 10:04 ` [PATCH v7 03/12] i2c: rtl9300: remove broken SMBus Quick operation support Jonas Jelonek
2025-09-03 22:59 ` Andi Shyti
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).