6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Machon daniel.machon@microchip.com
[ Upstream commit 8a6be4bd6fb319cee63d228e37c8dda5fd1eb74a ]
When port mirroring is added to a port, the bit position of the source port, needs to be written to the register ANA_AC_PROBE_PORT_CFG. This register is replicated for n_ports > 32, and therefore we need to derive the correct register from the port number.
Before this patch, we wrongly calculate the register from portno / BITS_PER_BYTE, where the divisor ought to be 32, causing any port >=8 to be written to the wrong register. We fix this, by using do_div(), where the dividend is the register, the remainder is the bit position and the divisor is now 32.
Fixes: 4e50d72b3b95 ("net: sparx5: add port mirroring implementation") Signed-off-by: Daniel Machon daniel.machon@microchip.com Reviewed-by: Simon Horman horms@kernel.org Link: https://patch.msgid.link/20241009-mirroring-fix-v1-1-9ec962301989@microchip.... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/microchip/sparx5/sparx5_mirror.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c b/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c index 15db423be4aa6..459a53676ae96 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c @@ -31,10 +31,10 @@ static u64 sparx5_mirror_port_get(struct sparx5 *sparx5, u32 idx) /* Add port to mirror (only front ports) */ static void sparx5_mirror_port_add(struct sparx5 *sparx5, u32 idx, u32 portno) { - u32 val, reg = portno; + u64 reg = portno; + u32 val;
- reg = portno / BITS_PER_BYTE; - val = BIT(portno % BITS_PER_BYTE); + val = BIT(do_div(reg, 32));
if (reg == 0) return spx5_rmw(val, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx)); @@ -45,10 +45,10 @@ static void sparx5_mirror_port_add(struct sparx5 *sparx5, u32 idx, u32 portno) /* Delete port from mirror (only front ports) */ static void sparx5_mirror_port_del(struct sparx5 *sparx5, u32 idx, u32 portno) { - u32 val, reg = portno; + u64 reg = portno; + u32 val;
- reg = portno / BITS_PER_BYTE; - val = BIT(portno % BITS_PER_BYTE); + val = BIT(do_div(reg, 32));
if (reg == 0) return spx5_rmw(0, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx));