mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net 0/2] net: dsa: microchip: Fix set_ageing_time function for KSZ9477 and LAN937X switches
@ 2024-12-18  2:02 Tristram.Ha
  2024-12-18  2:02 ` [PATCH net 1/2] net: dsa: microchip: Fix KSZ9477 set_ageing_time function Tristram.Ha
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Tristram.Ha @ 2024-12-18  2:02 UTC (permalink / raw)
  To: Woojung Huh, Arun Ramadoss, Andrew Lunn, Vladimir Oltean
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	UNGLinuxDriver, netdev, linux-kernel, Tristram Ha

From: Tristram Ha <tristram.ha@microchip.com>

The aging count is not a simple number that is broken into two parts and
programmed into 2 registers.  These patches correct the programming for
KSZ9477 and LAN937X switches.

Tristram Ha (2):
  net: dsa: microchip: Fix KSZ9477 set_ageing_time function
  net: dsa: microchip: Fix LAN937X set_ageing_time function

 drivers/net/dsa/microchip/ksz9477.c      | 47 +++++++++++++-----
 drivers/net/dsa/microchip/ksz9477_reg.h  |  4 +-
 drivers/net/dsa/microchip/lan937x_main.c | 62 ++++++++++++++++++++++--
 drivers/net/dsa/microchip/lan937x_reg.h  |  9 ++--
 4 files changed, 102 insertions(+), 20 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH net 1/2] net: dsa: microchip: Fix KSZ9477 set_ageing_time function
  2024-12-18  2:02 [PATCH net 0/2] net: dsa: microchip: Fix set_ageing_time function for KSZ9477 and LAN937X switches Tristram.Ha
@ 2024-12-18  2:02 ` Tristram.Ha
  2024-12-19 16:50   ` Andrew Lunn
  2024-12-18  2:02 ` [PATCH net 2/2] net: dsa: microchip: Fix LAN937X " Tristram.Ha
  2024-12-20  2:10 ` [PATCH net 0/2] net: dsa: microchip: Fix set_ageing_time function for KSZ9477 and LAN937X switches patchwork-bot+netdevbpf
  2 siblings, 1 reply; 6+ messages in thread
From: Tristram.Ha @ 2024-12-18  2:02 UTC (permalink / raw)
  To: Woojung Huh, Arun Ramadoss, Andrew Lunn, Vladimir Oltean
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	UNGLinuxDriver, netdev, linux-kernel, Tristram Ha

From: Tristram Ha <tristram.ha@microchip.com>

The aging count is not a simple 11-bit value but comprises a 3-bit
multiplier and an 8-bit second count.  The code tries to use the
original multiplier which is 4 as the second count is still 300 seconds
by default.

Fixes: 2c119d9982b1 ("net: dsa: microchip: add the support for set_ageing_time")
Signed-off-by: Tristram Ha <tristram.ha@microchip.com>
---
 drivers/net/dsa/microchip/ksz9477.c     | 47 +++++++++++++++++++------
 drivers/net/dsa/microchip/ksz9477_reg.h |  4 +--
 2 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index d16817e0476f..29fe79ea74cd 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -2,7 +2,7 @@
 /*
  * Microchip KSZ9477 switch driver main logic
  *
- * Copyright (C) 2017-2019 Microchip Technology Inc.
+ * Copyright (C) 2017-2024 Microchip Technology Inc.
  */
 
 #include <linux/kernel.h>
@@ -983,26 +983,51 @@ void ksz9477_get_caps(struct ksz_device *dev, int port,
 int ksz9477_set_ageing_time(struct ksz_device *dev, unsigned int msecs)
 {
 	u32 secs = msecs / 1000;
-	u8 value;
-	u8 data;
+	u8 data, mult, value;
+	u32 max_val;
 	int ret;
 
-	value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs);
+#define MAX_TIMER_VAL	((1 << 8) - 1)
 
-	ret = ksz_write8(dev, REG_SW_LUE_CTRL_3, value);
-	if (ret < 0)
-		return ret;
+	/* The aging timer comprises a 3-bit multiplier and an 8-bit second
+	 * value.  Either of them cannot be zero.  The maximum timer is then
+	 * 7 * 255 = 1785 seconds.
+	 */
+	if (!secs)
+		secs = 1;
 
-	data = FIELD_GET(SW_AGE_PERIOD_10_8_M, secs);
+	/* Return error if too large. */
+	else if (secs > 7 * MAX_TIMER_VAL)
+		return -EINVAL;
 
 	ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value);
 	if (ret < 0)
 		return ret;
 
-	value &= ~SW_AGE_CNT_M;
-	value |= FIELD_PREP(SW_AGE_CNT_M, data);
+	/* Check whether there is need to update the multiplier. */
+	mult = FIELD_GET(SW_AGE_CNT_M, value);
+	max_val = MAX_TIMER_VAL;
+	if (mult > 0) {
+		/* Try to use the same multiplier already in the register as
+		 * the hardware default uses multiplier 4 and 75 seconds for
+		 * 300 seconds.
+		 */
+		max_val = DIV_ROUND_UP(secs, mult);
+		if (max_val > MAX_TIMER_VAL || max_val * mult != secs)
+			max_val = MAX_TIMER_VAL;
+	}
+
+	data = DIV_ROUND_UP(secs, max_val);
+	if (mult != data) {
+		value &= ~SW_AGE_CNT_M;
+		value |= FIELD_PREP(SW_AGE_CNT_M, data);
+		ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value);
+		if (ret < 0)
+			return ret;
+	}
 
-	return ksz_write8(dev, REG_SW_LUE_CTRL_0, value);
+	value = DIV_ROUND_UP(secs, data);
+	return ksz_write8(dev, REG_SW_LUE_CTRL_3, value);
 }
 
 void ksz9477_port_queue_split(struct ksz_device *dev, int port)
diff --git a/drivers/net/dsa/microchip/ksz9477_reg.h b/drivers/net/dsa/microchip/ksz9477_reg.h
index 04235c22bf40..ff579920078e 100644
--- a/drivers/net/dsa/microchip/ksz9477_reg.h
+++ b/drivers/net/dsa/microchip/ksz9477_reg.h
@@ -2,7 +2,7 @@
 /*
  * Microchip KSZ9477 register definitions
  *
- * Copyright (C) 2017-2018 Microchip Technology Inc.
+ * Copyright (C) 2017-2024 Microchip Technology Inc.
  */
 
 #ifndef __KSZ9477_REGS_H
@@ -165,8 +165,6 @@
 #define SW_VLAN_ENABLE			BIT(7)
 #define SW_DROP_INVALID_VID		BIT(6)
 #define SW_AGE_CNT_M			GENMASK(5, 3)
-#define SW_AGE_CNT_S			3
-#define SW_AGE_PERIOD_10_8_M		GENMASK(10, 8)
 #define SW_RESV_MCAST_ENABLE		BIT(2)
 #define SW_HASH_OPTION_M		0x03
 #define SW_HASH_OPTION_CRC		1
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH net 2/2] net: dsa: microchip: Fix LAN937X set_ageing_time function
  2024-12-18  2:02 [PATCH net 0/2] net: dsa: microchip: Fix set_ageing_time function for KSZ9477 and LAN937X switches Tristram.Ha
  2024-12-18  2:02 ` [PATCH net 1/2] net: dsa: microchip: Fix KSZ9477 set_ageing_time function Tristram.Ha
@ 2024-12-18  2:02 ` Tristram.Ha
  2024-12-19 16:58   ` Andrew Lunn
  2024-12-20  2:10 ` [PATCH net 0/2] net: dsa: microchip: Fix set_ageing_time function for KSZ9477 and LAN937X switches patchwork-bot+netdevbpf
  2 siblings, 1 reply; 6+ messages in thread
From: Tristram.Ha @ 2024-12-18  2:02 UTC (permalink / raw)
  To: Woojung Huh, Arun Ramadoss, Andrew Lunn, Vladimir Oltean
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	UNGLinuxDriver, netdev, linux-kernel, Tristram Ha

From: Tristram Ha <tristram.ha@microchip.com>

The aging count is not a simple 20-bit value but comprises a 3-bit
multiplier and a 20-bit second time.  The code tries to use the
original multiplier which is 4 as the second count is still 300 seconds
by default.

As the 20-bit number is now too large for practical use there is an option
to interpret it as microseconds instead of seconds.

Fixes: 2c119d9982b1 ("net: dsa: microchip: add the support for set_ageing_time")
Signed-off-by: Tristram Ha <tristram.ha@microchip.com>
---
 drivers/net/dsa/microchip/lan937x_main.c | 62 ++++++++++++++++++++++--
 drivers/net/dsa/microchip/lan937x_reg.h  |  9 ++--
 2 files changed, 65 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
index b7652efd632e..b1ae3b9de3d1 100644
--- a/drivers/net/dsa/microchip/lan937x_main.c
+++ b/drivers/net/dsa/microchip/lan937x_main.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Microchip LAN937X switch driver main logic
- * Copyright (C) 2019-2022 Microchip Technology Inc.
+ * Copyright (C) 2019-2024 Microchip Technology Inc.
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -461,10 +461,66 @@ int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu)
 
 int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs)
 {
-	u32 secs = msecs / 1000;
-	u32 value;
+	u8 data, mult, value8;
+	bool in_msec = false;
+	u32 max_val, value;
+	u32 secs = msecs;
 	int ret;
 
+#define MAX_TIMER_VAL	((1 << 20) - 1)
+
+	/* The aging timer comprises a 3-bit multiplier and a 20-bit second
+	 * value.  Either of them cannot be zero.  The maximum timer is then
+	 * 7 * 1048575 = 7340025 seconds.  As this value is too large for
+	 * practical use it can be interpreted as microseconds, making the
+	 * maximum timer 7340 seconds with finer control.  This allows for
+	 * maximum 122 minutes compared to 29 minutes in KSZ9477 switch.
+	 */
+	if (msecs % 1000)
+		in_msec = true;
+	else
+		secs /= 1000;
+	if (!secs)
+		secs = 1;
+
+	/* Return error if too large. */
+	else if (secs > 7 * MAX_TIMER_VAL)
+		return -EINVAL;
+
+	/* Configure how to interpret the number value. */
+	ret = ksz_rmw8(dev, REG_SW_LUE_CTRL_2, SW_AGE_CNT_IN_MICROSEC,
+		       in_msec ? SW_AGE_CNT_IN_MICROSEC : 0);
+	if (ret < 0)
+		return ret;
+
+	ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value8);
+	if (ret < 0)
+		return ret;
+
+	/* Check whether there is need to update the multiplier. */
+	mult = FIELD_GET(SW_AGE_CNT_M, value8);
+	max_val = MAX_TIMER_VAL;
+	if (mult > 0) {
+		/* Try to use the same multiplier already in the register as
+		 * the hardware default uses multiplier 4 and 75 seconds for
+		 * 300 seconds.
+		 */
+		max_val = DIV_ROUND_UP(secs, mult);
+		if (max_val > MAX_TIMER_VAL || max_val * mult != secs)
+			max_val = MAX_TIMER_VAL;
+	}
+
+	data = DIV_ROUND_UP(secs, max_val);
+	if (mult != data) {
+		value8 &= ~SW_AGE_CNT_M;
+		value8 |= FIELD_PREP(SW_AGE_CNT_M, data);
+		ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value8);
+		if (ret < 0)
+			return ret;
+	}
+
+	secs = DIV_ROUND_UP(secs, data);
+
 	value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs);
 
 	ret = ksz_write8(dev, REG_SW_AGE_PERIOD__1, value);
diff --git a/drivers/net/dsa/microchip/lan937x_reg.h b/drivers/net/dsa/microchip/lan937x_reg.h
index 4ec93e421da4..72042fd64e5b 100644
--- a/drivers/net/dsa/microchip/lan937x_reg.h
+++ b/drivers/net/dsa/microchip/lan937x_reg.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /* Microchip LAN937X switch register definitions
- * Copyright (C) 2019-2021 Microchip Technology Inc.
+ * Copyright (C) 2019-2024 Microchip Technology Inc.
  */
 #ifndef __LAN937X_REG_H
 #define __LAN937X_REG_H
@@ -56,8 +56,7 @@
 
 #define SW_VLAN_ENABLE			BIT(7)
 #define SW_DROP_INVALID_VID		BIT(6)
-#define SW_AGE_CNT_M			0x7
-#define SW_AGE_CNT_S			3
+#define SW_AGE_CNT_M			GENMASK(5, 3)
 #define SW_RESV_MCAST_ENABLE		BIT(2)
 
 #define REG_SW_LUE_CTRL_1		0x0311
@@ -70,6 +69,10 @@
 #define SW_FAST_AGING			BIT(1)
 #define SW_LINK_AUTO_AGING		BIT(0)
 
+#define REG_SW_LUE_CTRL_2		0x0312
+
+#define SW_AGE_CNT_IN_MICROSEC		BIT(7)
+
 #define REG_SW_AGE_PERIOD__1		0x0313
 #define SW_AGE_PERIOD_7_0_M		GENMASK(7, 0)
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net 1/2] net: dsa: microchip: Fix KSZ9477 set_ageing_time function
  2024-12-18  2:02 ` [PATCH net 1/2] net: dsa: microchip: Fix KSZ9477 set_ageing_time function Tristram.Ha
@ 2024-12-19 16:50   ` Andrew Lunn
  0 siblings, 0 replies; 6+ messages in thread
From: Andrew Lunn @ 2024-12-19 16:50 UTC (permalink / raw)
  To: Tristram.Ha
  Cc: Woojung Huh, Arun Ramadoss, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, UNGLinuxDriver,
	netdev, linux-kernel

On Tue, Dec 17, 2024 at 06:02:23PM -0800, Tristram.Ha@microchip.com wrote:
> From: Tristram Ha <tristram.ha@microchip.com>
> 
> The aging count is not a simple 11-bit value but comprises a 3-bit
> multiplier and an 8-bit second count.  The code tries to use the
> original multiplier which is 4 as the second count is still 300 seconds
> by default.
> 
> Fixes: 2c119d9982b1 ("net: dsa: microchip: add the support for set_ageing_time")
> Signed-off-by: Tristram Ha <tristram.ha@microchip.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net 2/2] net: dsa: microchip: Fix LAN937X set_ageing_time function
  2024-12-18  2:02 ` [PATCH net 2/2] net: dsa: microchip: Fix LAN937X " Tristram.Ha
@ 2024-12-19 16:58   ` Andrew Lunn
  0 siblings, 0 replies; 6+ messages in thread
From: Andrew Lunn @ 2024-12-19 16:58 UTC (permalink / raw)
  To: Tristram.Ha
  Cc: Woojung Huh, Arun Ramadoss, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, UNGLinuxDriver,
	netdev, linux-kernel

On Tue, Dec 17, 2024 at 06:02:24PM -0800, Tristram.Ha@microchip.com wrote:
> From: Tristram Ha <tristram.ha@microchip.com>
> 
> The aging count is not a simple 20-bit value but comprises a 3-bit
> multiplier and a 20-bit second time.  The code tries to use the
> original multiplier which is 4 as the second count is still 300 seconds
> by default.
> 
> As the 20-bit number is now too large for practical use there is an option
> to interpret it as microseconds instead of seconds.
> 
> Fixes: 2c119d9982b1 ("net: dsa: microchip: add the support for set_ageing_time")
> Signed-off-by: Tristram Ha <tristram.ha@microchip.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net 0/2] net: dsa: microchip: Fix set_ageing_time function for KSZ9477 and LAN937X switches
  2024-12-18  2:02 [PATCH net 0/2] net: dsa: microchip: Fix set_ageing_time function for KSZ9477 and LAN937X switches Tristram.Ha
  2024-12-18  2:02 ` [PATCH net 1/2] net: dsa: microchip: Fix KSZ9477 set_ageing_time function Tristram.Ha
  2024-12-18  2:02 ` [PATCH net 2/2] net: dsa: microchip: Fix LAN937X " Tristram.Ha
@ 2024-12-20  2:10 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-12-20  2:10 UTC (permalink / raw)
  To: Tristram.Ha
  Cc: woojung.huh, arun.ramadoss, andrew, olteanv, davem, edumazet,
	kuba, pabeni, UNGLinuxDriver, netdev, linux-kernel, tristram.ha

Hello:

This series was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Tue, 17 Dec 2024 18:02:22 -0800 you wrote:
> From: Tristram Ha <tristram.ha@microchip.com>
> 
> The aging count is not a simple number that is broken into two parts and
> programmed into 2 registers.  These patches correct the programming for
> KSZ9477 and LAN937X switches.
> 
> Tristram Ha (2):
>   net: dsa: microchip: Fix KSZ9477 set_ageing_time function
>   net: dsa: microchip: Fix LAN937X set_ageing_time function
> 
> [...]

Here is the summary with links:
  - [net,1/2] net: dsa: microchip: Fix KSZ9477 set_ageing_time function
    https://git.kernel.org/netdev/net/c/262bfba8ab82
  - [net,2/2] net: dsa: microchip: Fix LAN937X set_ageing_time function
    https://git.kernel.org/netdev/net/c/bb9869043438

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-12-20  2:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-12-18  2:02 [PATCH net 0/2] net: dsa: microchip: Fix set_ageing_time function for KSZ9477 and LAN937X switches Tristram.Ha
2024-12-18  2:02 ` [PATCH net 1/2] net: dsa: microchip: Fix KSZ9477 set_ageing_time function Tristram.Ha
2024-12-19 16:50   ` Andrew Lunn
2024-12-18  2:02 ` [PATCH net 2/2] net: dsa: microchip: Fix LAN937X " Tristram.Ha
2024-12-19 16:58   ` Andrew Lunn
2024-12-20  2:10 ` [PATCH net 0/2] net: dsa: microchip: Fix set_ageing_time function for KSZ9477 and LAN937X switches patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®