mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 06:31:58 +02:00
net: dsa: mt7530: Add TBF qdisc offload support
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> Link: https://patch.msgid.link/20241031-mt7530-tc-offload-v2-1-cb242ad954a0@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
61bf0009a7
commit
2e570cd187
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user