Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Lorenzo Bianconi and committed by
Jakub Kicinski
2e570cd1 61bf0009

+61
+49
drivers/net/dsa/mt7530.c
··· 21 21 #include <linux/gpio/consumer.h> 22 22 #include <linux/gpio/driver.h> 23 23 #include <net/dsa.h> 24 + #include <net/pkt_cls.h> 24 25 25 26 #include "mt7530.h" 26 27 ··· 3147 3146 mt7530_rmw(priv, MT753X_MFC, MT7530_CPU_EN | MT7530_CPU_PORT_MASK, val); 3148 3147 } 3149 3148 3149 + static int mt753x_tc_setup_qdisc_tbf(struct dsa_switch *ds, int port, 3150 + struct tc_tbf_qopt_offload *qopt) 3151 + { 3152 + struct tc_tbf_qopt_offload_replace_params *p = &qopt->replace_params; 3153 + struct mt7530_priv *priv = ds->priv; 3154 + u32 rate = 0; 3155 + 3156 + switch (qopt->command) { 3157 + case TC_TBF_REPLACE: 3158 + rate = div_u64(p->rate.rate_bytes_ps, 1000) << 3; /* kbps */ 3159 + fallthrough; 3160 + case TC_TBF_DESTROY: { 3161 + u32 val, tick; 3162 + 3163 + mt7530_rmw(priv, MT753X_GERLCR, EGR_BC_MASK, 3164 + EGR_BC_CRC_IPG_PREAMBLE); 3165 + 3166 + /* if rate is greater than 10Mbps tick is 1/32 ms, 3167 + * 1ms otherwise 3168 + */ 3169 + tick = rate > 10000 ? 2 : 7; 3170 + val = FIELD_PREP(ERLCR_CIR_MASK, (rate >> 5)) | 3171 + FIELD_PREP(ERLCR_EN_MASK, !!rate) | 3172 + FIELD_PREP(ERLCR_EXP_MASK, tick) | 3173 + ERLCR_TBF_MODE_MASK | 3174 + FIELD_PREP(ERLCR_MANT_MASK, 0xf); 3175 + mt7530_write(priv, MT753X_ERLCR_P(port), val); 3176 + break; 3177 + } 3178 + default: 3179 + return -EOPNOTSUPP; 3180 + } 3181 + 3182 + return 0; 3183 + } 3184 + 3185 + static int mt753x_setup_tc(struct dsa_switch *ds, int port, 3186 + enum tc_setup_type type, void *type_data) 3187 + { 3188 + switch (type) { 3189 + case TC_SETUP_QDISC_TBF: 3190 + return mt753x_tc_setup_qdisc_tbf(ds, port, type_data); 3191 + default: 3192 + return -EOPNOTSUPP; 3193 + } 3194 + } 3195 + 3150 3196 static int mt7988_setup(struct dsa_switch *ds) 3151 3197 { 3152 3198 struct mt7530_priv *priv = ds->priv; ··· 3241 3193 .get_mac_eee = mt753x_get_mac_eee, 3242 3194 .set_mac_eee = mt753x_set_mac_eee, 3243 3195 .conduit_state_change = mt753x_conduit_state_change, 3196 + .port_setup_tc = mt753x_setup_tc, 3244 3197 }; 3245 3198 EXPORT_SYMBOL_GPL(mt7530_switch_ops); 3246 3199
+12
drivers/net/dsa/mt7530.h
··· 248 248 #define AGE_UNIT_MAX 0xfff 249 249 #define AGE_UNIT(x) (AGE_UNIT_MASK & (x)) 250 250 251 + #define MT753X_ERLCR_P(x) (0x1040 + ((x) * 0x100)) 252 + #define ERLCR_CIR_MASK GENMASK(31, 16) 253 + #define ERLCR_EN_MASK BIT(15) 254 + #define ERLCR_EXP_MASK GENMASK(11, 8) 255 + #define ERLCR_TBF_MODE_MASK BIT(7) 256 + #define ERLCR_MANT_MASK GENMASK(6, 0) 257 + 258 + #define MT753X_GERLCR 0x10e0 259 + #define EGR_BC_MASK GENMASK(7, 0) 260 + #define EGR_BC_CRC 0x4 /* crc */ 261 + #define EGR_BC_CRC_IPG_PREAMBLE 0x18 /* crc + ipg + preamble */ 262 + 251 263 /* Register for port STP state control */ 252 264 #define MT7530_SSP_P(x) (0x2000 + ((x) * 0x100)) 253 265 #define FID_PST(fid, state) (((state) & 0x3) << ((fid) * 2))