1 // SPDX-License-Identifier: GPL-2.0+ 2 /* Microchip VCAP API 3 * 4 * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries. 5 */ 6 7 #include "sparx5_tc.h" 8 #include "vcap_api.h" 9 #include "vcap_api_client.h" 10 #include "sparx5_main_regs.h" 11 #include "sparx5_main.h" 12 #include "sparx5_vcap_impl.h" 13 14 static int sparx5_tc_matchall_replace(struct net_device *ndev, 15 struct tc_cls_matchall_offload *tmo, 16 bool ingress) 17 { 18 struct sparx5_port *port = netdev_priv(ndev); 19 struct flow_action_entry *action; 20 struct sparx5 *sparx5; 21 int err; 22 23 if (!flow_offload_has_one_action(&tmo->rule->action)) { 24 NL_SET_ERR_MSG_MOD(tmo->common.extack, 25 "Only one action per filter is supported"); 26 return -EOPNOTSUPP; 27 } 28 action = &tmo->rule->action.entries[0]; 29 30 sparx5 = port->sparx5; 31 switch (action->id) { 32 case FLOW_ACTION_GOTO: 33 err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev, 34 action->chain_index, tmo->cookie, 35 true); 36 if (err == -EFAULT) { 37 NL_SET_ERR_MSG_MOD(tmo->common.extack, 38 "Unsupported goto chain"); 39 return -EOPNOTSUPP; 40 } 41 if (err == -EADDRINUSE) { 42 NL_SET_ERR_MSG_MOD(tmo->common.extack, 43 "VCAP already enabled"); 44 return -EOPNOTSUPP; 45 } 46 if (err) { 47 NL_SET_ERR_MSG_MOD(tmo->common.extack, 48 "Could not enable VCAP lookups"); 49 return err; 50 } 51 break; 52 default: 53 NL_SET_ERR_MSG_MOD(tmo->common.extack, "Unsupported action"); 54 return -EOPNOTSUPP; 55 } 56 return 0; 57 } 58 59 static int sparx5_tc_matchall_destroy(struct net_device *ndev, 60 struct tc_cls_matchall_offload *tmo, 61 bool ingress) 62 { 63 struct sparx5_port *port = netdev_priv(ndev); 64 struct sparx5 *sparx5; 65 int err; 66 67 sparx5 = port->sparx5; 68 if (!tmo->rule && tmo->cookie) { 69 err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev, 0, 70 tmo->cookie, false); 71 if (err) 72 return err; 73 return 0; 74 } 75 NL_SET_ERR_MSG_MOD(tmo->common.extack, "Unsupported action"); 76 return -EOPNOTSUPP; 77 } 78 79 int sparx5_tc_matchall(struct net_device *ndev, 80 struct tc_cls_matchall_offload *tmo, 81 bool ingress) 82 { 83 if (!tc_cls_can_offload_and_chain0(ndev, &tmo->common)) { 84 NL_SET_ERR_MSG_MOD(tmo->common.extack, 85 "Only chain zero is supported"); 86 return -EOPNOTSUPP; 87 } 88 89 switch (tmo->command) { 90 case TC_CLSMATCHALL_REPLACE: 91 return sparx5_tc_matchall_replace(ndev, tmo, ingress); 92 case TC_CLSMATCHALL_DESTROY: 93 return sparx5_tc_matchall_destroy(ndev, tmo, ingress); 94 default: 95 return -EOPNOTSUPP; 96 } 97 } 98