1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2021 Marvell.
6 const struct cnxk_rte_flow_term_info term[] = {
7 [RTE_FLOW_ITEM_TYPE_ETH] = {ROC_NPC_ITEM_TYPE_ETH,
8 sizeof(struct rte_flow_item_eth)},
9 [RTE_FLOW_ITEM_TYPE_VLAN] = {ROC_NPC_ITEM_TYPE_VLAN,
10 sizeof(struct rte_flow_item_vlan)},
11 [RTE_FLOW_ITEM_TYPE_E_TAG] = {ROC_NPC_ITEM_TYPE_E_TAG,
12 sizeof(struct rte_flow_item_e_tag)},
13 [RTE_FLOW_ITEM_TYPE_IPV4] = {ROC_NPC_ITEM_TYPE_IPV4,
14 sizeof(struct rte_flow_item_ipv4)},
15 [RTE_FLOW_ITEM_TYPE_IPV6] = {ROC_NPC_ITEM_TYPE_IPV6,
16 sizeof(struct rte_flow_item_ipv6)},
17 [RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT] = {
18 ROC_NPC_ITEM_TYPE_IPV6_FRAG_EXT,
19 sizeof(struct rte_flow_item_ipv6_frag_ext)},
20 [RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4] = {
21 ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4,
22 sizeof(struct rte_flow_item_arp_eth_ipv4)},
23 [RTE_FLOW_ITEM_TYPE_MPLS] = {ROC_NPC_ITEM_TYPE_MPLS,
24 sizeof(struct rte_flow_item_mpls)},
25 [RTE_FLOW_ITEM_TYPE_ICMP] = {ROC_NPC_ITEM_TYPE_ICMP,
26 sizeof(struct rte_flow_item_icmp)},
27 [RTE_FLOW_ITEM_TYPE_UDP] = {ROC_NPC_ITEM_TYPE_UDP,
28 sizeof(struct rte_flow_item_udp)},
29 [RTE_FLOW_ITEM_TYPE_TCP] = {ROC_NPC_ITEM_TYPE_TCP,
30 sizeof(struct rte_flow_item_tcp)},
31 [RTE_FLOW_ITEM_TYPE_SCTP] = {ROC_NPC_ITEM_TYPE_SCTP,
32 sizeof(struct rte_flow_item_sctp)},
33 [RTE_FLOW_ITEM_TYPE_ESP] = {ROC_NPC_ITEM_TYPE_ESP,
34 sizeof(struct rte_flow_item_esp)},
35 [RTE_FLOW_ITEM_TYPE_GRE] = {ROC_NPC_ITEM_TYPE_GRE,
36 sizeof(struct rte_flow_item_gre)},
37 [RTE_FLOW_ITEM_TYPE_NVGRE] = {ROC_NPC_ITEM_TYPE_NVGRE,
38 sizeof(struct rte_flow_item_nvgre)},
39 [RTE_FLOW_ITEM_TYPE_VXLAN] = {ROC_NPC_ITEM_TYPE_VXLAN,
40 sizeof(struct rte_flow_item_vxlan)},
41 [RTE_FLOW_ITEM_TYPE_GTPC] = {ROC_NPC_ITEM_TYPE_GTPC,
42 sizeof(struct rte_flow_item_gtp)},
43 [RTE_FLOW_ITEM_TYPE_GTPU] = {ROC_NPC_ITEM_TYPE_GTPU,
44 sizeof(struct rte_flow_item_gtp)},
45 [RTE_FLOW_ITEM_TYPE_GENEVE] = {ROC_NPC_ITEM_TYPE_GENEVE,
46 sizeof(struct rte_flow_item_geneve)},
47 [RTE_FLOW_ITEM_TYPE_VXLAN_GPE] = {
48 ROC_NPC_ITEM_TYPE_VXLAN_GPE,
49 sizeof(struct rte_flow_item_vxlan_gpe)},
50 [RTE_FLOW_ITEM_TYPE_IPV6_EXT] = {ROC_NPC_ITEM_TYPE_IPV6_EXT,
51 sizeof(struct rte_flow_item_ipv6_ext)},
52 [RTE_FLOW_ITEM_TYPE_VOID] = {ROC_NPC_ITEM_TYPE_VOID, 0},
53 [RTE_FLOW_ITEM_TYPE_ANY] = {ROC_NPC_ITEM_TYPE_ANY, 0},
54 [RTE_FLOW_ITEM_TYPE_GRE_KEY] = {ROC_NPC_ITEM_TYPE_GRE_KEY,
56 [RTE_FLOW_ITEM_TYPE_HIGIG2] = {ROC_NPC_ITEM_TYPE_HIGIG2,
57 sizeof(struct rte_flow_item_higig2_hdr)},
58 [RTE_FLOW_ITEM_TYPE_RAW] = {ROC_NPC_ITEM_TYPE_RAW,
59 sizeof(struct rte_flow_item_raw)},
60 [RTE_FLOW_ITEM_TYPE_MARK] = {ROC_NPC_ITEM_TYPE_MARK,
61 sizeof(struct rte_flow_item_mark)}};
64 npc_rss_action_validate(struct rte_eth_dev *eth_dev,
65 const struct rte_flow_attr *attr,
66 const struct rte_flow_action *act)
68 const struct rte_flow_action_rss *rss;
70 rss = (const struct rte_flow_action_rss *)act->conf;
73 plt_err("No support of RSS in egress");
77 if (eth_dev->data->dev_conf.rxmode.mq_mode != RTE_ETH_MQ_RX_RSS) {
78 plt_err("multi-queue mode is disabled");
82 if (!rss || !rss->queue_num) {
83 plt_err("no valid queues");
87 if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) {
88 plt_err("non-default RSS hash functions are not supported");
92 if (rss->key_len && rss->key_len > ROC_NIX_RSS_KEY_LEN) {
93 plt_err("RSS hash key too large");
101 npc_rss_flowkey_get(struct cnxk_eth_dev *eth_dev,
102 const struct roc_npc_action *rss_action,
103 uint32_t *flowkey_cfg)
105 const struct roc_npc_action_rss *rss;
107 rss = (const struct roc_npc_action_rss *)rss_action->conf;
109 *flowkey_cfg = cnxk_rss_ethdev_to_nix(eth_dev, rss->types, rss->level);
113 cnxk_map_actions(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
114 const struct rte_flow_action actions[],
115 struct roc_npc_action in_actions[], uint32_t *flowkey_cfg)
117 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
118 const struct rte_flow_action_port_id *port_act;
119 const struct rte_flow_action_queue *act_q;
120 struct roc_npc *roc_npc_src = &dev->npc;
121 struct rte_eth_dev *portid_eth_dev;
122 char if_name[RTE_ETH_NAME_MAX_LEN];
123 struct cnxk_eth_dev *hw_dst;
124 struct roc_npc *roc_npc_dst;
128 for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
129 switch (actions->type) {
130 case RTE_FLOW_ACTION_TYPE_VOID:
131 in_actions[i].type = ROC_NPC_ACTION_TYPE_VOID;
134 case RTE_FLOW_ACTION_TYPE_MARK:
135 in_actions[i].type = ROC_NPC_ACTION_TYPE_MARK;
136 in_actions[i].conf = actions->conf;
139 case RTE_FLOW_ACTION_TYPE_FLAG:
140 in_actions[i].type = ROC_NPC_ACTION_TYPE_FLAG;
143 case RTE_FLOW_ACTION_TYPE_COUNT:
144 in_actions[i].type = ROC_NPC_ACTION_TYPE_COUNT;
147 case RTE_FLOW_ACTION_TYPE_DROP:
148 in_actions[i].type = ROC_NPC_ACTION_TYPE_DROP;
151 case RTE_FLOW_ACTION_TYPE_PF:
152 in_actions[i].type = ROC_NPC_ACTION_TYPE_PF;
155 case RTE_FLOW_ACTION_TYPE_VF:
156 in_actions[i].type = ROC_NPC_ACTION_TYPE_VF;
157 in_actions[i].conf = actions->conf;
160 case RTE_FLOW_ACTION_TYPE_PORT_ID:
161 in_actions[i].type = ROC_NPC_ACTION_TYPE_PORT_ID;
162 in_actions[i].conf = actions->conf;
163 port_act = (const struct rte_flow_action_port_id *)
165 if (rte_eth_dev_get_name_by_port(port_act->id,
167 plt_err("Name not found for output port id");
170 portid_eth_dev = rte_eth_dev_allocated(if_name);
171 if (!portid_eth_dev) {
172 plt_err("eth_dev not found for output port id");
175 if (strcmp(portid_eth_dev->device->driver->name,
176 eth_dev->device->driver->name) != 0) {
177 plt_err("Output port not under same driver");
180 hw_dst = portid_eth_dev->data->dev_private;
181 roc_npc_dst = &hw_dst->npc;
183 rc = roc_npc_validate_portid_action(roc_npc_src,
190 case RTE_FLOW_ACTION_TYPE_QUEUE:
191 act_q = (const struct rte_flow_action_queue *)
194 if (rq >= eth_dev->data->nb_rx_queues) {
195 plt_npc_dbg("Invalid queue index");
198 in_actions[i].type = ROC_NPC_ACTION_TYPE_QUEUE;
199 in_actions[i].conf = actions->conf;
202 case RTE_FLOW_ACTION_TYPE_RSS:
203 rc = npc_rss_action_validate(eth_dev, attr, actions);
206 in_actions[i].type = ROC_NPC_ACTION_TYPE_RSS;
207 in_actions[i].conf = actions->conf;
208 npc_rss_flowkey_get(dev, &in_actions[i], flowkey_cfg);
211 case RTE_FLOW_ACTION_TYPE_SECURITY:
212 in_actions[i].type = ROC_NPC_ACTION_TYPE_SEC;
213 in_actions[i].conf = actions->conf;
215 case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
216 in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_STRIP;
218 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
219 in_actions[i].type = ROC_NPC_ACTION_TYPE_VLAN_INSERT;
220 in_actions[i].conf = actions->conf;
222 case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
224 ROC_NPC_ACTION_TYPE_VLAN_ETHTYPE_INSERT;
225 in_actions[i].conf = actions->conf;
227 case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
229 ROC_NPC_ACTION_TYPE_VLAN_PCP_INSERT;
230 in_actions[i].conf = actions->conf;
232 case RTE_FLOW_ACTION_TYPE_METER:
233 in_actions[i].type = ROC_NPC_ACTION_TYPE_METER;
234 in_actions[i].conf = actions->conf;
237 plt_npc_dbg("Action is not supported = %d",
243 in_actions[i].type = ROC_NPC_ACTION_TYPE_END;
251 cnxk_map_flow_data(struct rte_eth_dev *eth_dev,
252 const struct rte_flow_attr *attr,
253 const struct rte_flow_item pattern[],
254 const struct rte_flow_action actions[],
255 struct roc_npc_attr *in_attr,
256 struct roc_npc_item_info in_pattern[],
257 struct roc_npc_action in_actions[], uint32_t *flowkey_cfg)
261 in_attr->priority = attr->priority;
262 in_attr->ingress = attr->ingress;
263 in_attr->egress = attr->egress;
265 while (pattern->type != RTE_FLOW_ITEM_TYPE_END) {
266 in_pattern[i].spec = pattern->spec;
267 in_pattern[i].last = pattern->last;
268 in_pattern[i].mask = pattern->mask;
269 in_pattern[i].type = term[pattern->type].item_type;
270 in_pattern[i].size = term[pattern->type].item_size;
274 in_pattern[i].type = ROC_NPC_ITEM_TYPE_END;
276 return cnxk_map_actions(eth_dev, attr, actions, in_actions,
281 cnxk_flow_validate(struct rte_eth_dev *eth_dev,
282 const struct rte_flow_attr *attr,
283 const struct rte_flow_item pattern[],
284 const struct rte_flow_action actions[],
285 struct rte_flow_error *error)
287 struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
288 struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
289 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
290 struct roc_npc *npc = &dev->npc;
291 struct roc_npc_attr in_attr;
292 struct roc_npc_flow flow;
293 uint32_t flowkey_cfg = 0;
296 memset(&flow, 0, sizeof(flow));
298 rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,
299 in_pattern, in_actions, &flowkey_cfg);
301 rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
302 NULL, "Failed to map flow data");
306 rc = roc_npc_flow_parse(npc, &in_attr, in_pattern, in_actions, &flow);
309 rte_flow_error_set(error, 0, rc, NULL,
310 "Flow validation failed");
316 struct roc_npc_flow *
317 cnxk_flow_create(struct rte_eth_dev *eth_dev, const struct rte_flow_attr *attr,
318 const struct rte_flow_item pattern[],
319 const struct rte_flow_action actions[],
320 struct rte_flow_error *error)
322 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
323 struct roc_npc_item_info in_pattern[ROC_NPC_ITEM_TYPE_END + 1];
324 struct roc_npc_action in_actions[ROC_NPC_MAX_ACTION_COUNT];
325 struct roc_npc *npc = &dev->npc;
326 struct roc_npc_attr in_attr;
327 struct roc_npc_flow *flow;
331 rc = cnxk_map_flow_data(eth_dev, attr, pattern, actions, &in_attr,
332 in_pattern, in_actions,
333 &npc->flowkey_cfg_state);
335 rte_flow_error_set(error, 0, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
336 NULL, "Failed to map flow data");
340 flow = roc_npc_flow_create(npc, &in_attr, in_pattern, in_actions,
343 rte_flow_error_set(error, errcode, errcode, NULL,
344 roc_error_msg_get(errcode));
352 cnxk_flow_destroy(struct rte_eth_dev *eth_dev, struct roc_npc_flow *flow,
353 struct rte_flow_error *error)
355 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
356 struct roc_npc *npc = &dev->npc;
359 rc = roc_npc_flow_destroy(npc, flow);
361 rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
362 NULL, "Flow Destroy failed");
367 cnxk_flow_flush(struct rte_eth_dev *eth_dev, struct rte_flow_error *error)
369 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
370 struct roc_npc *npc = &dev->npc;
373 rc = roc_npc_mcam_free_all_resources(npc);
375 rte_flow_error_set(error, EIO, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
376 NULL, "Failed to flush filter");
384 cnxk_flow_query(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
385 const struct rte_flow_action *action, void *data,
386 struct rte_flow_error *error)
388 struct roc_npc_flow *in_flow = (struct roc_npc_flow *)flow;
389 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
390 struct roc_npc *npc = &dev->npc;
391 struct rte_flow_query_count *query = data;
392 const char *errmsg = NULL;
393 int errcode = ENOTSUP;
396 if (action->type != RTE_FLOW_ACTION_TYPE_COUNT) {
397 errmsg = "Only COUNT is supported in query";
401 if (in_flow->ctr_id == NPC_COUNTER_NONE) {
402 errmsg = "Counter is not available";
406 rc = roc_npc_mcam_read_counter(npc, in_flow->ctr_id, &query->hits);
409 errmsg = "Error reading flow counter";
413 query->bytes_set = 0;
416 rc = roc_npc_mcam_clear_counter(npc, in_flow->ctr_id);
419 errmsg = "Error clearing flow counter";
426 rte_flow_error_set(error, errcode, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
432 cnxk_flow_isolate(struct rte_eth_dev *eth_dev __rte_unused,
433 int enable __rte_unused, struct rte_flow_error *error)
435 /* If we support, we need to un-install the default mcam
436 * entry for this port.
439 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
440 NULL, "Flow isolation not supported");
446 cnxk_flow_dev_dump(struct rte_eth_dev *eth_dev, struct rte_flow *flow,
447 FILE *file, struct rte_flow_error *error)
449 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
450 struct roc_npc *npc = &dev->npc;
453 rte_flow_error_set(error, EINVAL,
454 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
460 rte_flow_error_set(error, EINVAL,
461 RTE_FLOW_ERROR_TYPE_HANDLE,
467 roc_npc_flow_dump(file, npc);
472 struct rte_flow_ops cnxk_flow_ops = {
473 .validate = cnxk_flow_validate,
474 .flush = cnxk_flow_flush,
475 .query = cnxk_flow_query,
476 .isolate = cnxk_flow_isolate,
477 .dev_dump = cnxk_flow_dev_dump,