Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2024 Marvell.
3 : : */
4 : :
5 : : #include "cnxk_flow_common.h"
6 : : #include "cnxk_ethdev_mcs.h"
7 : : #include <cnxk_flow.h>
8 : :
9 : : static int
10 : : cnxk_mtr_connect(struct rte_eth_dev *eth_dev, uint32_t mtr_id)
11 : : {
12 : 0 : return nix_mtr_connect(eth_dev, mtr_id);
13 : : }
14 : :
15 : : int
16 : 0 : cnxk_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t mtr_id)
17 : : {
18 : : struct rte_mtr_error mtr_error;
19 : :
20 : 0 : return nix_mtr_destroy(eth_dev, mtr_id, &mtr_error);
21 : : }
22 : :
23 : : static int
24 : 0 : cnxk_mtr_configure(struct rte_eth_dev *eth_dev, const struct rte_flow_action actions[])
25 : : {
26 : 0 : uint32_t mtr_id = 0xffff, prev_mtr_id = 0xffff, next_mtr_id = 0xffff;
27 : : const struct rte_flow_action_meter *mtr_conf;
28 : : const struct rte_flow_action_queue *q_conf;
29 : : const struct rte_flow_action_rss *rss_conf;
30 : : struct cnxk_mtr_policy_node *policy;
31 : : bool is_mtr_act = false;
32 : 0 : int tree_level = 0;
33 : : int rc = -EINVAL, i;
34 : :
35 [ # # ]: 0 : for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {
36 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) {
37 : 0 : mtr_conf = (const struct rte_flow_action_meter *)(actions[i].conf);
38 : 0 : mtr_id = mtr_conf->mtr_id;
39 : : is_mtr_act = true;
40 : : }
41 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) {
42 : 0 : q_conf = (const struct rte_flow_action_queue *)(actions[i].conf);
43 [ # # ]: 0 : if (is_mtr_act)
44 : 0 : nix_mtr_rq_update(eth_dev, mtr_id, 1, &q_conf->index);
45 : : }
46 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) {
47 : 0 : rss_conf = (const struct rte_flow_action_rss *)(actions[i].conf);
48 [ # # ]: 0 : if (is_mtr_act)
49 : 0 : nix_mtr_rq_update(eth_dev, mtr_id, rss_conf->queue_num,
50 : 0 : rss_conf->queue);
51 : : }
52 : : }
53 : :
54 [ # # ]: 0 : if (!is_mtr_act)
55 : : return rc;
56 : :
57 : 0 : prev_mtr_id = mtr_id;
58 : 0 : next_mtr_id = mtr_id;
59 [ # # ]: 0 : while (next_mtr_id != 0xffff) {
60 : 0 : rc = nix_mtr_validate(eth_dev, next_mtr_id);
61 [ # # ]: 0 : if (rc)
62 : 0 : return rc;
63 : :
64 : 0 : rc = nix_mtr_policy_act_get(eth_dev, next_mtr_id, &policy);
65 [ # # ]: 0 : if (rc)
66 : 0 : return rc;
67 : :
68 : 0 : rc = nix_mtr_color_action_validate(eth_dev, mtr_id, &prev_mtr_id, &next_mtr_id,
69 : : policy, &tree_level);
70 [ # # ]: 0 : if (rc)
71 : 0 : return rc;
72 : : }
73 : :
74 : 0 : return nix_mtr_configure(eth_dev, mtr_id);
75 : : }
76 : :
77 : : static int
78 : 0 : cnxk_rss_action_validate(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
79 : : const struct rte_flow_action *act)
80 : : {
81 : : const struct rte_flow_action_rss *rss;
82 : :
83 [ # # ]: 0 : if (act == NULL)
84 : : return -EINVAL;
85 : :
86 : 0 : rss = (const struct rte_flow_action_rss *)act->conf;
87 : :
88 [ # # ]: 0 : if (attr->egress) {
89 : 0 : plt_err("No support of RSS in egress");
90 : 0 : return -EINVAL;
91 : : }
92 : :
93 [ # # ]: 0 : if (eth_dev->data->dev_conf.rxmode.mq_mode != RTE_ETH_MQ_RX_RSS) {
94 : 0 : plt_err("multi-queue mode is disabled");
95 : 0 : return -ENOTSUP;
96 : : }
97 : :
98 [ # # # # ]: 0 : if (!rss || !rss->queue_num) {
99 : 0 : plt_err("no valid queues");
100 : 0 : return -EINVAL;
101 : : }
102 : :
103 [ # # ]: 0 : if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
104 : 0 : plt_err("non-default RSS hash functions are not supported");
105 : 0 : return -ENOTSUP;
106 : : }
107 : :
108 [ # # ]: 0 : if (rss->key_len && rss->key_len > ROC_NIX_RSS_KEY_LEN) {
109 : 0 : plt_err("RSS hash key too large");
110 : 0 : return -ENOTSUP;
111 : : }
112 : :
113 : : return 0;
114 : : }
115 : :
116 : : struct roc_npc_flow *
117 : 0 : cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
118 : : const struct rte_flow_item pattern[], const struct rte_flow_action actions[],
119 : : struct rte_flow_error *error)
120 : : {
121 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
122 : : const struct rte_flow_action *action_rss = NULL;
123 : : const struct rte_flow_action_meter *mtr = NULL;
124 : : const struct rte_flow_action *act_q = NULL;
125 : : struct cnxk_eth_sec_sess *eth_sec = NULL;
126 : : struct roc_npc_flow *flow;
127 : : uint32_t flow_flags = 0;
128 : 0 : void *mcs_flow = NULL;
129 : : uint32_t req_act = 0;
130 : : int i, rc;
131 : :
132 [ # # ]: 0 : for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {
133 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER)
134 : 0 : req_act |= ROC_NPC_ACTION_TYPE_METER;
135 : :
136 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_QUEUE) {
137 : 0 : req_act |= ROC_NPC_ACTION_TYPE_QUEUE;
138 : : act_q = &actions[i];
139 : : }
140 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_RSS) {
141 : 0 : req_act |= ROC_NPC_ACTION_TYPE_RSS;
142 : : action_rss = &actions[i];
143 : : }
144 : : }
145 : :
146 [ # # ]: 0 : if (req_act & ROC_NPC_ACTION_TYPE_METER) {
147 [ # # ]: 0 : if ((req_act & ROC_NPC_ACTION_TYPE_RSS) &&
148 : : ((req_act & ROC_NPC_ACTION_TYPE_QUEUE))) {
149 : : return NULL;
150 : : }
151 [ # # ]: 0 : if (req_act & ROC_NPC_ACTION_TYPE_RSS) {
152 : 0 : rc = cnxk_rss_action_validate(eth_dev, attr, action_rss);
153 [ # # ]: 0 : if (rc)
154 : : return NULL;
155 [ # # ]: 0 : } else if (req_act & ROC_NPC_ACTION_TYPE_QUEUE) {
156 : : const struct rte_flow_action_queue *act_queue;
157 : 0 : act_queue = (const struct rte_flow_action_queue *)act_q->conf;
158 [ # # ]: 0 : if (act_queue->index > eth_dev->data->nb_rx_queues)
159 : : return NULL;
160 : : } else {
161 : : return NULL;
162 : : }
163 : : }
164 [ # # ]: 0 : for (i = 0; actions[i].type != RTE_FLOW_ACTION_TYPE_END; i++) {
165 [ # # ]: 0 : if (actions[i].type == RTE_FLOW_ACTION_TYPE_METER) {
166 : 0 : mtr = (const struct rte_flow_action_meter *)actions[i].conf;
167 : 0 : rc = cnxk_mtr_configure(eth_dev, actions);
168 [ # # ]: 0 : if (rc) {
169 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
170 : : "Failed to configure mtr ");
171 : 0 : return NULL;
172 : : }
173 : : break;
174 : : }
175 : : }
176 : :
177 [ # # # # ]: 0 : if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY &&
178 : 0 : cnxk_eth_macsec_sess_get_by_sess(dev, actions[0].conf) != NULL) {
179 : 0 : rc = cnxk_mcs_flow_configure(eth_dev, attr, pattern, actions, error, &mcs_flow);
180 [ # # ]: 0 : if (rc) {
181 : 0 : rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
182 : : "Failed to configure mcs flow");
183 : 0 : return NULL;
184 : : }
185 : 0 : return mcs_flow;
186 : : }
187 : :
188 [ # # ]: 0 : if (actions[0].type == RTE_FLOW_ACTION_TYPE_SECURITY) {
189 : 0 : eth_sec = cnxk_eth_sec_sess_get_by_sess(dev, actions[0].conf);
190 [ # # ]: 0 : if (eth_sec != NULL) {
191 [ # # ]: 0 : flow_flags = eth_sec->inb_oop ? CNXK_FLOW_NON_INPLACE : 0;
192 : 0 : flow_flags |= CNXK_FLOW_NO_SEC_ACTION;
193 : : }
194 : : }
195 : :
196 : 0 : flow = cnxk_flow_create_common(eth_dev, attr, pattern, actions, error, false, flow_flags);
197 [ # # ]: 0 : if (!flow) {
198 [ # # ]: 0 : if (mtr)
199 : 0 : nix_mtr_chain_reset(eth_dev, mtr->mtr_id);
200 : :
201 : : } else {
202 [ # # ]: 0 : if (mtr)
203 : 0 : cnxk_mtr_connect(eth_dev, mtr->mtr_id);
204 : : }
205 : :
206 : : return flow;
207 : : }
208 : :
209 : : int
210 : 0 : cnxk_flow_info_get_common(struct rte_eth_dev *dev, struct rte_flow_port_info *port_info,
211 : : struct rte_flow_queue_info *queue_info, struct rte_flow_error *err)
212 : : {
213 : : RTE_SET_USED(dev);
214 : : RTE_SET_USED(err);
215 : :
216 : : memset(port_info, 0, sizeof(*port_info));
217 : : memset(queue_info, 0, sizeof(*queue_info));
218 : :
219 : 0 : port_info->max_nb_counters = CNXK_NPC_COUNTERS_MAX;
220 : 0 : port_info->max_nb_meters = CNXK_NIX_MTR_COUNT_MAX;
221 : :
222 : 0 : return 0;
223 : : }
|