xref: /linux/drivers/net/netdevsim/tc.c (revision 4b99990cdf9560e8a071640baf19f312e6ae02f4)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/netdevice.h>
4 #include <net/pkt_sched.h>
5 #include <net/pkt_cls.h>
6 
7 #include "netdevsim.h"
8 
9 static int
10 nsim_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
11 {
12 	struct flow_cls_common_offload *common = type_data;
13 	int err = 0;
14 
15 	switch (type) {
16 	case TC_SETUP_CLSBPF:
17 		err = nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv);
18 		break;
19 	case TC_SETUP_CLSFLOWER:
20 		break;
21 	default:
22 		NSIM_EA(common->extack, "offload type not supported");
23 		err = -EOPNOTSUPP;
24 		break;
25 	}
26 
27 	return err;
28 }
29 
30 static void nsim_taprio_stats(struct tc_taprio_qopt_stats *stats)
31 {
32 	stats->window_drops = 0;
33 	stats->tx_overruns = 0;
34 }
35 
36 static int nsim_setup_tc_taprio(struct net_device *dev,
37 				struct tc_taprio_qopt_offload *offload)
38 {
39 	int err = 0;
40 
41 	switch (offload->cmd) {
42 	case TAPRIO_CMD_REPLACE:
43 	case TAPRIO_CMD_DESTROY:
44 		break;
45 	case TAPRIO_CMD_STATS:
46 		nsim_taprio_stats(&offload->stats);
47 		break;
48 	default:
49 		err = -EOPNOTSUPP;
50 	}
51 
52 	return err;
53 }
54 
55 static int nsim_setup_tc_ets(struct net_device *dev,
56 			     struct tc_ets_qopt_offload *offload)
57 {
58 	int err = 0;
59 
60 	switch (offload->command) {
61 	case TC_ETS_REPLACE:
62 	case TC_ETS_DESTROY:
63 		break;
64 	case TC_ETS_STATS:
65 		_bstats_update(offload->stats.bstats, 0, 0);
66 		break;
67 	default:
68 		err = -EOPNOTSUPP;
69 	}
70 
71 	return err;
72 }
73 
74 static LIST_HEAD(nsim_block_cb_list);
75 
76 int
77 nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
78 {
79 	struct netdevsim *ns = netdev_priv(dev);
80 
81 	switch (type) {
82 	case TC_SETUP_QDISC_TAPRIO:
83 		return nsim_setup_tc_taprio(dev, type_data);
84 	case TC_SETUP_QDISC_ETS:
85 		return nsim_setup_tc_ets(dev, type_data);
86 	case TC_SETUP_BLOCK:
87 		return flow_block_cb_setup_simple(type_data,
88 						  &nsim_block_cb_list,
89 						  nsim_setup_tc_block_cb,
90 						  ns, ns, true);
91 	case TC_SETUP_FT:
92 		return 0;
93 	default:
94 		return -EOPNOTSUPP;
95 	}
96 }
97 ALLOW_ERROR_INJECTION(nsim_setup_tc, ERRNO);
98