1 // SPDX-License-Identifier: GPL-2.0+
2
3 #include "lan966x_main.h"
4
lan966x_tc_matchall_add(struct lan966x_port * port,struct tc_cls_matchall_offload * f,bool ingress)5 static int lan966x_tc_matchall_add(struct lan966x_port *port,
6 struct tc_cls_matchall_offload *f,
7 bool ingress)
8 {
9 struct flow_action_entry *act;
10
11 if (!flow_offload_has_one_action(&f->rule->action)) {
12 NL_SET_ERR_MSG_MOD(f->common.extack,
13 "Only once action per filter is supported");
14 return -EOPNOTSUPP;
15 }
16
17 act = &f->rule->action.entries[0];
18 switch (act->id) {
19 case FLOW_ACTION_POLICE:
20 return lan966x_police_port_add(port, &f->rule->action, act,
21 f->cookie, ingress,
22 f->common.extack);
23 case FLOW_ACTION_MIRRED:
24 return lan966x_mirror_port_add(port, act, f->cookie,
25 ingress, f->common.extack);
26 default:
27 NL_SET_ERR_MSG_MOD(f->common.extack,
28 "Unsupported action");
29 return -EOPNOTSUPP;
30 }
31
32 return 0;
33 }
34
lan966x_tc_matchall_del(struct lan966x_port * port,struct tc_cls_matchall_offload * f,bool ingress)35 static int lan966x_tc_matchall_del(struct lan966x_port *port,
36 struct tc_cls_matchall_offload *f,
37 bool ingress)
38 {
39 if (f->cookie == port->tc.police_id) {
40 return lan966x_police_port_del(port, f->cookie,
41 f->common.extack);
42 } else if (f->cookie == port->tc.ingress_mirror_id ||
43 f->cookie == port->tc.egress_mirror_id) {
44 return lan966x_mirror_port_del(port, ingress,
45 f->common.extack);
46 } else {
47 NL_SET_ERR_MSG_MOD(f->common.extack,
48 "Unsupported action");
49 return -EOPNOTSUPP;
50 }
51
52 return 0;
53 }
54
lan966x_tc_matchall_stats(struct lan966x_port * port,struct tc_cls_matchall_offload * f,bool ingress)55 static int lan966x_tc_matchall_stats(struct lan966x_port *port,
56 struct tc_cls_matchall_offload *f,
57 bool ingress)
58 {
59 if (f->cookie == port->tc.police_id) {
60 lan966x_police_port_stats(port, &f->stats);
61 } else if (f->cookie == port->tc.ingress_mirror_id ||
62 f->cookie == port->tc.egress_mirror_id) {
63 lan966x_mirror_port_stats(port, &f->stats, ingress);
64 } else {
65 NL_SET_ERR_MSG_MOD(f->common.extack,
66 "Unsupported action");
67 return -EOPNOTSUPP;
68 }
69
70 return 0;
71 }
72
lan966x_tc_matchall(struct lan966x_port * port,struct tc_cls_matchall_offload * f,bool ingress)73 int lan966x_tc_matchall(struct lan966x_port *port,
74 struct tc_cls_matchall_offload *f,
75 bool ingress)
76 {
77 if (!tc_cls_can_offload_and_chain0(port->dev, &f->common)) {
78 NL_SET_ERR_MSG_MOD(f->common.extack,
79 "Only chain zero is supported");
80 return -EOPNOTSUPP;
81 }
82
83 switch (f->command) {
84 case TC_CLSMATCHALL_REPLACE:
85 return lan966x_tc_matchall_add(port, f, ingress);
86 case TC_CLSMATCHALL_DESTROY:
87 return lan966x_tc_matchall_del(port, f, ingress);
88 case TC_CLSMATCHALL_STATS:
89 return lan966x_tc_matchall_stats(port, f, ingress);
90 default:
91 return -EOPNOTSUPP;
92 }
93
94 return 0;
95 }
96