kernel: 5.10: backport qca8k new feature
[openwrt/openwrt.git] / target / linux / generic / backport-5.10 / 760-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch
diff --git a/target/linux/generic/backport-5.10/760-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch b/target/linux/generic/backport-5.10/760-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch
new file mode 100644 (file)
index 0000000..f32e6ae
--- /dev/null
@@ -0,0 +1,78 @@
+From 6a3bdc5209f45d2af83aa92433ab6e5cf2297aa4 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Mon, 22 Nov 2021 16:23:47 +0100
+Subject: net: dsa: qca8k: add set_ageing_time support
+
+qca8k support setting ageing time in step of 7s. Add support for it and
+set the max value accepted of 7645m.
+Documentation talks about support for 10000m but that values doesn't
+make sense as the value doesn't match the max value in the reg.
+
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/qca8k.c | 25 +++++++++++++++++++++++++
+ drivers/net/dsa/qca8k.h |  3 +++
+ 2 files changed, 28 insertions(+)
+
+--- a/drivers/net/dsa/qca8k.c
++++ b/drivers/net/dsa/qca8k.c
+@@ -1261,6 +1261,10 @@ qca8k_setup(struct dsa_switch *ds)
+       /* We don't have interrupts for link changes, so we need to poll */
+       ds->pcs_poll = true;
++      /* Set min a max ageing value supported */
++      ds->ageing_time_min = 7000;
++      ds->ageing_time_max = 458745000;
++
+       return 0;
+ }
+@@ -1801,6 +1805,26 @@ qca8k_port_fast_age(struct dsa_switch *d
+ }
+ static int
++qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
++{
++      struct qca8k_priv *priv = ds->priv;
++      unsigned int secs = msecs / 1000;
++      u32 val;
++
++      /* AGE_TIME reg is set in 7s step */
++      val = secs / 7;
++
++      /* Handle case with 0 as val to NOT disable
++       * learning
++       */
++      if (!val)
++              val = 1;
++
++      return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK,
++                                QCA8K_ATU_AGE_TIME(val));
++}
++
++static int
+ qca8k_port_enable(struct dsa_switch *ds, int port,
+                 struct phy_device *phy)
+ {
+@@ -2006,6 +2030,7 @@ static const struct dsa_switch_ops qca8k
+       .get_strings            = qca8k_get_strings,
+       .get_ethtool_stats      = qca8k_get_ethtool_stats,
+       .get_sset_count         = qca8k_get_sset_count,
++      .set_ageing_time        = qca8k_set_ageing_time,
+       .get_mac_eee            = qca8k_get_mac_eee,
+       .set_mac_eee            = qca8k_set_mac_eee,
+       .port_enable            = qca8k_port_enable,
+--- a/drivers/net/dsa/qca8k.h
++++ b/drivers/net/dsa/qca8k.h
+@@ -175,6 +175,9 @@
+ #define   QCA8K_VTU_FUNC1_BUSY                                BIT(31)
+ #define   QCA8K_VTU_FUNC1_VID_MASK                    GENMASK(27, 16)
+ #define   QCA8K_VTU_FUNC1_FULL                                BIT(4)
++#define QCA8K_REG_ATU_CTRL                            0x618
++#define   QCA8K_ATU_AGE_TIME_MASK                     GENMASK(15, 0)
++#define   QCA8K_ATU_AGE_TIME(x)                               FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x))
+ #define QCA8K_REG_GLOBAL_FW_CTRL0                     0x620
+ #define   QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN           BIT(10)
+ #define QCA8K_REG_GLOBAL_FW_CTRL1                     0x624