Loading...
1// SPDX-License-Identifier: GPL-2.0+
2
3#include "lan966x_main.h"
4
5static 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
39static 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
57static 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
75int 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}
1// SPDX-License-Identifier: GPL-2.0+
2
3#include "lan966x_main.h"
4
5static 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, act, f->cookie,
28 f->common.extack);
29 default:
30 NL_SET_ERR_MSG_MOD(f->common.extack,
31 "Unsupported action");
32 return -EOPNOTSUPP;
33 }
34
35 return 0;
36}
37
38static int lan966x_tc_matchall_del(struct lan966x_port *port,
39 struct tc_cls_matchall_offload *f,
40 bool ingress)
41{
42 if (f->cookie == port->tc.police_id) {
43 return lan966x_police_port_del(port, f->cookie,
44 f->common.extack);
45 } else if (f->cookie == port->tc.ingress_mirror_id ||
46 f->cookie == port->tc.egress_mirror_id) {
47 return lan966x_mirror_port_del(port, ingress,
48 f->common.extack);
49 } else if (f->cookie == port->tc.goto_id) {
50 return lan966x_goto_port_del(port, f->cookie,
51 f->common.extack);
52 } else {
53 NL_SET_ERR_MSG_MOD(f->common.extack,
54 "Unsupported action");
55 return -EOPNOTSUPP;
56 }
57
58 return 0;
59}
60
61static int lan966x_tc_matchall_stats(struct lan966x_port *port,
62 struct tc_cls_matchall_offload *f,
63 bool ingress)
64{
65 if (f->cookie == port->tc.police_id) {
66 lan966x_police_port_stats(port, &f->stats);
67 } else if (f->cookie == port->tc.ingress_mirror_id ||
68 f->cookie == port->tc.egress_mirror_id) {
69 lan966x_mirror_port_stats(port, &f->stats, ingress);
70 } else {
71 NL_SET_ERR_MSG_MOD(f->common.extack,
72 "Unsupported action");
73 return -EOPNOTSUPP;
74 }
75
76 return 0;
77}
78
79int lan966x_tc_matchall(struct lan966x_port *port,
80 struct tc_cls_matchall_offload *f,
81 bool ingress)
82{
83 if (!tc_cls_can_offload_and_chain0(port->dev, &f->common)) {
84 NL_SET_ERR_MSG_MOD(f->common.extack,
85 "Only chain zero is supported");
86 return -EOPNOTSUPP;
87 }
88
89 switch (f->command) {
90 case TC_CLSMATCHALL_REPLACE:
91 return lan966x_tc_matchall_add(port, f, ingress);
92 case TC_CLSMATCHALL_DESTROY:
93 return lan966x_tc_matchall_del(port, f, ingress);
94 case TC_CLSMATCHALL_STATS:
95 return lan966x_tc_matchall_stats(port, f, ingress);
96 default:
97 return -EOPNOTSUPP;
98 }
99
100 return 0;
101}