[net-next,v2,3/3] net: dsa: microchip: ksz8: add MTU configuration support

Message ID 20221107135755.2664997-4-o.rempel@pengutronix.de
State New
Headers
Series net: dsa: microchip: add MTU support for KSZ8 series |

Commit Message

Oleksij Rempel Nov. 7, 2022, 1:57 p.m. UTC
  Make MTU configurable on KSZ87xx and KSZ88xx series of switches.

Before this patch, pre-configured behavior was different on different
switch series, due to opposite meaning of the same bit:
- KSZ87xx: Reg 4, Bit 1 - if 1, max frame size is 1532; if 0 - 1514
- KSZ88xx: Reg 4, Bit 1 - if 1, max frame size is 1514; if 0 - 1532

Since the code was telling "... SW_LEGAL_PACKET_DISABLE, true)", I
assume, the idea was to set max frame size to 1532.

With this patch, by setting MTU size 1500, both switch series will be
configured to the 1532 frame limit.

This patch was tested on KSZ8873.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/net/dsa/microchip/ksz8.h        |  1 +
 drivers/net/dsa/microchip/ksz8795.c     | 57 ++++++++++++++++++++++++-
 drivers/net/dsa/microchip/ksz8795_reg.h |  3 ++
 drivers/net/dsa/microchip/ksz_common.c  |  7 +++
 drivers/net/dsa/microchip/ksz_common.h  |  4 ++
 5 files changed, 70 insertions(+), 2 deletions(-)
  

Comments

Arun Ramadoss Nov. 8, 2022, 5:28 a.m. UTC | #1
On Mon, 2022-11-07 at 14:57 +0100, Oleksij Rempel wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you
> know the content is safe
> 
> Make MTU configurable on KSZ87xx and KSZ88xx series of switches.
> 
> Before this patch, pre-configured behavior was different on different
> switch series, due to opposite meaning of the same bit:
> - KSZ87xx: Reg 4, Bit 1 - if 1, max frame size is 1532; if 0 - 1514
> - KSZ88xx: Reg 4, Bit 1 - if 1, max frame size is 1514; if 0 - 1532
> 
> Since the code was telling "... SW_LEGAL_PACKET_DISABLE, true)", I
> assume, the idea was to set max frame size to 1532.
> 
> With this patch, by setting MTU size 1500, both switch series will be
> configured to the 1532 frame limit.
> 
> This patch was tested on KSZ8873.
> 
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> ---
>  drivers/net/dsa/microchip/ksz8.h        |  1 +
>  drivers/net/dsa/microchip/ksz8795.c     | 57
> ++++++++++++++++++++++++-
>  drivers/net/dsa/microchip/ksz8795_reg.h |  3 ++
>  drivers/net/dsa/microchip/ksz_common.c  |  7 +++
>  drivers/net/dsa/microchip/ksz_common.h  |  4 ++
>  5 files changed, 70 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/dsa/microchip/ksz8.h
> b/drivers/net/dsa/microchip/ksz8.h
> index 8582b4b67d98..ea05abfbd51d 100644
> --- a/drivers/net/dsa/microchip/ksz8.h
> +++ b/drivers/net/dsa/microchip/ksz8.h
> @@ -57,5 +57,6 @@ int ksz8_reset_switch(struct ksz_device *dev);
>  int ksz8_switch_detect(struct ksz_device *dev);
>  int ksz8_switch_init(struct ksz_device *dev);
>  void ksz8_switch_exit(struct ksz_device *dev);
> +int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu);
> 
>  #endif
> diff --git a/drivers/net/dsa/microchip/ksz8795.c
> b/drivers/net/dsa/microchip/ksz8795.c
> index bd3b133e7085..804f421d1829 100644
> --- a/drivers/net/dsa/microchip/ksz8795.c
> +++ b/drivers/net/dsa/microchip/ksz8795.c
> @@ -76,6 +76,61 @@ int ksz8_reset_switch(struct ksz_device *dev)
>         return 0;
>  }
> 
> +static int ksz8863_change_mtu(struct ksz_device *dev, int port, int
> max_frame)
> +{
> +       u8 ctrl2 = 0;
> +
> +       if (max_frame <= KSZ8863_LEGAL_PACKET_SIZE)
> +               ctrl2 |= KSZ8863_LEGAL_PACKET_ENABLE;
> +       else if (max_frame > KSZ8863_NORMAL_PACKET_SIZE)
> +               ctrl2 |= KSZ8863_HUGE_PACKET_ENABLE;
> +
> +       return ksz_rmw8(dev, REG_SW_CTRL_2,
> KSZ8863_LEGAL_PACKET_ENABLE
> +                       | KSZ8863_HUGE_PACKET_ENABLE, ctrl2);
> +}
> +
> +static int ksz8795_change_mtu(struct ksz_device *dev, int port, int
> max_frame)
> +{
> +       u8 ctrl1 = 0, ctrl2 = 0;
> +       int ret;
> +
> +       if (max_frame > KSZ8863_LEGAL_PACKET_SIZE)
> +               ctrl2 |= SW_LEGAL_PACKET_DISABLE;
> +       else if (max_frame > KSZ8863_NORMAL_PACKET_SIZE)
> +               ctrl1 |= SW_HUGE_PACKET;
Suggestion:
Since we are using the macro KSZ8863_LEGAL_PACKET_SIZE for ksz8795 as
well, it will be good to have common name for macro like
KSZ8_LEGAL_PACKET_SIZE which will avoid the confusion later.

> +
> +       ret = ksz_rmw8(dev, REG_SW_CTRL_1, SW_HUGE_PACKET, ctrl1);
> +       if (ret)
> +               return ret;
> +
> +       return ksz_rmw8(dev, REG_SW_CTRL_2, SW_LEGAL_PACKET_DISABLE,
> ctrl2);
> +}
> +
> +int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu)
> +{
> +       u16 frame_size, max_frame = 0;
> +       int i;
> +
> +       frame_size = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
> +
> +       /* Cache the per-port MTU setting */
> +       dev->ports[port].max_frame = frame_size;
> +
> +       for (i = 0; i < dev->info->port_cnt; i++)
> +               max_frame = max(max_frame, dev->ports[i].max_frame);
> +
> +       switch (dev->chip_id) {
> +       case KSZ8795_CHIP_ID:
> +       case KSZ8794_CHIP_ID:
> +       case KSZ8765_CHIP_ID:
> +               return ksz8795_change_mtu(dev, port, max_frame);
> +       case KSZ8830_CHIP_ID:
> +               return ksz8863_change_mtu(dev, port, max_frame);
> +       }
> +
> +       return -EOPNOTSUPP;
> +}
> +
>  static void ksz8795_set_prio_queue(struct ksz_device *dev, int port,
> int queue)
>  {
>         u8 hi, lo;
> @@ -1233,8 +1288,6 @@ void ksz8_config_cpu_port(struct dsa_switch
> *ds)
>         masks = dev->info->masks;
>         regs = dev->info->regs;
> 
> -       /* Switch marks the maximum frame with extra byte as
> oversize. */
> -       ksz_cfg(dev, REG_SW_CTRL_2, SW_LEGAL_PACKET_DISABLE, true);
>         ksz_cfg(dev, regs[S_TAIL_TAG_CTRL],
> masks[SW_TAIL_TAG_ENABLE], true);
> 
>         p = &dev->ports[dev->cpu_port];
> diff --git a/drivers/net/dsa/microchip/ksz8795_reg.h
> b/drivers/net/dsa/microchip/ksz8795_reg.h
> index 77487d611824..7a57c6088f80 100644
> --- a/drivers/net/dsa/microchip/ksz8795_reg.h
> +++ b/drivers/net/dsa/microchip/ksz8795_reg.h
> @@ -48,6 +48,9 @@
>  #define NO_EXC_COLLISION_DROP          BIT(3)
>  #define SW_LEGAL_PACKET_DISABLE                BIT(1)
> 
> +#define KSZ8863_HUGE_PACKET_ENABLE     BIT(2)
> +#define KSZ8863_LEGAL_PACKET_ENABLE    BIT(1)
> +
>  #define REG_SW_CTRL_3                  0x05
>   #define WEIGHTED_FAIR_QUEUE_ENABLE    BIT(3)
> 
> diff --git a/drivers/net/dsa/microchip/ksz_common.c
> b/drivers/net/dsa/microchip/ksz_common.c
> index 486ad03d0acf..188c66145df7 100644
> --- a/drivers/net/dsa/microchip/ksz_common.c
> +++ b/drivers/net/dsa/microchip/ksz_common.c
> @@ -172,6 +172,7 @@ static const struct ksz_dev_ops ksz8_dev_ops = {
>         .reset = ksz8_reset_switch,
>         .init = ksz8_switch_init,
>         .exit = ksz8_switch_exit,
> +       .change_mtu = ksz8_change_mtu,
>  };
> 
>  static void ksz9477_phylink_mac_link_up(struct ksz_device *dev, int
> port,
> @@ -2473,6 +2474,12 @@ static int ksz_max_mtu(struct dsa_switch *ds,
> int port)
>         struct ksz_device *dev = ds->priv;
> 
>         switch (dev->chip_id) {
> +       case KSZ8795_CHIP_ID:
> +       case KSZ8794_CHIP_ID:
> +       case KSZ8765_CHIP_ID:
> +               return KSZ8795_HUGE_PACKET_SIZE - VLAN_ETH_HLEN -
> ETH_FCS_LEN;
> +       case KSZ8830_CHIP_ID:
> +               return KSZ8863_HUGE_PACKET_SIZE - VLAN_ETH_HLEN -
> ETH_FCS_LEN;
>         case KSZ8563_CHIP_ID:
>         case KSZ9477_CHIP_ID:
>         case KSZ9567_CHIP_ID:
> diff --git a/drivers/net/dsa/microchip/ksz_common.h
> b/drivers/net/dsa/microchip/ksz_common.h
> index 85ce6ec573ba..17a13fd3b92e 100644
> --- a/drivers/net/dsa/microchip/ksz_common.h
> +++ b/drivers/net/dsa/microchip/ksz_common.h
> @@ -589,6 +589,10 @@ static inline int is_lan937x(struct ksz_device
> *dev)
> 
>  #define PORT_SRC_PHY_INT               1
> 
> +#define KSZ8795_HUGE_PACKET_SIZE       2000
> +#define KSZ8863_HUGE_PACKET_SIZE       1916
> +#define KSZ8863_NORMAL_PACKET_SIZE     1536
> +#define KSZ8863_LEGAL_PACKET_SIZE      1518
>  #define KSZ9477_MAX_FRAME_SIZE         9000
> 
>  /* Regmap tables generation */
> --
> 2.30.2
>
  

Patch

diff --git a/drivers/net/dsa/microchip/ksz8.h b/drivers/net/dsa/microchip/ksz8.h
index 8582b4b67d98..ea05abfbd51d 100644
--- a/drivers/net/dsa/microchip/ksz8.h
+++ b/drivers/net/dsa/microchip/ksz8.h
@@ -57,5 +57,6 @@  int ksz8_reset_switch(struct ksz_device *dev);
 int ksz8_switch_detect(struct ksz_device *dev);
 int ksz8_switch_init(struct ksz_device *dev);
 void ksz8_switch_exit(struct ksz_device *dev);
+int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu);
 
 #endif
diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c
index bd3b133e7085..804f421d1829 100644
--- a/drivers/net/dsa/microchip/ksz8795.c
+++ b/drivers/net/dsa/microchip/ksz8795.c
@@ -76,6 +76,61 @@  int ksz8_reset_switch(struct ksz_device *dev)
 	return 0;
 }
 
+static int ksz8863_change_mtu(struct ksz_device *dev, int port, int max_frame)
+{
+	u8 ctrl2 = 0;
+
+	if (max_frame <= KSZ8863_LEGAL_PACKET_SIZE)
+		ctrl2 |= KSZ8863_LEGAL_PACKET_ENABLE;
+	else if (max_frame > KSZ8863_NORMAL_PACKET_SIZE)
+		ctrl2 |= KSZ8863_HUGE_PACKET_ENABLE;
+
+	return ksz_rmw8(dev, REG_SW_CTRL_2, KSZ8863_LEGAL_PACKET_ENABLE
+			| KSZ8863_HUGE_PACKET_ENABLE, ctrl2);
+}
+
+static int ksz8795_change_mtu(struct ksz_device *dev, int port, int max_frame)
+{
+	u8 ctrl1 = 0, ctrl2 = 0;
+	int ret;
+
+	if (max_frame > KSZ8863_LEGAL_PACKET_SIZE)
+		ctrl2 |= SW_LEGAL_PACKET_DISABLE;
+	else if (max_frame > KSZ8863_NORMAL_PACKET_SIZE)
+		ctrl1 |= SW_HUGE_PACKET;
+
+	ret = ksz_rmw8(dev, REG_SW_CTRL_1, SW_HUGE_PACKET, ctrl1);
+	if (ret)
+		return ret;
+
+	return ksz_rmw8(dev, REG_SW_CTRL_2, SW_LEGAL_PACKET_DISABLE, ctrl2);
+}
+
+int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu)
+{
+	u16 frame_size, max_frame = 0;
+	int i;
+
+	frame_size = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
+
+	/* Cache the per-port MTU setting */
+	dev->ports[port].max_frame = frame_size;
+
+	for (i = 0; i < dev->info->port_cnt; i++)
+		max_frame = max(max_frame, dev->ports[i].max_frame);
+
+	switch (dev->chip_id) {
+	case KSZ8795_CHIP_ID:
+	case KSZ8794_CHIP_ID:
+	case KSZ8765_CHIP_ID:
+		return ksz8795_change_mtu(dev, port, max_frame);
+	case KSZ8830_CHIP_ID:
+		return ksz8863_change_mtu(dev, port, max_frame);
+	}
+
+	return -EOPNOTSUPP;
+}
+
 static void ksz8795_set_prio_queue(struct ksz_device *dev, int port, int queue)
 {
 	u8 hi, lo;
@@ -1233,8 +1288,6 @@  void ksz8_config_cpu_port(struct dsa_switch *ds)
 	masks = dev->info->masks;
 	regs = dev->info->regs;
 
-	/* Switch marks the maximum frame with extra byte as oversize. */
-	ksz_cfg(dev, REG_SW_CTRL_2, SW_LEGAL_PACKET_DISABLE, true);
 	ksz_cfg(dev, regs[S_TAIL_TAG_CTRL], masks[SW_TAIL_TAG_ENABLE], true);
 
 	p = &dev->ports[dev->cpu_port];
diff --git a/drivers/net/dsa/microchip/ksz8795_reg.h b/drivers/net/dsa/microchip/ksz8795_reg.h
index 77487d611824..7a57c6088f80 100644
--- a/drivers/net/dsa/microchip/ksz8795_reg.h
+++ b/drivers/net/dsa/microchip/ksz8795_reg.h
@@ -48,6 +48,9 @@ 
 #define NO_EXC_COLLISION_DROP		BIT(3)
 #define SW_LEGAL_PACKET_DISABLE		BIT(1)
 
+#define KSZ8863_HUGE_PACKET_ENABLE	BIT(2)
+#define KSZ8863_LEGAL_PACKET_ENABLE	BIT(1)
+
 #define REG_SW_CTRL_3			0x05
  #define WEIGHTED_FAIR_QUEUE_ENABLE	BIT(3)
 
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 486ad03d0acf..188c66145df7 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -172,6 +172,7 @@  static const struct ksz_dev_ops ksz8_dev_ops = {
 	.reset = ksz8_reset_switch,
 	.init = ksz8_switch_init,
 	.exit = ksz8_switch_exit,
+	.change_mtu = ksz8_change_mtu,
 };
 
 static void ksz9477_phylink_mac_link_up(struct ksz_device *dev, int port,
@@ -2473,6 +2474,12 @@  static int ksz_max_mtu(struct dsa_switch *ds, int port)
 	struct ksz_device *dev = ds->priv;
 
 	switch (dev->chip_id) {
+	case KSZ8795_CHIP_ID:
+	case KSZ8794_CHIP_ID:
+	case KSZ8765_CHIP_ID:
+		return KSZ8795_HUGE_PACKET_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN;
+	case KSZ8830_CHIP_ID:
+		return KSZ8863_HUGE_PACKET_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN;
 	case KSZ8563_CHIP_ID:
 	case KSZ9477_CHIP_ID:
 	case KSZ9567_CHIP_ID:
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index 85ce6ec573ba..17a13fd3b92e 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -589,6 +589,10 @@  static inline int is_lan937x(struct ksz_device *dev)
 
 #define PORT_SRC_PHY_INT		1
 
+#define KSZ8795_HUGE_PACKET_SIZE	2000
+#define KSZ8863_HUGE_PACKET_SIZE	1916
+#define KSZ8863_NORMAL_PACKET_SIZE	1536
+#define KSZ8863_LEGAL_PACKET_SIZE	1518
 #define KSZ9477_MAX_FRAME_SIZE		9000
 
 /* Regmap tables generation */