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 case FLOW_ACTION_GOTO:
27 return lan966x_goto_port_add(port, f->common.chain_index,
28 act->chain_index, f->cookie,
29 f->common.extack);
30 default:
31 NL_SET_ERR_MSG_MOD(f->common.extack,
32 "Unsupported action");
33 return -EOPNOTSUPP;
34 }
35
36 return 0;
37 }
38
lan966x_tc_matchall_del(struct lan966x_port * port,struct tc_cls_matchall_offload * f,bool ingress)39 static int lan966x_tc_matchall_del(struct lan966x_port *port,
40 struct tc_cls_matchall_offload *f,
41 bool ingress)
42 {
43 if (f->cookie == port->tc.police_id) {
44 return lan966x_police_port_del(port, f->cookie,
45 f->common.extack);
46 } else if (f->cookie == port->tc.ingress_mirror_id ||
47 f->cookie == port->tc.egress_mirror_id) {
48 return lan966x_mirror_port_del(port, ingress,
49 f->common.extack);
50 } else {
51 return lan966x_goto_port_del(port, f->cookie, f->common.extack);
52 }
53
54 return 0;
55 }
56
lan966x_tc_matchall_stats(struct lan966x_port * port,struct tc_cls_matchall_offload * f,bool ingress)57 static int lan966x_tc_matchall_stats(struct lan966x_port *port,
58 struct tc_cls_matchall_offload *f,
59 bool ingress)
60 {
61 if (f->cookie == port->tc.police_id) {
62 lan966x_police_port_stats(port, &f->stats);
63 } else if (f->cookie == port->tc.ingress_mirror_id ||
64 f->cookie == port->tc.egress_mirror_id) {
65 lan966x_mirror_port_stats(port, &f->stats, ingress);
66 } else {
67 NL_SET_ERR_MSG_MOD(f->common.extack,
68 "Unsupported action");
69 return -EOPNOTSUPP;
70 }
71
72 return 0;
73 }
74
lan966x_tc_matchall(struct lan966x_port * port,struct tc_cls_matchall_offload * f,bool ingress)75 int lan966x_tc_matchall(struct lan966x_port *port,
76 struct tc_cls_matchall_offload *f,
77 bool ingress)
78 {
79 switch (f->command) {
80 case TC_CLSMATCHALL_REPLACE:
81 return lan966x_tc_matchall_add(port, f, ingress);
82 case TC_CLSMATCHALL_DESTROY:
83 return lan966x_tc_matchall_del(port, f, ingress);
84 case TC_CLSMATCHALL_STATS:
85 return lan966x_tc_matchall_stats(port, f, ingress);
86 default:
87 return -EOPNOTSUPP;
88 }
89
90 return 0;
91 }
92