diff mbox series

[net-next,v2] net: dsa: mt7530: Add TBF qdisc offload support

Message ID 20241031-mt7530-tc-offload-v2-1-cb242ad954a0@kernel.org (mailing list archive)
State New
Delegated to: Netdev Maintainers
Headers show
Series [net-next,v2] net: dsa: mt7530: Add TBF qdisc offload support | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 5 this patch: 5
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 15 of 15 maintainers
netdev/build_clang success Errors and warnings before: 3 this patch: 3
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 4 this patch: 4
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 85 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest fail net-next-2024-11-01--00-00 (tests: 110)

Commit Message

Lorenzo Bianconi Oct. 31, 2024, 2:28 p.m. UTC
Introduce port_setup_tc callback in mt7530 dsa driver in order to enable
dsa ports rate shaping via hw Token Bucket Filter (TBF) for hw switched
traffic.

Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
Changes in v2:
- remove device id limitation and allow tbf qdisc configuration on each mt7530
  compliant devices
- rename MT7530_ERLCR_P in MT753X_ERLCR_P and MT7530_GERLCR in
  MT753X_GERLCR
- Link to v1: https://lore.kernel.org/r/20241030-mt7530-tc-offload-v1-1-f7eeffaf3d9e@kernel.org
---
 drivers/net/dsa/mt7530.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/dsa/mt7530.h | 12 ++++++++++++
 2 files changed, 61 insertions(+)


---
base-commit: 157a4881225bd0af5444aab9510e7b6da28f2469
change-id: 20241030-mt7530-tc-offload-05e204441500

Best regards,

Comments

Arınç ÜNAL Oct. 31, 2024, 2:54 p.m. UTC | #1
This is a very nice addition, thanks for working on this!

Arınç

On 31/10/2024 17:28, Lorenzo Bianconi wrote:
> Introduce port_setup_tc callback in mt7530 dsa driver in order to enable
> dsa ports rate shaping via hw Token Bucket Filter (TBF) for hw switched
> traffic.
> 
> Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> Changes in v2:
> - remove device id limitation and allow tbf qdisc configuration on each mt7530
>    compliant devices
> - rename MT7530_ERLCR_P in MT753X_ERLCR_P and MT7530_GERLCR in
>    MT753X_GERLCR
> - Link to v1: https://lore.kernel.org/r/20241030-mt7530-tc-offload-v1-1-f7eeffaf3d9e@kernel.org
> ---
>   drivers/net/dsa/mt7530.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
>   drivers/net/dsa/mt7530.h | 12 ++++++++++++
>   2 files changed, 61 insertions(+)
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index d84ee1b419a614dda5f440e6571cff5f4f27bf21..086b8b3d5b40f776815967492914bd46a04b6886 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -21,6 +21,7 @@
>   #include <linux/gpio/consumer.h>
>   #include <linux/gpio/driver.h>
>   #include <net/dsa.h>
> +#include <net/pkt_cls.h>
>   
>   #include "mt7530.h"
>   
> @@ -3146,6 +3147,53 @@ mt753x_conduit_state_change(struct dsa_switch *ds,
>   	mt7530_rmw(priv, MT753X_MFC, MT7530_CPU_EN | MT7530_CPU_PORT_MASK, val);
>   }
>   
> +static int mt753x_tc_setup_qdisc_tbf(struct dsa_switch *ds, int port,
> +				     struct tc_tbf_qopt_offload *qopt)
> +{
> +	struct tc_tbf_qopt_offload_replace_params *p = &qopt->replace_params;
> +	struct mt7530_priv *priv = ds->priv;
> +	u32 rate = 0;
> +
> +	switch (qopt->command) {
> +	case TC_TBF_REPLACE:
> +		rate = div_u64(p->rate.rate_bytes_ps, 1000) << 3; /* kbps */
> +		fallthrough;
> +	case TC_TBF_DESTROY: {
> +		u32 val, tick;
> +
> +		mt7530_rmw(priv, MT753X_GERLCR, EGR_BC_MASK,
> +			   EGR_BC_CRC_IPG_PREAMBLE);
> +
> +		/* if rate is greater than 10Mbps tick is 1/32 ms,
> +		 * 1ms otherwise
> +		 */
> +		tick = rate > 10000 ? 2 : 7;
> +		val = FIELD_PREP(ERLCR_CIR_MASK, (rate >> 5)) |
> +		      FIELD_PREP(ERLCR_EN_MASK, !!rate) |
> +		      FIELD_PREP(ERLCR_EXP_MASK, tick) |
> +		      ERLCR_TBF_MODE_MASK |
> +		      FIELD_PREP(ERLCR_MANT_MASK, 0xf);
> +		mt7530_write(priv, MT753X_ERLCR_P(port), val);
> +		break;
> +	}
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mt753x_setup_tc(struct dsa_switch *ds, int port,
> +			   enum tc_setup_type type, void *type_data)
> +{
> +	switch (type) {
> +	case TC_SETUP_QDISC_TBF:
> +		return mt753x_tc_setup_qdisc_tbf(ds, port, type_data);
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +}
> +
>   static int mt7988_setup(struct dsa_switch *ds)
>   {
>   	struct mt7530_priv *priv = ds->priv;
> @@ -3193,6 +3241,7 @@ const struct dsa_switch_ops mt7530_switch_ops = {
>   	.get_mac_eee		= mt753x_get_mac_eee,
>   	.set_mac_eee		= mt753x_set_mac_eee,
>   	.conduit_state_change	= mt753x_conduit_state_change,
> +	.port_setup_tc		= mt753x_setup_tc,
>   };
>   EXPORT_SYMBOL_GPL(mt7530_switch_ops);
>   
> diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
> index 6ad33a9f6b1dff3a423baa668a8a2ca158f72b91..448200689f492dcb73ef056d7284090c1c662e67 100644
> --- a/drivers/net/dsa/mt7530.h
> +++ b/drivers/net/dsa/mt7530.h
> @@ -248,6 +248,18 @@ enum mt7530_vlan_egress_attr {
>   #define  AGE_UNIT_MAX			0xfff
>   #define  AGE_UNIT(x)			(AGE_UNIT_MASK & (x))
>   
> +#define MT753X_ERLCR_P(x)		(0x1040 + ((x) * 0x100))
> +#define  ERLCR_CIR_MASK			GENMASK(31, 16)
> +#define  ERLCR_EN_MASK			BIT(15)
> +#define  ERLCR_EXP_MASK			GENMASK(11, 8)
> +#define  ERLCR_TBF_MODE_MASK		BIT(7)
> +#define  ERLCR_MANT_MASK		GENMASK(6, 0)
> +
> +#define MT753X_GERLCR			0x10e0
> +#define  EGR_BC_MASK			GENMASK(7, 0)
> +#define  EGR_BC_CRC			0x4	/* crc */
> +#define  EGR_BC_CRC_IPG_PREAMBLE	0x18	/* crc + ipg + preamble */
> +
>   /* Register for port STP state control */
>   #define MT7530_SSP_P(x)			(0x2000 + ((x) * 0x100))
>   #define  FID_PST(fid, state)		(((state) & 0x3) << ((fid) * 2))
> 
> ---
> base-commit: 157a4881225bd0af5444aab9510e7b6da28f2469
> change-id: 20241030-mt7530-tc-offload-05e204441500
> 
> Best regards,
Andrew Lunn Oct. 31, 2024, 6:31 p.m. UTC | #2
On Thu, Oct 31, 2024 at 03:28:18PM +0100, Lorenzo Bianconi wrote:
> Introduce port_setup_tc callback in mt7530 dsa driver in order to enable
> dsa ports rate shaping via hw Token Bucket Filter (TBF) for hw switched
> traffic.
> 
> Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

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

    Andrew
diff mbox series

Patch

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index d84ee1b419a614dda5f440e6571cff5f4f27bf21..086b8b3d5b40f776815967492914bd46a04b6886 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -21,6 +21,7 @@ 
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
 #include <net/dsa.h>
+#include <net/pkt_cls.h>
 
 #include "mt7530.h"
 
@@ -3146,6 +3147,53 @@  mt753x_conduit_state_change(struct dsa_switch *ds,
 	mt7530_rmw(priv, MT753X_MFC, MT7530_CPU_EN | MT7530_CPU_PORT_MASK, val);
 }
 
+static int mt753x_tc_setup_qdisc_tbf(struct dsa_switch *ds, int port,
+				     struct tc_tbf_qopt_offload *qopt)
+{
+	struct tc_tbf_qopt_offload_replace_params *p = &qopt->replace_params;
+	struct mt7530_priv *priv = ds->priv;
+	u32 rate = 0;
+
+	switch (qopt->command) {
+	case TC_TBF_REPLACE:
+		rate = div_u64(p->rate.rate_bytes_ps, 1000) << 3; /* kbps */
+		fallthrough;
+	case TC_TBF_DESTROY: {
+		u32 val, tick;
+
+		mt7530_rmw(priv, MT753X_GERLCR, EGR_BC_MASK,
+			   EGR_BC_CRC_IPG_PREAMBLE);
+
+		/* if rate is greater than 10Mbps tick is 1/32 ms,
+		 * 1ms otherwise
+		 */
+		tick = rate > 10000 ? 2 : 7;
+		val = FIELD_PREP(ERLCR_CIR_MASK, (rate >> 5)) |
+		      FIELD_PREP(ERLCR_EN_MASK, !!rate) |
+		      FIELD_PREP(ERLCR_EXP_MASK, tick) |
+		      ERLCR_TBF_MODE_MASK |
+		      FIELD_PREP(ERLCR_MANT_MASK, 0xf);
+		mt7530_write(priv, MT753X_ERLCR_P(port), val);
+		break;
+	}
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int mt753x_setup_tc(struct dsa_switch *ds, int port,
+			   enum tc_setup_type type, void *type_data)
+{
+	switch (type) {
+	case TC_SETUP_QDISC_TBF:
+		return mt753x_tc_setup_qdisc_tbf(ds, port, type_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 static int mt7988_setup(struct dsa_switch *ds)
 {
 	struct mt7530_priv *priv = ds->priv;
@@ -3193,6 +3241,7 @@  const struct dsa_switch_ops mt7530_switch_ops = {
 	.get_mac_eee		= mt753x_get_mac_eee,
 	.set_mac_eee		= mt753x_set_mac_eee,
 	.conduit_state_change	= mt753x_conduit_state_change,
+	.port_setup_tc		= mt753x_setup_tc,
 };
 EXPORT_SYMBOL_GPL(mt7530_switch_ops);
 
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 6ad33a9f6b1dff3a423baa668a8a2ca158f72b91..448200689f492dcb73ef056d7284090c1c662e67 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -248,6 +248,18 @@  enum mt7530_vlan_egress_attr {
 #define  AGE_UNIT_MAX			0xfff
 #define  AGE_UNIT(x)			(AGE_UNIT_MASK & (x))
 
+#define MT753X_ERLCR_P(x)		(0x1040 + ((x) * 0x100))
+#define  ERLCR_CIR_MASK			GENMASK(31, 16)
+#define  ERLCR_EN_MASK			BIT(15)
+#define  ERLCR_EXP_MASK			GENMASK(11, 8)
+#define  ERLCR_TBF_MODE_MASK		BIT(7)
+#define  ERLCR_MANT_MASK		GENMASK(6, 0)
+
+#define MT753X_GERLCR			0x10e0
+#define  EGR_BC_MASK			GENMASK(7, 0)
+#define  EGR_BC_CRC			0x4	/* crc */
+#define  EGR_BC_CRC_IPG_PREAMBLE	0x18	/* crc + ipg + preamble */
+
 /* Register for port STP state control */
 #define MT7530_SSP_P(x)			(0x2000 + ((x) * 0x100))
 #define  FID_PST(fid, state)		(((state) & 0x3) << ((fid) * 2))