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 tmo->common.chain_index, 35 action->chain_index, tmo->cookie, 36 true); 37 if (err == -EFAULT) { 38 NL_SET_ERR_MSG_MOD(tmo->common.extack, 39 "Unsupported goto chain"); 40 return -EOPNOTSUPP; 41 } 42 if (err == -EADDRINUSE) { 43 NL_SET_ERR_MSG_MOD(tmo->common.extack, 44 "VCAP already enabled"); 45 return -EOPNOTSUPP; 46 } 47 if (err == -EADDRNOTAVAIL) { 48 NL_SET_ERR_MSG_MOD(tmo->common.extack, 49 "Already matching this chain"); 50 return -EOPNOTSUPP; 51 } 52 if (err) { 53 NL_SET_ERR_MSG_MOD(tmo->common.extack, 54 "Could not enable VCAP lookups"); 55 return err; 56 } 57 break; 58 default: 59 NL_SET_ERR_MSG_MOD(tmo->common.extack, "Unsupported action"); 60 return -EOPNOTSUPP; 61 } 62 return 0; 63 } 64 65 static int sparx5_tc_matchall_destroy(struct net_device *ndev, 66 struct tc_cls_matchall_offload *tmo, 67 bool ingress) 68 { 69 struct sparx5_port *port = netdev_priv(ndev); 70 struct sparx5 *sparx5; 71 int err; 72 73 sparx5 = port->sparx5; 74 if (!tmo->rule && tmo->cookie) { 75 err = vcap_enable_lookups(sparx5->vcap_ctrl, ndev, 76 0, 0, tmo->cookie, false); 77 if (err) 78 return err; 79 return 0; 80 } 81 NL_SET_ERR_MSG_MOD(tmo->common.extack, "Unsupported action"); 82 return -EOPNOTSUPP; 83 } 84 85 int sparx5_tc_matchall(struct net_device *ndev, 86 struct tc_cls_matchall_offload *tmo, 87 bool ingress) 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