Loading...
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
14static 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
65static 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
85int 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}
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
14static 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
59static 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
79int 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}