xref: /openbmc/linux/drivers/net/ethernet/microchip/lan966x/lan966x_tc.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
13c83431fSHoratiu Vultur // SPDX-License-Identifier: GPL-2.0+
23c83431fSHoratiu Vultur 
33c83431fSHoratiu Vultur #include <net/pkt_cls.h>
49adafe2bSVladimir Oltean #include <net/pkt_sched.h>
53c83431fSHoratiu Vultur 
63c83431fSHoratiu Vultur #include "lan966x_main.h"
73c83431fSHoratiu Vultur 
85390334bSHoratiu Vultur static LIST_HEAD(lan966x_tc_block_cb_list);
95390334bSHoratiu Vultur 
lan966x_tc_setup_qdisc_mqprio(struct lan966x_port * port,struct tc_mqprio_qopt_offload * mqprio)103c83431fSHoratiu Vultur static int lan966x_tc_setup_qdisc_mqprio(struct lan966x_port *port,
113c83431fSHoratiu Vultur 					 struct tc_mqprio_qopt_offload *mqprio)
123c83431fSHoratiu Vultur {
133c83431fSHoratiu Vultur 	u8 num_tc = mqprio->qopt.num_tc;
143c83431fSHoratiu Vultur 
153c83431fSHoratiu Vultur 	mqprio->qopt.hw = TC_MQPRIO_HW_OFFLOAD_TCS;
163c83431fSHoratiu Vultur 
173c83431fSHoratiu Vultur 	return num_tc ? lan966x_mqprio_add(port, num_tc) :
183c83431fSHoratiu Vultur 			lan966x_mqprio_del(port);
193c83431fSHoratiu Vultur }
203c83431fSHoratiu Vultur 
lan966x_tc_setup_qdisc_taprio(struct lan966x_port * port,struct tc_taprio_qopt_offload * taprio)21e462b271SHoratiu Vultur static int lan966x_tc_setup_qdisc_taprio(struct lan966x_port *port,
22e462b271SHoratiu Vultur 					 struct tc_taprio_qopt_offload *taprio)
23e462b271SHoratiu Vultur {
24*2d800bc5SVladimir Oltean 	switch (taprio->cmd) {
25*2d800bc5SVladimir Oltean 	case TAPRIO_CMD_REPLACE:
26*2d800bc5SVladimir Oltean 		return lan966x_taprio_add(port, taprio);
27*2d800bc5SVladimir Oltean 	case TAPRIO_CMD_DESTROY:
28*2d800bc5SVladimir Oltean 		return lan966x_taprio_del(port);
29*2d800bc5SVladimir Oltean 	default:
30*2d800bc5SVladimir Oltean 		return -EOPNOTSUPP;
31*2d800bc5SVladimir Oltean 	}
32e462b271SHoratiu Vultur }
33e462b271SHoratiu Vultur 
lan966x_tc_setup_qdisc_tbf(struct lan966x_port * port,struct tc_tbf_qopt_offload * qopt)3494644b6dSHoratiu Vultur static int lan966x_tc_setup_qdisc_tbf(struct lan966x_port *port,
3594644b6dSHoratiu Vultur 				      struct tc_tbf_qopt_offload *qopt)
3694644b6dSHoratiu Vultur {
3794644b6dSHoratiu Vultur 	switch (qopt->command) {
3894644b6dSHoratiu Vultur 	case TC_TBF_REPLACE:
3994644b6dSHoratiu Vultur 		return lan966x_tbf_add(port, qopt);
4094644b6dSHoratiu Vultur 	case TC_TBF_DESTROY:
4194644b6dSHoratiu Vultur 		return lan966x_tbf_del(port, qopt);
4294644b6dSHoratiu Vultur 	default:
4394644b6dSHoratiu Vultur 		return -EOPNOTSUPP;
4494644b6dSHoratiu Vultur 	}
4594644b6dSHoratiu Vultur 
4694644b6dSHoratiu Vultur 	return -EOPNOTSUPP;
4794644b6dSHoratiu Vultur }
4894644b6dSHoratiu Vultur 
lan966x_tc_setup_qdisc_cbs(struct lan966x_port * port,struct tc_cbs_qopt_offload * qopt)4921ce14a8SHoratiu Vultur static int lan966x_tc_setup_qdisc_cbs(struct lan966x_port *port,
5021ce14a8SHoratiu Vultur 				      struct tc_cbs_qopt_offload *qopt)
5121ce14a8SHoratiu Vultur {
5221ce14a8SHoratiu Vultur 	return qopt->enable ? lan966x_cbs_add(port, qopt) :
5321ce14a8SHoratiu Vultur 			      lan966x_cbs_del(port, qopt);
5421ce14a8SHoratiu Vultur }
5521ce14a8SHoratiu Vultur 
lan966x_tc_setup_qdisc_ets(struct lan966x_port * port,struct tc_ets_qopt_offload * qopt)5629aaf3d4SHoratiu Vultur static int lan966x_tc_setup_qdisc_ets(struct lan966x_port *port,
5729aaf3d4SHoratiu Vultur 				      struct tc_ets_qopt_offload *qopt)
5829aaf3d4SHoratiu Vultur {
5929aaf3d4SHoratiu Vultur 	switch (qopt->command) {
6029aaf3d4SHoratiu Vultur 	case TC_ETS_REPLACE:
6129aaf3d4SHoratiu Vultur 		return lan966x_ets_add(port, qopt);
6229aaf3d4SHoratiu Vultur 	case TC_ETS_DESTROY:
6329aaf3d4SHoratiu Vultur 		return lan966x_ets_del(port, qopt);
6429aaf3d4SHoratiu Vultur 	default:
6529aaf3d4SHoratiu Vultur 		return -EOPNOTSUPP;
6629aaf3d4SHoratiu Vultur 	};
6729aaf3d4SHoratiu Vultur 
6829aaf3d4SHoratiu Vultur 	return -EOPNOTSUPP;
6929aaf3d4SHoratiu Vultur }
7029aaf3d4SHoratiu Vultur 
lan966x_tc_block_cb(enum tc_setup_type type,void * type_data,void * cb_priv,bool ingress)715390334bSHoratiu Vultur static int lan966x_tc_block_cb(enum tc_setup_type type, void *type_data,
725390334bSHoratiu Vultur 			       void *cb_priv, bool ingress)
735390334bSHoratiu Vultur {
745390334bSHoratiu Vultur 	struct lan966x_port *port = cb_priv;
755390334bSHoratiu Vultur 
765390334bSHoratiu Vultur 	switch (type) {
775390334bSHoratiu Vultur 	case TC_SETUP_CLSMATCHALL:
785390334bSHoratiu Vultur 		return lan966x_tc_matchall(port, type_data, ingress);
793643abd6SHoratiu Vultur 	case TC_SETUP_CLSFLOWER:
80e7e3f514SSteen Hegelund 		return lan966x_tc_flower(port, type_data, ingress);
815390334bSHoratiu Vultur 	default:
825390334bSHoratiu Vultur 		return -EOPNOTSUPP;
835390334bSHoratiu Vultur 	}
845390334bSHoratiu Vultur }
855390334bSHoratiu Vultur 
lan966x_tc_block_cb_ingress(enum tc_setup_type type,void * type_data,void * cb_priv)865390334bSHoratiu Vultur static int lan966x_tc_block_cb_ingress(enum tc_setup_type type,
875390334bSHoratiu Vultur 				       void *type_data, void *cb_priv)
885390334bSHoratiu Vultur {
895390334bSHoratiu Vultur 	return lan966x_tc_block_cb(type, type_data, cb_priv, true);
905390334bSHoratiu Vultur }
915390334bSHoratiu Vultur 
lan966x_tc_block_cb_egress(enum tc_setup_type type,void * type_data,void * cb_priv)925390334bSHoratiu Vultur static int lan966x_tc_block_cb_egress(enum tc_setup_type type,
935390334bSHoratiu Vultur 				      void *type_data, void *cb_priv)
945390334bSHoratiu Vultur {
955390334bSHoratiu Vultur 	return lan966x_tc_block_cb(type, type_data, cb_priv, false);
965390334bSHoratiu Vultur }
975390334bSHoratiu Vultur 
lan966x_tc_setup_block(struct lan966x_port * port,struct flow_block_offload * f)985390334bSHoratiu Vultur static int lan966x_tc_setup_block(struct lan966x_port *port,
995390334bSHoratiu Vultur 				  struct flow_block_offload *f)
1005390334bSHoratiu Vultur {
1015390334bSHoratiu Vultur 	flow_setup_cb_t *cb;
1025390334bSHoratiu Vultur 	bool ingress;
1035390334bSHoratiu Vultur 
1045390334bSHoratiu Vultur 	if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) {
1055390334bSHoratiu Vultur 		cb = lan966x_tc_block_cb_ingress;
1065390334bSHoratiu Vultur 		port->tc.ingress_shared_block = f->block_shared;
1075390334bSHoratiu Vultur 		ingress = true;
1085390334bSHoratiu Vultur 	} else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) {
1095390334bSHoratiu Vultur 		cb = lan966x_tc_block_cb_egress;
1105390334bSHoratiu Vultur 		ingress = false;
1115390334bSHoratiu Vultur 	} else {
1125390334bSHoratiu Vultur 		return -EOPNOTSUPP;
1135390334bSHoratiu Vultur 	}
1145390334bSHoratiu Vultur 
1155390334bSHoratiu Vultur 	return flow_block_cb_setup_simple(f, &lan966x_tc_block_cb_list,
1165390334bSHoratiu Vultur 					  cb, port, port, ingress);
1175390334bSHoratiu Vultur }
1185390334bSHoratiu Vultur 
lan966x_tc_setup(struct net_device * dev,enum tc_setup_type type,void * type_data)1193c83431fSHoratiu Vultur int lan966x_tc_setup(struct net_device *dev, enum tc_setup_type type,
1203c83431fSHoratiu Vultur 		     void *type_data)
1213c83431fSHoratiu Vultur {
1223c83431fSHoratiu Vultur 	struct lan966x_port *port = netdev_priv(dev);
1233c83431fSHoratiu Vultur 
1243c83431fSHoratiu Vultur 	switch (type) {
1253c83431fSHoratiu Vultur 	case TC_SETUP_QDISC_MQPRIO:
1263c83431fSHoratiu Vultur 		return lan966x_tc_setup_qdisc_mqprio(port, type_data);
127e462b271SHoratiu Vultur 	case TC_SETUP_QDISC_TAPRIO:
128e462b271SHoratiu Vultur 		return lan966x_tc_setup_qdisc_taprio(port, type_data);
12994644b6dSHoratiu Vultur 	case TC_SETUP_QDISC_TBF:
13094644b6dSHoratiu Vultur 		return lan966x_tc_setup_qdisc_tbf(port, type_data);
13121ce14a8SHoratiu Vultur 	case TC_SETUP_QDISC_CBS:
13221ce14a8SHoratiu Vultur 		return lan966x_tc_setup_qdisc_cbs(port, type_data);
13329aaf3d4SHoratiu Vultur 	case TC_SETUP_QDISC_ETS:
13429aaf3d4SHoratiu Vultur 		return lan966x_tc_setup_qdisc_ets(port, type_data);
1355390334bSHoratiu Vultur 	case TC_SETUP_BLOCK:
1365390334bSHoratiu Vultur 		return lan966x_tc_setup_block(port, type_data);
1373c83431fSHoratiu Vultur 	default:
1383c83431fSHoratiu Vultur 		return -EOPNOTSUPP;
1393c83431fSHoratiu Vultur 	}
1403c83431fSHoratiu Vultur 
1413c83431fSHoratiu Vultur 	return 0;
1423c83431fSHoratiu Vultur }
143