1 // SPDX-License-Identifier: GPL-2.0+ 2 3 #include "lan966x_main.h" 4 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 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 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 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