xref: /dpdk/drivers/net/bnxt/bnxt_flow.c (revision d6f923ba)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2018 Broadcom
3  * All rights reserved.
4  */
5 
6 #include <sys/queue.h>
7 
8 #include <rte_log.h>
9 #include <rte_malloc.h>
10 #include <rte_flow.h>
11 #include <rte_flow_driver.h>
12 #include <rte_tailq.h>
13 
14 #include "bnxt.h"
15 #include "bnxt_filter.h"
16 #include "bnxt_hwrm.h"
17 #include "bnxt_ring.h"
18 #include "bnxt_rxq.h"
19 #include "bnxt_vnic.h"
20 #include "hsi_struct_def_dpdk.h"
21 
22 static int
23 bnxt_flow_args_validate(const struct rte_flow_attr *attr,
24 			const struct rte_flow_item pattern[],
25 			const struct rte_flow_action actions[],
26 			struct rte_flow_error *error)
27 {
28 	if (!pattern) {
29 		rte_flow_error_set(error,
30 				   EINVAL,
31 				   RTE_FLOW_ERROR_TYPE_ITEM_NUM,
32 				   NULL,
33 				   "NULL pattern.");
34 		return -rte_errno;
35 	}
36 
37 	if (!actions) {
38 		rte_flow_error_set(error,
39 				   EINVAL,
40 				   RTE_FLOW_ERROR_TYPE_ACTION_NUM,
41 				   NULL,
42 				   "NULL action.");
43 		return -rte_errno;
44 	}
45 
46 	if (!attr) {
47 		rte_flow_error_set(error,
48 				   EINVAL,
49 				   RTE_FLOW_ERROR_TYPE_ATTR,
50 				   NULL,
51 				   "NULL attribute.");
52 		return -rte_errno;
53 	}
54 
55 	return 0;
56 }
57 
58 static const struct rte_flow_item *
59 bnxt_flow_non_void_item(const struct rte_flow_item *cur)
60 {
61 	while (1) {
62 		if (cur->type != RTE_FLOW_ITEM_TYPE_VOID)
63 			return cur;
64 		cur++;
65 	}
66 }
67 
68 static const struct rte_flow_action *
69 bnxt_flow_non_void_action(const struct rte_flow_action *cur)
70 {
71 	while (1) {
72 		if (cur->type != RTE_FLOW_ACTION_TYPE_VOID)
73 			return cur;
74 		cur++;
75 	}
76 }
77 
78 static int
79 bnxt_filter_type_check(const struct rte_flow_item pattern[],
80 		       struct rte_flow_error *error)
81 {
82 	const struct rte_flow_item *item =
83 		bnxt_flow_non_void_item(pattern);
84 	int use_ntuple = 1;
85 	bool has_vlan = 0;
86 
87 	while (item->type != RTE_FLOW_ITEM_TYPE_END) {
88 		switch (item->type) {
89 		case RTE_FLOW_ITEM_TYPE_ANY:
90 		case RTE_FLOW_ITEM_TYPE_ETH:
91 			use_ntuple = 0;
92 			break;
93 		case RTE_FLOW_ITEM_TYPE_VLAN:
94 			use_ntuple = 0;
95 			has_vlan = 1;
96 			break;
97 		case RTE_FLOW_ITEM_TYPE_IPV4:
98 		case RTE_FLOW_ITEM_TYPE_IPV6:
99 		case RTE_FLOW_ITEM_TYPE_TCP:
100 		case RTE_FLOW_ITEM_TYPE_UDP:
101 			/* FALLTHROUGH */
102 			/* need ntuple match, reset exact match */
103 			use_ntuple |= 1;
104 			break;
105 		default:
106 			PMD_DRV_LOG(DEBUG, "Unknown Flow type\n");
107 			use_ntuple |= 0;
108 		}
109 		item++;
110 	}
111 
112 	if (has_vlan && use_ntuple) {
113 		PMD_DRV_LOG(ERR,
114 			    "VLAN flow cannot use NTUPLE filter\n");
115 		rte_flow_error_set(error, EINVAL,
116 				   RTE_FLOW_ERROR_TYPE_ITEM,
117 				   item,
118 				   "Cannot use VLAN with NTUPLE");
119 		return -rte_errno;
120 	}
121 
122 	return use_ntuple;
123 }
124 
125 static int
126 bnxt_validate_and_parse_flow_type(struct bnxt *bp,
127 				  const struct rte_flow_attr *attr,
128 				  const struct rte_flow_item pattern[],
129 				  struct rte_flow_error *error,
130 				  struct bnxt_filter_info *filter)
131 {
132 	const struct rte_flow_item *item = bnxt_flow_non_void_item(pattern);
133 	const struct rte_flow_item_vlan *vlan_spec, *vlan_mask;
134 	const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_mask;
135 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
136 	const struct rte_flow_item_tcp *tcp_spec, *tcp_mask;
137 	const struct rte_flow_item_udp *udp_spec, *udp_mask;
138 	const struct rte_flow_item_eth *eth_spec, *eth_mask;
139 	const struct rte_ether_addr *dst, *src;
140 	const struct rte_flow_item_nvgre *nvgre_spec;
141 	const struct rte_flow_item_nvgre *nvgre_mask;
142 	const struct rte_flow_item_gre *gre_spec;
143 	const struct rte_flow_item_gre *gre_mask;
144 	const struct rte_flow_item_vxlan *vxlan_spec;
145 	const struct rte_flow_item_vxlan *vxlan_mask;
146 	uint8_t vni_mask[] = {0xFF, 0xFF, 0xFF};
147 	uint8_t tni_mask[] = {0xFF, 0xFF, 0xFF};
148 	const struct rte_flow_item_vf *vf_spec;
149 	uint32_t tenant_id_be = 0, valid_flags = 0;
150 	bool vni_masked = 0;
151 	bool tni_masked = 0;
152 	uint32_t en_ethertype;
153 	uint8_t inner = 0;
154 	uint32_t vf = 0;
155 	uint32_t en = 0;
156 	int use_ntuple;
157 	int dflt_vnic;
158 
159 	use_ntuple = bnxt_filter_type_check(pattern, error);
160 	if (use_ntuple < 0)
161 		return use_ntuple;
162 	PMD_DRV_LOG(DEBUG, "Use NTUPLE %d\n", use_ntuple);
163 
164 	filter->filter_type = use_ntuple ?
165 		HWRM_CFA_NTUPLE_FILTER : HWRM_CFA_L2_FILTER;
166 	en_ethertype = use_ntuple ?
167 		NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE :
168 		EM_FLOW_ALLOC_INPUT_EN_ETHERTYPE;
169 
170 	while (item->type != RTE_FLOW_ITEM_TYPE_END) {
171 		if (item->last) {
172 			/* last or range is NOT supported as match criteria */
173 			rte_flow_error_set(error, EINVAL,
174 					   RTE_FLOW_ERROR_TYPE_ITEM,
175 					   item,
176 					   "No support for range");
177 			return -rte_errno;
178 		}
179 
180 		switch (item->type) {
181 		case RTE_FLOW_ITEM_TYPE_ANY:
182 			inner =
183 			((const struct rte_flow_item_any *)item->spec)->num > 3;
184 			if (inner)
185 				PMD_DRV_LOG(DEBUG, "Parse inner header\n");
186 			break;
187 		case RTE_FLOW_ITEM_TYPE_ETH:
188 			if (!item->spec || !item->mask)
189 				break;
190 
191 			eth_spec = item->spec;
192 			eth_mask = item->mask;
193 
194 			/* Source MAC address mask cannot be partially set.
195 			 * Should be All 0's or all 1's.
196 			 * Destination MAC address mask must not be partially
197 			 * set. Should be all 1's or all 0's.
198 			 */
199 			if ((!rte_is_zero_ether_addr(&eth_mask->src) &&
200 			     !rte_is_broadcast_ether_addr(&eth_mask->src)) ||
201 			    (!rte_is_zero_ether_addr(&eth_mask->dst) &&
202 			     !rte_is_broadcast_ether_addr(&eth_mask->dst))) {
203 				rte_flow_error_set(error,
204 						   EINVAL,
205 						   RTE_FLOW_ERROR_TYPE_ITEM,
206 						   item,
207 						   "MAC_addr mask not valid");
208 				return -rte_errno;
209 			}
210 
211 			/* Mask is not allowed. Only exact matches are */
212 			if (eth_mask->type &&
213 			    eth_mask->type != RTE_BE16(0xffff)) {
214 				rte_flow_error_set(error, EINVAL,
215 						   RTE_FLOW_ERROR_TYPE_ITEM,
216 						   item,
217 						   "ethertype mask not valid");
218 				return -rte_errno;
219 			}
220 
221 			if (rte_is_broadcast_ether_addr(&eth_mask->dst)) {
222 				dst = &eth_spec->dst;
223 				if (!rte_is_valid_assigned_ether_addr(dst)) {
224 					rte_flow_error_set(error,
225 							   EINVAL,
226 							   RTE_FLOW_ERROR_TYPE_ITEM,
227 							   item,
228 							   "DMAC is invalid");
229 					PMD_DRV_LOG(ERR,
230 						    "DMAC is invalid!\n");
231 					return -rte_errno;
232 				}
233 				rte_memcpy(filter->dst_macaddr,
234 					   &eth_spec->dst, RTE_ETHER_ADDR_LEN);
235 				en |= use_ntuple ?
236 					NTUPLE_FLTR_ALLOC_INPUT_EN_DST_MACADDR :
237 					EM_FLOW_ALLOC_INPUT_EN_DST_MACADDR;
238 				valid_flags |= inner ?
239 					BNXT_FLOW_L2_INNER_DST_VALID_FLAG :
240 					BNXT_FLOW_L2_DST_VALID_FLAG;
241 				filter->priority = attr->priority;
242 				PMD_DRV_LOG(DEBUG,
243 					    "Creating a priority flow\n");
244 			}
245 			if (rte_is_broadcast_ether_addr(&eth_mask->src)) {
246 				src = &eth_spec->src;
247 				if (!rte_is_valid_assigned_ether_addr(src)) {
248 					rte_flow_error_set(error,
249 							   EINVAL,
250 							   RTE_FLOW_ERROR_TYPE_ITEM,
251 							   item,
252 							   "SMAC is invalid");
253 					PMD_DRV_LOG(ERR,
254 						    "SMAC is invalid!\n");
255 					return -rte_errno;
256 				}
257 				rte_memcpy(filter->src_macaddr,
258 					   &eth_spec->src, RTE_ETHER_ADDR_LEN);
259 				en |= use_ntuple ?
260 					NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_MACADDR :
261 					EM_FLOW_ALLOC_INPUT_EN_SRC_MACADDR;
262 				valid_flags |= inner ?
263 					BNXT_FLOW_L2_INNER_SRC_VALID_FLAG :
264 					BNXT_FLOW_L2_SRC_VALID_FLAG;
265 			} /*
266 			   * else {
267 			   *  PMD_DRV_LOG(ERR, "Handle this condition\n");
268 			   * }
269 			   */
270 			if (eth_mask->type) {
271 				filter->ethertype =
272 					rte_be_to_cpu_16(eth_spec->type);
273 				en |= en_ethertype;
274 			}
275 			if (inner)
276 				valid_flags |= BNXT_FLOW_PARSE_INNER_FLAG;
277 
278 			break;
279 		case RTE_FLOW_ITEM_TYPE_VLAN:
280 			vlan_spec = item->spec;
281 			vlan_mask = item->mask;
282 			if (en & en_ethertype) {
283 				rte_flow_error_set(error, EINVAL,
284 						   RTE_FLOW_ERROR_TYPE_ITEM,
285 						   item,
286 						   "VLAN TPID matching is not"
287 						   " supported");
288 				return -rte_errno;
289 			}
290 			if (vlan_mask->tci &&
291 			    vlan_mask->tci == RTE_BE16(0x0fff)) {
292 				/* Only the VLAN ID can be matched. */
293 				filter->l2_ovlan =
294 					rte_be_to_cpu_16(vlan_spec->tci &
295 							 RTE_BE16(0x0fff));
296 				en |= EM_FLOW_ALLOC_INPUT_EN_OVLAN_VID;
297 			} else {
298 				rte_flow_error_set(error,
299 						   EINVAL,
300 						   RTE_FLOW_ERROR_TYPE_ITEM,
301 						   item,
302 						   "VLAN mask is invalid");
303 				return -rte_errno;
304 			}
305 			if (vlan_mask->inner_type &&
306 			    vlan_mask->inner_type != RTE_BE16(0xffff)) {
307 				rte_flow_error_set(error, EINVAL,
308 						   RTE_FLOW_ERROR_TYPE_ITEM,
309 						   item,
310 						   "inner ethertype mask not"
311 						   " valid");
312 				return -rte_errno;
313 			}
314 			if (vlan_mask->inner_type) {
315 				filter->ethertype =
316 					rte_be_to_cpu_16(vlan_spec->inner_type);
317 				en |= en_ethertype;
318 			}
319 
320 			break;
321 		case RTE_FLOW_ITEM_TYPE_IPV4:
322 			/* If mask is not involved, we could use EM filters. */
323 			ipv4_spec = item->spec;
324 			ipv4_mask = item->mask;
325 
326 			if (!item->spec || !item->mask)
327 				break;
328 
329 			/* Only IP DST and SRC fields are maskable. */
330 			if (ipv4_mask->hdr.version_ihl ||
331 			    ipv4_mask->hdr.type_of_service ||
332 			    ipv4_mask->hdr.total_length ||
333 			    ipv4_mask->hdr.packet_id ||
334 			    ipv4_mask->hdr.fragment_offset ||
335 			    ipv4_mask->hdr.time_to_live ||
336 			    ipv4_mask->hdr.next_proto_id ||
337 			    ipv4_mask->hdr.hdr_checksum) {
338 				rte_flow_error_set(error,
339 						   EINVAL,
340 						   RTE_FLOW_ERROR_TYPE_ITEM,
341 						   item,
342 						   "Invalid IPv4 mask.");
343 				return -rte_errno;
344 			}
345 
346 			filter->dst_ipaddr[0] = ipv4_spec->hdr.dst_addr;
347 			filter->src_ipaddr[0] = ipv4_spec->hdr.src_addr;
348 
349 			if (use_ntuple)
350 				en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR |
351 					NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
352 			else
353 				en |= EM_FLOW_ALLOC_INPUT_EN_SRC_IPADDR |
354 					EM_FLOW_ALLOC_INPUT_EN_DST_IPADDR;
355 
356 			if (ipv4_mask->hdr.src_addr) {
357 				filter->src_ipaddr_mask[0] =
358 					ipv4_mask->hdr.src_addr;
359 				en |= !use_ntuple ? 0 :
360 				     NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
361 			}
362 
363 			if (ipv4_mask->hdr.dst_addr) {
364 				filter->dst_ipaddr_mask[0] =
365 					ipv4_mask->hdr.dst_addr;
366 				en |= !use_ntuple ? 0 :
367 				     NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
368 			}
369 
370 			filter->ip_addr_type = use_ntuple ?
371 			 HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_IP_ADDR_TYPE_IPV4 :
372 			 HWRM_CFA_EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV4;
373 
374 			if (ipv4_spec->hdr.next_proto_id) {
375 				filter->ip_protocol =
376 					ipv4_spec->hdr.next_proto_id;
377 				if (use_ntuple)
378 					en |= NTUPLE_FLTR_ALLOC_IN_EN_IP_PROTO;
379 				else
380 					en |= EM_FLOW_ALLOC_INPUT_EN_IP_PROTO;
381 			}
382 			break;
383 		case RTE_FLOW_ITEM_TYPE_IPV6:
384 			ipv6_spec = item->spec;
385 			ipv6_mask = item->mask;
386 
387 			if (!item->spec || !item->mask)
388 				break;
389 
390 			/* Only IP DST and SRC fields are maskable. */
391 			if (ipv6_mask->hdr.vtc_flow ||
392 			    ipv6_mask->hdr.payload_len ||
393 			    ipv6_mask->hdr.proto ||
394 			    ipv6_mask->hdr.hop_limits) {
395 				rte_flow_error_set(error,
396 						   EINVAL,
397 						   RTE_FLOW_ERROR_TYPE_ITEM,
398 						   item,
399 						   "Invalid IPv6 mask.");
400 				return -rte_errno;
401 			}
402 
403 			if (use_ntuple)
404 				en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR |
405 					NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR;
406 			else
407 				en |= EM_FLOW_ALLOC_INPUT_EN_SRC_IPADDR |
408 					EM_FLOW_ALLOC_INPUT_EN_DST_IPADDR;
409 
410 			rte_memcpy(filter->src_ipaddr,
411 				   ipv6_spec->hdr.src_addr, 16);
412 			rte_memcpy(filter->dst_ipaddr,
413 				   ipv6_spec->hdr.dst_addr, 16);
414 
415 			if (!bnxt_check_zero_bytes(ipv6_mask->hdr.src_addr,
416 						   16)) {
417 				rte_memcpy(filter->src_ipaddr_mask,
418 					   ipv6_mask->hdr.src_addr, 16);
419 				en |= !use_ntuple ? 0 :
420 				    NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_IPADDR_MASK;
421 			}
422 
423 			if (!bnxt_check_zero_bytes(ipv6_mask->hdr.dst_addr,
424 						   16)) {
425 				rte_memcpy(filter->dst_ipaddr_mask,
426 					   ipv6_mask->hdr.dst_addr, 16);
427 				en |= !use_ntuple ? 0 :
428 				     NTUPLE_FLTR_ALLOC_INPUT_EN_DST_IPADDR_MASK;
429 			}
430 
431 			filter->ip_addr_type = use_ntuple ?
432 				NTUPLE_FLTR_ALLOC_INPUT_IP_ADDR_TYPE_IPV6 :
433 				EM_FLOW_ALLOC_INPUT_IP_ADDR_TYPE_IPV6;
434 			break;
435 		case RTE_FLOW_ITEM_TYPE_TCP:
436 			tcp_spec = item->spec;
437 			tcp_mask = item->mask;
438 
439 			if (!item->spec || !item->mask)
440 				break;
441 
442 			/* Check TCP mask. Only DST & SRC ports are maskable */
443 			if (tcp_mask->hdr.sent_seq ||
444 			    tcp_mask->hdr.recv_ack ||
445 			    tcp_mask->hdr.data_off ||
446 			    tcp_mask->hdr.tcp_flags ||
447 			    tcp_mask->hdr.rx_win ||
448 			    tcp_mask->hdr.cksum ||
449 			    tcp_mask->hdr.tcp_urp) {
450 				rte_flow_error_set(error,
451 						   EINVAL,
452 						   RTE_FLOW_ERROR_TYPE_ITEM,
453 						   item,
454 						   "Invalid TCP mask");
455 				return -rte_errno;
456 			}
457 
458 			filter->src_port = tcp_spec->hdr.src_port;
459 			filter->dst_port = tcp_spec->hdr.dst_port;
460 
461 			if (use_ntuple)
462 				en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT |
463 					NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
464 			else
465 				en |= EM_FLOW_ALLOC_INPUT_EN_SRC_PORT |
466 					EM_FLOW_ALLOC_INPUT_EN_DST_PORT;
467 
468 			if (tcp_mask->hdr.dst_port) {
469 				filter->dst_port_mask = tcp_mask->hdr.dst_port;
470 				en |= !use_ntuple ? 0 :
471 				  NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
472 			}
473 
474 			if (tcp_mask->hdr.src_port) {
475 				filter->src_port_mask = tcp_mask->hdr.src_port;
476 				en |= !use_ntuple ? 0 :
477 				  NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
478 			}
479 			break;
480 		case RTE_FLOW_ITEM_TYPE_UDP:
481 			udp_spec = item->spec;
482 			udp_mask = item->mask;
483 
484 			if (!item->spec || !item->mask)
485 				break;
486 
487 			if (udp_mask->hdr.dgram_len ||
488 			    udp_mask->hdr.dgram_cksum) {
489 				rte_flow_error_set(error,
490 						   EINVAL,
491 						   RTE_FLOW_ERROR_TYPE_ITEM,
492 						   item,
493 						   "Invalid UDP mask");
494 				return -rte_errno;
495 			}
496 
497 			filter->src_port = udp_spec->hdr.src_port;
498 			filter->dst_port = udp_spec->hdr.dst_port;
499 
500 			if (use_ntuple)
501 				en |= NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT |
502 					NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT;
503 			else
504 				en |= EM_FLOW_ALLOC_INPUT_EN_SRC_PORT |
505 					EM_FLOW_ALLOC_INPUT_EN_DST_PORT;
506 
507 			if (udp_mask->hdr.dst_port) {
508 				filter->dst_port_mask = udp_mask->hdr.dst_port;
509 				en |= !use_ntuple ? 0 :
510 				  NTUPLE_FLTR_ALLOC_INPUT_EN_DST_PORT_MASK;
511 			}
512 
513 			if (udp_mask->hdr.src_port) {
514 				filter->src_port_mask = udp_mask->hdr.src_port;
515 				en |= !use_ntuple ? 0 :
516 				  NTUPLE_FLTR_ALLOC_INPUT_EN_SRC_PORT_MASK;
517 			}
518 			break;
519 		case RTE_FLOW_ITEM_TYPE_VXLAN:
520 			vxlan_spec = item->spec;
521 			vxlan_mask = item->mask;
522 			/* Check if VXLAN item is used to describe protocol.
523 			 * If yes, both spec and mask should be NULL.
524 			 * If no, both spec and mask shouldn't be NULL.
525 			 */
526 			if ((!vxlan_spec && vxlan_mask) ||
527 			    (vxlan_spec && !vxlan_mask)) {
528 				rte_flow_error_set(error,
529 						   EINVAL,
530 						   RTE_FLOW_ERROR_TYPE_ITEM,
531 						   item,
532 						   "Invalid VXLAN item");
533 				return -rte_errno;
534 			}
535 
536 			if (!vxlan_spec && !vxlan_mask) {
537 				filter->tunnel_type =
538 				CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN;
539 				break;
540 			}
541 
542 			if (vxlan_spec->rsvd1 || vxlan_spec->rsvd0[0] ||
543 			    vxlan_spec->rsvd0[1] || vxlan_spec->rsvd0[2] ||
544 			    vxlan_spec->flags != 0x8) {
545 				rte_flow_error_set(error,
546 						   EINVAL,
547 						   RTE_FLOW_ERROR_TYPE_ITEM,
548 						   item,
549 						   "Invalid VXLAN item");
550 				return -rte_errno;
551 			}
552 
553 			/* Check if VNI is masked. */
554 			if (vxlan_spec && vxlan_mask) {
555 				vni_masked =
556 					!!memcmp(vxlan_mask->vni, vni_mask,
557 						 RTE_DIM(vni_mask));
558 				if (vni_masked) {
559 					rte_flow_error_set
560 						(error,
561 						 EINVAL,
562 						 RTE_FLOW_ERROR_TYPE_ITEM,
563 						 item,
564 						 "Invalid VNI mask");
565 					return -rte_errno;
566 				}
567 
568 				rte_memcpy(((uint8_t *)&tenant_id_be + 1),
569 					   vxlan_spec->vni, 3);
570 				filter->vni =
571 					rte_be_to_cpu_32(tenant_id_be);
572 				filter->tunnel_type =
573 				 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN;
574 			}
575 			break;
576 		case RTE_FLOW_ITEM_TYPE_NVGRE:
577 			nvgre_spec = item->spec;
578 			nvgre_mask = item->mask;
579 			/* Check if NVGRE item is used to describe protocol.
580 			 * If yes, both spec and mask should be NULL.
581 			 * If no, both spec and mask shouldn't be NULL.
582 			 */
583 			if ((!nvgre_spec && nvgre_mask) ||
584 			    (nvgre_spec && !nvgre_mask)) {
585 				rte_flow_error_set(error,
586 						   EINVAL,
587 						   RTE_FLOW_ERROR_TYPE_ITEM,
588 						   item,
589 						   "Invalid NVGRE item");
590 				return -rte_errno;
591 			}
592 
593 			if (!nvgre_spec && !nvgre_mask) {
594 				filter->tunnel_type =
595 				CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE;
596 				break;
597 			}
598 
599 			if (nvgre_spec->c_k_s_rsvd0_ver != 0x2000 ||
600 			    nvgre_spec->protocol != 0x6558) {
601 				rte_flow_error_set(error,
602 						   EINVAL,
603 						   RTE_FLOW_ERROR_TYPE_ITEM,
604 						   item,
605 						   "Invalid NVGRE item");
606 				return -rte_errno;
607 			}
608 
609 			if (nvgre_spec && nvgre_mask) {
610 				tni_masked =
611 					!!memcmp(nvgre_mask->tni, tni_mask,
612 						 RTE_DIM(tni_mask));
613 				if (tni_masked) {
614 					rte_flow_error_set
615 						(error,
616 						 EINVAL,
617 						 RTE_FLOW_ERROR_TYPE_ITEM,
618 						 item,
619 						 "Invalid TNI mask");
620 					return -rte_errno;
621 				}
622 				rte_memcpy(((uint8_t *)&tenant_id_be + 1),
623 					   nvgre_spec->tni, 3);
624 				filter->vni =
625 					rte_be_to_cpu_32(tenant_id_be);
626 				filter->tunnel_type =
627 				 CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_NVGRE;
628 			}
629 			break;
630 
631 		case RTE_FLOW_ITEM_TYPE_GRE:
632 			gre_spec = (const struct rte_flow_item_gre *)item->spec;
633 			gre_mask = (const struct rte_flow_item_gre *)item->mask;
634 
635 			/*
636 			 *Check if GRE item is used to describe protocol.
637 			 * If yes, both spec and mask should be NULL.
638 			 * If no, both spec and mask shouldn't be NULL.
639 			 */
640 			if (!!gre_spec ^ !!gre_mask) {
641 				rte_flow_error_set(error, EINVAL,
642 						   RTE_FLOW_ERROR_TYPE_ITEM,
643 						   item,
644 						   "Invalid GRE item");
645 				return -rte_errno;
646 			}
647 
648 			if (!gre_spec && !gre_mask) {
649 				filter->tunnel_type =
650 				CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE;
651 				break;
652 			}
653 			break;
654 
655 		case RTE_FLOW_ITEM_TYPE_VF:
656 			vf_spec = item->spec;
657 			vf = vf_spec->id;
658 			if (!BNXT_PF(bp)) {
659 				rte_flow_error_set(error,
660 						   EINVAL,
661 						   RTE_FLOW_ERROR_TYPE_ITEM,
662 						   item,
663 						   "Configuring on a VF!");
664 				return -rte_errno;
665 			}
666 
667 			if (vf >= bp->pdev->max_vfs) {
668 				rte_flow_error_set(error,
669 						   EINVAL,
670 						   RTE_FLOW_ERROR_TYPE_ITEM,
671 						   item,
672 						   "Incorrect VF id!");
673 				return -rte_errno;
674 			}
675 
676 			if (!attr->transfer) {
677 				rte_flow_error_set(error,
678 						   ENOTSUP,
679 						   RTE_FLOW_ERROR_TYPE_ITEM,
680 						   item,
681 						   "Matching VF traffic without"
682 						   " affecting it (transfer attribute)"
683 						   " is unsupported");
684 				return -rte_errno;
685 			}
686 
687 			filter->mirror_vnic_id =
688 			dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
689 			if (dflt_vnic < 0) {
690 				/* This simply indicates there's no driver
691 				 * loaded. This is not an error.
692 				 */
693 				rte_flow_error_set
694 					(error,
695 					 EINVAL,
696 					 RTE_FLOW_ERROR_TYPE_ITEM,
697 					 item,
698 					 "Unable to get default VNIC for VF");
699 				return -rte_errno;
700 			}
701 
702 			filter->mirror_vnic_id = dflt_vnic;
703 			en |= NTUPLE_FLTR_ALLOC_INPUT_EN_MIRROR_VNIC_ID;
704 			break;
705 		default:
706 			break;
707 		}
708 		item++;
709 	}
710 	filter->enables = en;
711 	filter->valid_flags = valid_flags;
712 
713 	return 0;
714 }
715 
716 /* Parse attributes */
717 static int
718 bnxt_flow_parse_attr(const struct rte_flow_attr *attr,
719 		     struct rte_flow_error *error)
720 {
721 	/* Must be input direction */
722 	if (!attr->ingress) {
723 		rte_flow_error_set(error,
724 				   EINVAL,
725 				   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
726 				   attr,
727 				   "Only support ingress.");
728 		return -rte_errno;
729 	}
730 
731 	/* Not supported */
732 	if (attr->egress) {
733 		rte_flow_error_set(error,
734 				   EINVAL,
735 				   RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
736 				   attr,
737 				   "No support for egress.");
738 		return -rte_errno;
739 	}
740 
741 	return 0;
742 }
743 
744 static struct bnxt_filter_info *
745 bnxt_find_matching_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf)
746 {
747 	struct bnxt_filter_info *mf, *f0;
748 	struct bnxt_vnic_info *vnic0;
749 	int i;
750 
751 	vnic0 = BNXT_GET_DEFAULT_VNIC(bp);
752 	f0 = STAILQ_FIRST(&vnic0->filter);
753 
754 	/* This flow has same DST MAC as the port/l2 filter. */
755 	if (memcmp(f0->l2_addr, nf->dst_macaddr, RTE_ETHER_ADDR_LEN) == 0)
756 		return f0;
757 
758 	for (i = bp->max_vnics - 1; i >= 0; i--) {
759 		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
760 
761 		if (vnic->fw_vnic_id == INVALID_VNIC_ID)
762 			continue;
763 
764 		STAILQ_FOREACH(mf, &vnic->filter, next) {
765 
766 			if (mf->matching_l2_fltr_ptr)
767 				continue;
768 
769 			if (mf->ethertype == nf->ethertype &&
770 			    mf->l2_ovlan == nf->l2_ovlan &&
771 			    mf->l2_ovlan_mask == nf->l2_ovlan_mask &&
772 			    mf->l2_ivlan == nf->l2_ivlan &&
773 			    mf->l2_ivlan_mask == nf->l2_ivlan_mask &&
774 			    !memcmp(mf->src_macaddr, nf->src_macaddr,
775 				    RTE_ETHER_ADDR_LEN) &&
776 			    !memcmp(mf->dst_macaddr, nf->dst_macaddr,
777 				    RTE_ETHER_ADDR_LEN))
778 				return mf;
779 		}
780 	}
781 	return NULL;
782 }
783 
784 static struct bnxt_filter_info *
785 bnxt_create_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf,
786 		      struct bnxt_vnic_info *vnic)
787 {
788 	struct bnxt_filter_info *filter1;
789 	int rc;
790 
791 	/* Alloc new L2 filter.
792 	 * This flow needs MAC filter which does not match any existing
793 	 * L2 filters.
794 	 */
795 	filter1 = bnxt_get_unused_filter(bp);
796 	if (filter1 == NULL)
797 		return NULL;
798 
799 	memcpy(filter1, nf, sizeof(*filter1));
800 
801 	filter1->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_XDP_DISABLE;
802 	filter1->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
803 	if (nf->valid_flags & BNXT_FLOW_L2_SRC_VALID_FLAG ||
804 	    nf->valid_flags & BNXT_FLOW_L2_DST_VALID_FLAG) {
805 		filter1->flags |=
806 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST;
807 		PMD_DRV_LOG(DEBUG, "Create Outer filter\n");
808 	}
809 
810 	if (nf->filter_type == HWRM_CFA_L2_FILTER &&
811 	    (nf->valid_flags & BNXT_FLOW_L2_SRC_VALID_FLAG ||
812 	     nf->valid_flags & BNXT_FLOW_L2_INNER_SRC_VALID_FLAG)) {
813 		PMD_DRV_LOG(DEBUG, "Create L2 filter for SRC MAC\n");
814 		filter1->flags |=
815 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_SOURCE_VALID;
816 		memcpy(filter1->l2_addr, nf->src_macaddr, RTE_ETHER_ADDR_LEN);
817 	} else {
818 		PMD_DRV_LOG(DEBUG, "Create L2 filter for DST MAC\n");
819 		memcpy(filter1->l2_addr, nf->dst_macaddr, RTE_ETHER_ADDR_LEN);
820 	}
821 
822 	if (nf->priority &&
823 	    (nf->valid_flags & BNXT_FLOW_L2_DST_VALID_FLAG ||
824 	     nf->valid_flags & BNXT_FLOW_L2_INNER_DST_VALID_FLAG)) {
825 		/* Tell the FW where to place the filter in the table. */
826 		if (nf->priority > 65535) {
827 			filter1->pri_hint =
828 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER;
829 			/* This will place the filter in TCAM */
830 			filter1->l2_filter_id_hint = (uint64_t)-1;
831 		}
832 	}
833 
834 	if (nf->valid_flags & (BNXT_FLOW_L2_DST_VALID_FLAG |
835 			       BNXT_FLOW_L2_SRC_VALID_FLAG |
836 			       BNXT_FLOW_L2_INNER_SRC_VALID_FLAG |
837 			       BNXT_FLOW_L2_INNER_DST_VALID_FLAG)) {
838 		filter1->enables =
839 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
840 			L2_FILTER_ALLOC_INPUT_EN_L2_ADDR_MASK;
841 		memset(filter1->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN);
842 	}
843 
844 	if (nf->valid_flags & BNXT_FLOW_L2_DROP_FLAG) {
845 		filter1->flags |=
846 			HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_DROP;
847 		if (nf->ethertype == RTE_ETHER_TYPE_IPV4) {
848 			/* Num VLANs for drop filter will/should be 0.
849 			 * If the req is memset to 0, then the count will
850 			 * be automatically set to 0.
851 			 */
852 			if (nf->valid_flags & BNXT_FLOW_PARSE_INNER_FLAG) {
853 				filter1->enables |=
854 					L2_FILTER_ALLOC_INPUT_EN_T_NUM_VLANS;
855 			} else {
856 				filter1->enables |=
857 					L2_FILTER_ALLOC_INPUT_EN_NUM_VLANS;
858 				filter1->flags |=
859 				HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST;
860 			}
861 		}
862 	}
863 
864 	rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id,
865 				     filter1);
866 	if (rc) {
867 		bnxt_free_filter(bp, filter1);
868 		return NULL;
869 	}
870 	filter1->l2_ref_cnt++;
871 	return filter1;
872 }
873 
874 struct bnxt_filter_info *
875 bnxt_get_l2_filter(struct bnxt *bp, struct bnxt_filter_info *nf,
876 		   struct bnxt_vnic_info *vnic)
877 {
878 	struct bnxt_filter_info *l2_filter = NULL;
879 
880 	l2_filter = bnxt_find_matching_l2_filter(bp, nf);
881 	if (l2_filter) {
882 		l2_filter->l2_ref_cnt++;
883 	} else {
884 		l2_filter = bnxt_create_l2_filter(bp, nf, vnic);
885 		if (l2_filter) {
886 			STAILQ_INSERT_TAIL(&vnic->filter, l2_filter, next);
887 			l2_filter->vnic = vnic;
888 		}
889 	}
890 	nf->matching_l2_fltr_ptr = l2_filter;
891 
892 	return l2_filter;
893 }
894 
895 static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic)
896 {
897 	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
898 	uint64_t rx_offloads = dev_conf->rxmode.offloads;
899 	int rc;
900 
901 	rc = bnxt_vnic_grp_alloc(bp, vnic);
902 	if (rc)
903 		goto ret;
904 
905 	rc = bnxt_hwrm_vnic_alloc(bp, vnic);
906 	if (rc) {
907 		PMD_DRV_LOG(ERR, "HWRM vnic alloc failure rc: %x\n", rc);
908 		goto ret;
909 	}
910 	bp->nr_vnics++;
911 
912 	/* RSS context is required only when there is more than one RSS ring */
913 	if (vnic->rx_queue_cnt > 1) {
914 		rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic, 0 /* ctx_idx 0 */);
915 		if (rc) {
916 			PMD_DRV_LOG(ERR,
917 				    "HWRM vnic ctx alloc failure: %x\n", rc);
918 			goto ret;
919 		}
920 	} else {
921 		PMD_DRV_LOG(DEBUG, "No RSS context required\n");
922 	}
923 
924 	if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
925 		vnic->vlan_strip = true;
926 	else
927 		vnic->vlan_strip = false;
928 
929 	rc = bnxt_hwrm_vnic_cfg(bp, vnic);
930 	if (rc)
931 		goto ret;
932 
933 	bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
934 
935 ret:
936 	return rc;
937 }
938 
939 static int match_vnic_rss_cfg(struct bnxt *bp,
940 			      struct bnxt_vnic_info *vnic,
941 			      const struct rte_flow_action_rss *rss)
942 {
943 	unsigned int match = 0, i;
944 
945 	if (vnic->rx_queue_cnt != rss->queue_num)
946 		return -EINVAL;
947 
948 	for (i = 0; i < rss->queue_num; i++) {
949 		if (!bp->rx_queues[rss->queue[i]]->vnic->rx_queue_cnt &&
950 		    !bp->rx_queues[rss->queue[i]]->rx_started)
951 			return -EINVAL;
952 	}
953 
954 	for (i = 0; i < vnic->rx_queue_cnt; i++) {
955 		int j;
956 
957 		for (j = 0; j < vnic->rx_queue_cnt; j++) {
958 			if (bp->grp_info[rss->queue[i]].fw_grp_id ==
959 			    vnic->fw_grp_ids[j])
960 				match++;
961 		}
962 	}
963 
964 	if (match != vnic->rx_queue_cnt) {
965 		PMD_DRV_LOG(ERR,
966 			    "VNIC queue count %d vs queues matched %d\n",
967 			    match, vnic->rx_queue_cnt);
968 		return -EINVAL;
969 	}
970 
971 	return 0;
972 }
973 
974 static void
975 bnxt_update_filter_flags_en(struct bnxt_filter_info *filter,
976 			    struct bnxt_filter_info *filter1,
977 			    int use_ntuple)
978 {
979 	if (!use_ntuple &&
980 	    !(filter->valid_flags &
981 	      ~(BNXT_FLOW_L2_DST_VALID_FLAG |
982 		BNXT_FLOW_L2_SRC_VALID_FLAG |
983 		BNXT_FLOW_L2_INNER_SRC_VALID_FLAG |
984 		BNXT_FLOW_L2_INNER_DST_VALID_FLAG |
985 		BNXT_FLOW_L2_DROP_FLAG |
986 		BNXT_FLOW_PARSE_INNER_FLAG))) {
987 		filter->flags = filter1->flags;
988 		filter->enables = filter1->enables;
989 		filter->filter_type = HWRM_CFA_L2_FILTER;
990 		memcpy(filter->l2_addr, filter1->l2_addr, RTE_ETHER_ADDR_LEN);
991 		memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN);
992 		filter->pri_hint = filter1->pri_hint;
993 		filter->l2_filter_id_hint = filter1->l2_filter_id_hint;
994 	}
995 	filter->fw_l2_filter_id = filter1->fw_l2_filter_id;
996 	filter->l2_ref_cnt = filter1->l2_ref_cnt;
997 	filter->flow_id = filter1->flow_id;
998 	PMD_DRV_LOG(DEBUG,
999 		"l2_filter: %p fw_l2_filter_id %" PRIx64 " l2_ref_cnt %u\n",
1000 		filter1, filter->fw_l2_filter_id, filter->l2_ref_cnt);
1001 }
1002 
1003 static int
1004 bnxt_validate_and_parse_flow(struct rte_eth_dev *dev,
1005 			     const struct rte_flow_item pattern[],
1006 			     const struct rte_flow_action actions[],
1007 			     const struct rte_flow_attr *attr,
1008 			     struct rte_flow_error *error,
1009 			     struct bnxt_filter_info *filter)
1010 {
1011 	const struct rte_flow_action *act =
1012 		bnxt_flow_non_void_action(actions);
1013 	struct bnxt *bp = dev->data->dev_private;
1014 	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
1015 	struct bnxt_vnic_info *vnic = NULL, *vnic0 = NULL;
1016 	const struct rte_flow_action_queue *act_q;
1017 	const struct rte_flow_action_vf *act_vf;
1018 	struct bnxt_filter_info *filter1 = NULL;
1019 	const struct rte_flow_action_rss *rss;
1020 	struct bnxt_rx_queue *rxq = NULL;
1021 	int dflt_vnic, vnic_id;
1022 	unsigned int rss_idx;
1023 	uint32_t vf = 0, i;
1024 	int rc, use_ntuple;
1025 
1026 	rc =
1027 	bnxt_validate_and_parse_flow_type(bp, attr, pattern, error, filter);
1028 	if (rc != 0)
1029 		goto ret;
1030 
1031 	rc = bnxt_flow_parse_attr(attr, error);
1032 	if (rc != 0)
1033 		goto ret;
1034 
1035 	/* Since we support ingress attribute only - right now. */
1036 	if (filter->filter_type == HWRM_CFA_EM_FILTER)
1037 		filter->flags = HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_PATH_RX;
1038 
1039 	use_ntuple = bnxt_filter_type_check(pattern, error);
1040 
1041 start:
1042 	switch (act->type) {
1043 	case RTE_FLOW_ACTION_TYPE_QUEUE:
1044 		/* Allow this flow. Redirect to a VNIC. */
1045 		act_q = (const struct rte_flow_action_queue *)act->conf;
1046 		if (!act_q->index || act_q->index >= bp->rx_nr_rings) {
1047 			rte_flow_error_set(error,
1048 					   EINVAL,
1049 					   RTE_FLOW_ERROR_TYPE_ACTION,
1050 					   act,
1051 					   "Invalid queue ID.");
1052 			rc = -rte_errno;
1053 			goto ret;
1054 		}
1055 		PMD_DRV_LOG(DEBUG, "Queue index %d\n", act_q->index);
1056 
1057 		vnic_id = attr->group;
1058 		if (!vnic_id) {
1059 			PMD_DRV_LOG(DEBUG, "Group id is 0\n");
1060 			vnic_id = act_q->index;
1061 		}
1062 
1063 		vnic = &bp->vnic_info[vnic_id];
1064 		if (vnic == NULL) {
1065 			rte_flow_error_set(error,
1066 					   EINVAL,
1067 					   RTE_FLOW_ERROR_TYPE_ACTION,
1068 					   act,
1069 					   "No matching VNIC found.");
1070 			rc = -rte_errno;
1071 			goto ret;
1072 		}
1073 		if (vnic->rx_queue_cnt) {
1074 			if (vnic->start_grp_id != act_q->index) {
1075 				PMD_DRV_LOG(ERR,
1076 					    "VNIC already in use\n");
1077 				rte_flow_error_set(error,
1078 						   EINVAL,
1079 						   RTE_FLOW_ERROR_TYPE_ACTION,
1080 						   act,
1081 						   "VNIC already in use");
1082 				rc = -rte_errno;
1083 				goto ret;
1084 			}
1085 			goto use_vnic;
1086 		}
1087 
1088 		rxq = bp->rx_queues[act_q->index];
1089 
1090 		if (!(dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS) && rxq &&
1091 		    vnic->fw_vnic_id != INVALID_HW_RING_ID)
1092 			goto use_vnic;
1093 
1094 		if (!rxq) {
1095 			PMD_DRV_LOG(ERR,
1096 				    "Queue invalid or used with other VNIC\n");
1097 			rte_flow_error_set(error,
1098 					   EINVAL,
1099 					   RTE_FLOW_ERROR_TYPE_ACTION,
1100 					   act,
1101 					   "Queue invalid queue or in use");
1102 			rc = -rte_errno;
1103 			goto ret;
1104 		}
1105 
1106 		rxq->vnic = vnic;
1107 		rxq->rx_started = 1;
1108 		vnic->rx_queue_cnt++;
1109 		vnic->start_grp_id = act_q->index;
1110 		vnic->end_grp_id = act_q->index;
1111 		vnic->func_default = 0;	//This is not a default VNIC.
1112 
1113 		PMD_DRV_LOG(DEBUG, "VNIC found\n");
1114 
1115 		rc = bnxt_vnic_prep(bp, vnic);
1116 		if (rc)  {
1117 			rte_flow_error_set(error,
1118 					   EINVAL,
1119 					   RTE_FLOW_ERROR_TYPE_ACTION,
1120 					   act,
1121 					   "VNIC prep fail");
1122 			rc = -rte_errno;
1123 			goto ret;
1124 		}
1125 
1126 		PMD_DRV_LOG(DEBUG,
1127 			    "vnic[%d] = %p vnic->fw_grp_ids = %p\n",
1128 			    act_q->index, vnic, vnic->fw_grp_ids);
1129 
1130 use_vnic:
1131 		vnic->ff_pool_idx = vnic_id;
1132 		PMD_DRV_LOG(DEBUG,
1133 			    "Setting vnic ff_idx %d\n", vnic->ff_pool_idx);
1134 		filter->dst_id = vnic->fw_vnic_id;
1135 
1136 		/* For ntuple filter, create the L2 filter with default VNIC.
1137 		 * The user specified redirect queue will be set while creating
1138 		 * the ntuple filter in hardware.
1139 		 */
1140 		vnic0 = BNXT_GET_DEFAULT_VNIC(bp);
1141 		if (use_ntuple)
1142 			filter1 = bnxt_get_l2_filter(bp, filter, vnic0);
1143 		else
1144 			filter1 = bnxt_get_l2_filter(bp, filter, vnic);
1145 		if (filter1 == NULL) {
1146 			rte_flow_error_set(error,
1147 					   ENOSPC,
1148 					   RTE_FLOW_ERROR_TYPE_ACTION,
1149 					   act,
1150 					   "Filter not available");
1151 			rc = -rte_errno;
1152 			goto ret;
1153 		}
1154 
1155 		PMD_DRV_LOG(DEBUG, "new fltr: %p l2fltr: %p l2_ref_cnt: %d\n",
1156 			    filter, filter1, filter1->l2_ref_cnt);
1157 		bnxt_update_filter_flags_en(filter, filter1, use_ntuple);
1158 		break;
1159 	case RTE_FLOW_ACTION_TYPE_DROP:
1160 		vnic0 = &bp->vnic_info[0];
1161 		filter->dst_id = vnic0->fw_vnic_id;
1162 		filter->valid_flags |= BNXT_FLOW_L2_DROP_FLAG;
1163 		filter1 = bnxt_get_l2_filter(bp, filter, vnic0);
1164 		if (filter1 == NULL) {
1165 			rte_flow_error_set(error,
1166 					   ENOSPC,
1167 					   RTE_FLOW_ERROR_TYPE_ACTION,
1168 					   act,
1169 					   "Filter not available");
1170 			rc = -rte_errno;
1171 			goto ret;
1172 		}
1173 
1174 		if (filter->filter_type == HWRM_CFA_EM_FILTER)
1175 			filter->flags =
1176 				HWRM_CFA_EM_FLOW_ALLOC_INPUT_FLAGS_DROP;
1177 		else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
1178 			filter->flags =
1179 				HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_DROP;
1180 
1181 		bnxt_update_filter_flags_en(filter, filter1, use_ntuple);
1182 		break;
1183 	case RTE_FLOW_ACTION_TYPE_COUNT:
1184 		vnic0 = &bp->vnic_info[0];
1185 		filter1 = bnxt_get_l2_filter(bp, filter, vnic0);
1186 		if (filter1 == NULL) {
1187 			rte_flow_error_set(error,
1188 					   ENOSPC,
1189 					   RTE_FLOW_ERROR_TYPE_ACTION,
1190 					   act,
1191 					   "New filter not available");
1192 			rc = -rte_errno;
1193 			goto ret;
1194 		}
1195 
1196 		filter->fw_l2_filter_id = filter1->fw_l2_filter_id;
1197 		filter->flow_id = filter1->flow_id;
1198 		filter->flags = HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_FLAGS_METER;
1199 		break;
1200 	case RTE_FLOW_ACTION_TYPE_VF:
1201 		act_vf = (const struct rte_flow_action_vf *)act->conf;
1202 		vf = act_vf->id;
1203 
1204 		if (filter->tunnel_type ==
1205 		    CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_VXLAN ||
1206 		    filter->tunnel_type ==
1207 		    CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_IPGRE) {
1208 			/* If issued on a VF, ensure id is 0 and is trusted */
1209 			if (BNXT_VF(bp)) {
1210 				if (!BNXT_VF_IS_TRUSTED(bp) || vf) {
1211 					rte_flow_error_set(error, EINVAL,
1212 						RTE_FLOW_ERROR_TYPE_ACTION,
1213 						act,
1214 						"Incorrect VF");
1215 					rc = -rte_errno;
1216 					goto ret;
1217 				}
1218 			}
1219 
1220 			filter->enables |= filter->tunnel_type;
1221 			filter->filter_type = HWRM_CFA_TUNNEL_REDIRECT_FILTER;
1222 			goto done;
1223 		}
1224 
1225 		if (vf >= bp->pdev->max_vfs) {
1226 			rte_flow_error_set(error,
1227 					   EINVAL,
1228 					   RTE_FLOW_ERROR_TYPE_ACTION,
1229 					   act,
1230 					   "Incorrect VF id!");
1231 			rc = -rte_errno;
1232 			goto ret;
1233 		}
1234 
1235 		filter->mirror_vnic_id =
1236 		dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
1237 		if (dflt_vnic < 0) {
1238 			/* This simply indicates there's no driver loaded.
1239 			 * This is not an error.
1240 			 */
1241 			rte_flow_error_set(error,
1242 					   EINVAL,
1243 					   RTE_FLOW_ERROR_TYPE_ACTION,
1244 					   act,
1245 					   "Unable to get default VNIC for VF");
1246 			rc = -rte_errno;
1247 			goto ret;
1248 		}
1249 
1250 		filter->mirror_vnic_id = dflt_vnic;
1251 		filter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_MIRROR_VNIC_ID;
1252 
1253 		vnic0 = &bp->vnic_info[0];
1254 		filter1 = bnxt_get_l2_filter(bp, filter, vnic0);
1255 		if (filter1 == NULL) {
1256 			rte_flow_error_set(error,
1257 					   ENOSPC,
1258 					   RTE_FLOW_ERROR_TYPE_ACTION,
1259 					   act,
1260 					   "New filter not available");
1261 			rc = -rte_errno;
1262 			goto ret;
1263 		}
1264 
1265 		filter->fw_l2_filter_id = filter1->fw_l2_filter_id;
1266 		filter->flow_id = filter1->flow_id;
1267 		break;
1268 	case RTE_FLOW_ACTION_TYPE_RSS:
1269 		rss = (const struct rte_flow_action_rss *)act->conf;
1270 
1271 		vnic_id = attr->group;
1272 		if (!vnic_id) {
1273 			PMD_DRV_LOG(ERR, "Group id cannot be 0\n");
1274 			rte_flow_error_set(error,
1275 					   EINVAL,
1276 					   RTE_FLOW_ERROR_TYPE_ATTR,
1277 					   NULL,
1278 					   "Group id cannot be 0");
1279 			rc = -rte_errno;
1280 			goto ret;
1281 		}
1282 
1283 		vnic = &bp->vnic_info[vnic_id];
1284 		if (vnic == NULL) {
1285 			rte_flow_error_set(error,
1286 					   EINVAL,
1287 					   RTE_FLOW_ERROR_TYPE_ACTION,
1288 					   act,
1289 					   "No matching VNIC for RSS group.");
1290 			rc = -rte_errno;
1291 			goto ret;
1292 		}
1293 		PMD_DRV_LOG(DEBUG, "VNIC found\n");
1294 
1295 		/* Check if requested RSS config matches RSS config of VNIC
1296 		 * only if it is not a fresh VNIC configuration.
1297 		 * Otherwise the existing VNIC configuration can be used.
1298 		 */
1299 		if (vnic->rx_queue_cnt) {
1300 			rc = match_vnic_rss_cfg(bp, vnic, rss);
1301 			if (rc) {
1302 				PMD_DRV_LOG(ERR,
1303 					    "VNIC and RSS config mismatch\n");
1304 				rte_flow_error_set(error,
1305 						   EINVAL,
1306 						   RTE_FLOW_ERROR_TYPE_ACTION,
1307 						   act,
1308 						   "VNIC and RSS cfg mismatch");
1309 				rc = -rte_errno;
1310 				goto ret;
1311 			}
1312 			goto vnic_found;
1313 		}
1314 
1315 		for (i = 0; i < rss->queue_num; i++) {
1316 			PMD_DRV_LOG(DEBUG, "RSS action Queue %d\n",
1317 				    rss->queue[i]);
1318 
1319 			if (!rss->queue[i] ||
1320 			    rss->queue[i] >= bp->rx_nr_rings ||
1321 			    !bp->rx_queues[rss->queue[i]]) {
1322 				rte_flow_error_set(error,
1323 						   EINVAL,
1324 						   RTE_FLOW_ERROR_TYPE_ACTION,
1325 						   act,
1326 						   "Invalid queue ID for RSS");
1327 				rc = -rte_errno;
1328 				goto ret;
1329 			}
1330 			rxq = bp->rx_queues[rss->queue[i]];
1331 
1332 			if (bp->vnic_info[0].fw_grp_ids[rss->queue[i]] !=
1333 			    INVALID_HW_RING_ID) {
1334 				PMD_DRV_LOG(ERR,
1335 					    "queue active with other VNIC\n");
1336 				rte_flow_error_set(error,
1337 						   EINVAL,
1338 						   RTE_FLOW_ERROR_TYPE_ACTION,
1339 						   act,
1340 						   "Invalid queue ID for RSS");
1341 				rc = -rte_errno;
1342 				goto ret;
1343 			}
1344 
1345 			rxq->vnic = vnic;
1346 			rxq->rx_started = 1;
1347 			vnic->rx_queue_cnt++;
1348 		}
1349 
1350 		vnic->start_grp_id = rss->queue[0];
1351 		vnic->end_grp_id = rss->queue[rss->queue_num - 1];
1352 		vnic->func_default = 0;	//This is not a default VNIC.
1353 
1354 		rc = bnxt_vnic_prep(bp, vnic);
1355 		if (rc) {
1356 			rte_flow_error_set(error,
1357 					   EINVAL,
1358 					   RTE_FLOW_ERROR_TYPE_ACTION,
1359 					   act,
1360 					   "VNIC prep fail");
1361 			rc = -rte_errno;
1362 			goto ret;
1363 		}
1364 
1365 		PMD_DRV_LOG(DEBUG,
1366 			    "vnic[%d] = %p vnic->fw_grp_ids = %p\n",
1367 			    vnic_id, vnic, vnic->fw_grp_ids);
1368 
1369 		vnic->ff_pool_idx = vnic_id;
1370 		PMD_DRV_LOG(DEBUG,
1371 			    "Setting vnic ff_pool_idx %d\n", vnic->ff_pool_idx);
1372 
1373 		/* This can be done only after vnic_grp_alloc is done. */
1374 		for (i = 0; i < vnic->rx_queue_cnt; i++) {
1375 			vnic->fw_grp_ids[i] =
1376 				bp->grp_info[rss->queue[i]].fw_grp_id;
1377 			/* Make sure vnic0 does not use these rings. */
1378 			bp->vnic_info[0].fw_grp_ids[rss->queue[i]] =
1379 				INVALID_HW_RING_ID;
1380 		}
1381 
1382 		for (rss_idx = 0; rss_idx < HW_HASH_INDEX_SIZE; ) {
1383 			for (i = 0; i < vnic->rx_queue_cnt; i++)
1384 				vnic->rss_table[rss_idx++] =
1385 					vnic->fw_grp_ids[i];
1386 		}
1387 
1388 		/* Configure RSS only if the queue count is > 1 */
1389 		if (vnic->rx_queue_cnt > 1) {
1390 			vnic->hash_type =
1391 				bnxt_rte_to_hwrm_hash_types(rss->types);
1392 
1393 			if (!rss->key_len) {
1394 				/* If hash key has not been specified,
1395 				 * use random hash key.
1396 				 */
1397 				prandom_bytes(vnic->rss_hash_key,
1398 					      HW_HASH_KEY_SIZE);
1399 			} else {
1400 				if (rss->key_len > HW_HASH_KEY_SIZE)
1401 					memcpy(vnic->rss_hash_key,
1402 					       rss->key,
1403 					       HW_HASH_KEY_SIZE);
1404 				else
1405 					memcpy(vnic->rss_hash_key,
1406 					       rss->key,
1407 					       rss->key_len);
1408 			}
1409 			bnxt_hwrm_vnic_rss_cfg(bp, vnic);
1410 		} else {
1411 			PMD_DRV_LOG(DEBUG, "No RSS config required\n");
1412 		}
1413 
1414 vnic_found:
1415 		filter->dst_id = vnic->fw_vnic_id;
1416 		filter1 = bnxt_get_l2_filter(bp, filter, vnic);
1417 		if (filter1 == NULL) {
1418 			rte_flow_error_set(error,
1419 					   ENOSPC,
1420 					   RTE_FLOW_ERROR_TYPE_ACTION,
1421 					   act,
1422 					   "New filter not available");
1423 			rc = -rte_errno;
1424 			goto ret;
1425 		}
1426 
1427 		PMD_DRV_LOG(DEBUG, "L2 filter created\n");
1428 		bnxt_update_filter_flags_en(filter, filter1, use_ntuple);
1429 		break;
1430 	case RTE_FLOW_ACTION_TYPE_MARK:
1431 		if (bp->flags & BNXT_FLAG_RX_VECTOR_PKT_MODE) {
1432 			PMD_DRV_LOG(DEBUG,
1433 				    "Disable vector processing for mark\n");
1434 			rte_flow_error_set(error,
1435 					   ENOTSUP,
1436 					   RTE_FLOW_ERROR_TYPE_ACTION,
1437 					   act,
1438 					   "Disable vector processing for mark");
1439 			rc = -rte_errno;
1440 			goto ret;
1441 		}
1442 
1443 		if (bp->mark_table == NULL) {
1444 			rte_flow_error_set(error,
1445 					   ENOMEM,
1446 					   RTE_FLOW_ERROR_TYPE_ACTION,
1447 					   act,
1448 					   "Mark table not allocated.");
1449 			rc = -rte_errno;
1450 			goto ret;
1451 		}
1452 
1453 		filter->valid_flags |= BNXT_FLOW_MARK_FLAG;
1454 		filter->mark = ((const struct rte_flow_action_mark *)
1455 				act->conf)->id;
1456 		PMD_DRV_LOG(DEBUG, "Mark the flow %d\n", filter->mark);
1457 		break;
1458 	default:
1459 		rte_flow_error_set(error,
1460 				   EINVAL,
1461 				   RTE_FLOW_ERROR_TYPE_ACTION,
1462 				   act,
1463 				   "Invalid action.");
1464 		rc = -rte_errno;
1465 		goto ret;
1466 	}
1467 
1468 done:
1469 	act = bnxt_flow_non_void_action(++act);
1470 	while (act->type != RTE_FLOW_ACTION_TYPE_END)
1471 		goto start;
1472 
1473 	return rc;
1474 ret:
1475 
1476 	if (filter1) {
1477 		bnxt_hwrm_clear_l2_filter(bp, filter1);
1478 		bnxt_free_filter(bp, filter1);
1479 	}
1480 
1481 	if (rte_errno)  {
1482 		if (vnic && STAILQ_EMPTY(&vnic->filter))
1483 			vnic->rx_queue_cnt = 0;
1484 
1485 		if (rxq && !vnic->rx_queue_cnt)
1486 			rxq->vnic = &bp->vnic_info[0];
1487 	}
1488 	return -rte_errno;
1489 }
1490 
1491 static
1492 struct bnxt_vnic_info *find_matching_vnic(struct bnxt *bp,
1493 					  struct bnxt_filter_info *filter)
1494 {
1495 	struct bnxt_vnic_info *vnic = NULL;
1496 	unsigned int i;
1497 
1498 	for (i = 0; i < bp->max_vnics; i++) {
1499 		vnic = &bp->vnic_info[i];
1500 		if (vnic->fw_vnic_id != INVALID_VNIC_ID &&
1501 		    filter->dst_id == vnic->fw_vnic_id) {
1502 			PMD_DRV_LOG(DEBUG, "Found matching VNIC Id %d\n",
1503 				    vnic->ff_pool_idx);
1504 			return vnic;
1505 		}
1506 	}
1507 	return NULL;
1508 }
1509 
1510 static int
1511 bnxt_flow_validate(struct rte_eth_dev *dev,
1512 		   const struct rte_flow_attr *attr,
1513 		   const struct rte_flow_item pattern[],
1514 		   const struct rte_flow_action actions[],
1515 		   struct rte_flow_error *error)
1516 {
1517 	struct bnxt *bp = dev->data->dev_private;
1518 	struct bnxt_vnic_info *vnic = NULL;
1519 	struct bnxt_filter_info *filter;
1520 	int ret = 0;
1521 
1522 	bnxt_acquire_flow_lock(bp);
1523 	ret = bnxt_flow_args_validate(attr, pattern, actions, error);
1524 	if (ret != 0) {
1525 		bnxt_release_flow_lock(bp);
1526 		return ret;
1527 	}
1528 
1529 	filter = bnxt_get_unused_filter(bp);
1530 	if (filter == NULL) {
1531 		PMD_DRV_LOG(ERR, "Not enough resources for a new flow.\n");
1532 		bnxt_release_flow_lock(bp);
1533 		return -ENOMEM;
1534 	}
1535 
1536 	ret = bnxt_validate_and_parse_flow(dev, pattern, actions, attr,
1537 					   error, filter);
1538 	if (ret)
1539 		goto exit;
1540 
1541 	vnic = find_matching_vnic(bp, filter);
1542 	if (vnic) {
1543 		if (STAILQ_EMPTY(&vnic->filter)) {
1544 			rte_free(vnic->fw_grp_ids);
1545 			bnxt_hwrm_vnic_ctx_free(bp, vnic);
1546 			bnxt_hwrm_vnic_free(bp, vnic);
1547 			vnic->rx_queue_cnt = 0;
1548 			PMD_DRV_LOG(DEBUG, "Free VNIC\n");
1549 		}
1550 	}
1551 
1552 	if (filter->filter_type == HWRM_CFA_EM_FILTER)
1553 		bnxt_hwrm_clear_em_filter(bp, filter);
1554 	else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
1555 		bnxt_hwrm_clear_ntuple_filter(bp, filter);
1556 	else
1557 		bnxt_hwrm_clear_l2_filter(bp, filter);
1558 
1559 exit:
1560 	/* No need to hold on to this filter if we are just validating flow */
1561 	bnxt_free_filter(bp, filter);
1562 	bnxt_release_flow_lock(bp);
1563 
1564 	return ret;
1565 }
1566 
1567 static void
1568 bnxt_update_filter(struct bnxt *bp, struct bnxt_filter_info *old_filter,
1569 		   struct bnxt_filter_info *new_filter)
1570 {
1571 	/* Clear the new L2 filter that was created in the previous step in
1572 	 * bnxt_validate_and_parse_flow. For L2 filters, we will use the new
1573 	 * filter which points to the new destination queue and so we clear
1574 	 * the previous L2 filter. For ntuple filters, we are going to reuse
1575 	 * the old L2 filter and create new NTUPLE filter with this new
1576 	 * destination queue subsequently during bnxt_flow_create. So we
1577 	 * decrement the ref cnt of the L2 filter that would've been bumped
1578 	 * up previously in bnxt_validate_and_parse_flow as the old n-tuple
1579 	 * filter that was referencing it will be deleted now.
1580 	 */
1581 	bnxt_hwrm_clear_l2_filter(bp, old_filter);
1582 	if (new_filter->filter_type == HWRM_CFA_L2_FILTER) {
1583 		bnxt_hwrm_set_l2_filter(bp, new_filter->dst_id, new_filter);
1584 	} else {
1585 		if (new_filter->filter_type == HWRM_CFA_EM_FILTER)
1586 			bnxt_hwrm_clear_em_filter(bp, old_filter);
1587 		if (new_filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
1588 			bnxt_hwrm_clear_ntuple_filter(bp, old_filter);
1589 	}
1590 }
1591 
1592 static int
1593 bnxt_match_filter(struct bnxt *bp, struct bnxt_filter_info *nf)
1594 {
1595 	struct bnxt_filter_info *mf;
1596 	struct rte_flow *flow;
1597 	int i;
1598 
1599 	for (i = bp->max_vnics - 1; i >= 0; i--) {
1600 		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
1601 
1602 		if (vnic->fw_vnic_id == INVALID_VNIC_ID)
1603 			continue;
1604 
1605 		STAILQ_FOREACH(flow, &vnic->flow_list, next) {
1606 			mf = flow->filter;
1607 
1608 			if (mf->filter_type == nf->filter_type &&
1609 			    mf->flags == nf->flags &&
1610 			    mf->src_port == nf->src_port &&
1611 			    mf->src_port_mask == nf->src_port_mask &&
1612 			    mf->dst_port == nf->dst_port &&
1613 			    mf->dst_port_mask == nf->dst_port_mask &&
1614 			    mf->ip_protocol == nf->ip_protocol &&
1615 			    mf->ip_addr_type == nf->ip_addr_type &&
1616 			    mf->ethertype == nf->ethertype &&
1617 			    mf->vni == nf->vni &&
1618 			    mf->tunnel_type == nf->tunnel_type &&
1619 			    mf->l2_ovlan == nf->l2_ovlan &&
1620 			    mf->l2_ovlan_mask == nf->l2_ovlan_mask &&
1621 			    mf->l2_ivlan == nf->l2_ivlan &&
1622 			    mf->l2_ivlan_mask == nf->l2_ivlan_mask &&
1623 			    !memcmp(mf->l2_addr, nf->l2_addr,
1624 				    RTE_ETHER_ADDR_LEN) &&
1625 			    !memcmp(mf->l2_addr_mask, nf->l2_addr_mask,
1626 				    RTE_ETHER_ADDR_LEN) &&
1627 			    !memcmp(mf->src_macaddr, nf->src_macaddr,
1628 				    RTE_ETHER_ADDR_LEN) &&
1629 			    !memcmp(mf->dst_macaddr, nf->dst_macaddr,
1630 				    RTE_ETHER_ADDR_LEN) &&
1631 			    !memcmp(mf->src_ipaddr, nf->src_ipaddr,
1632 				    sizeof(nf->src_ipaddr)) &&
1633 			    !memcmp(mf->src_ipaddr_mask, nf->src_ipaddr_mask,
1634 				    sizeof(nf->src_ipaddr_mask)) &&
1635 			    !memcmp(mf->dst_ipaddr, nf->dst_ipaddr,
1636 				    sizeof(nf->dst_ipaddr)) &&
1637 			    !memcmp(mf->dst_ipaddr_mask, nf->dst_ipaddr_mask,
1638 				    sizeof(nf->dst_ipaddr_mask))) {
1639 				if (mf->dst_id == nf->dst_id)
1640 					return -EEXIST;
1641 				/* Free the old filter, update flow
1642 				 * with new filter
1643 				 */
1644 				bnxt_update_filter(bp, mf, nf);
1645 				STAILQ_REMOVE(&vnic->filter, mf,
1646 					      bnxt_filter_info, next);
1647 				STAILQ_INSERT_TAIL(&vnic->filter, nf, next);
1648 				bnxt_free_filter(bp, mf);
1649 				flow->filter = nf;
1650 				return -EXDEV;
1651 			}
1652 		}
1653 	}
1654 	return 0;
1655 }
1656 
1657 static struct rte_flow *
1658 bnxt_flow_create(struct rte_eth_dev *dev,
1659 		 const struct rte_flow_attr *attr,
1660 		 const struct rte_flow_item pattern[],
1661 		 const struct rte_flow_action actions[],
1662 		 struct rte_flow_error *error)
1663 {
1664 	struct bnxt *bp = dev->data->dev_private;
1665 	struct bnxt_vnic_info *vnic = NULL;
1666 	struct bnxt_filter_info *filter;
1667 	bool update_flow = false;
1668 	struct rte_flow *flow;
1669 	int ret = 0;
1670 	uint32_t tun_type;
1671 
1672 	if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
1673 		rte_flow_error_set(error, EINVAL,
1674 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1675 				   "Failed to create flow, Not a Trusted VF!");
1676 		return NULL;
1677 	}
1678 
1679 	if (!dev->data->dev_started) {
1680 		rte_flow_error_set(error,
1681 				   EINVAL,
1682 				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
1683 				   NULL,
1684 				   "Device must be started");
1685 		return NULL;
1686 	}
1687 
1688 	flow = rte_zmalloc("bnxt_flow", sizeof(struct rte_flow), 0);
1689 	if (!flow) {
1690 		rte_flow_error_set(error, ENOMEM,
1691 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1692 				   "Failed to allocate memory");
1693 		return flow;
1694 	}
1695 
1696 	bnxt_acquire_flow_lock(bp);
1697 	ret = bnxt_flow_args_validate(attr, pattern, actions, error);
1698 	if (ret != 0) {
1699 		PMD_DRV_LOG(ERR, "Not a validate flow.\n");
1700 		goto free_flow;
1701 	}
1702 
1703 	filter = bnxt_get_unused_filter(bp);
1704 	if (filter == NULL) {
1705 		PMD_DRV_LOG(ERR, "Not enough resources for a new flow.\n");
1706 		goto free_flow;
1707 	}
1708 
1709 	ret = bnxt_validate_and_parse_flow(dev, pattern, actions, attr,
1710 					   error, filter);
1711 	if (ret != 0)
1712 		goto free_filter;
1713 
1714 	ret = bnxt_match_filter(bp, filter);
1715 	if (ret == -EEXIST) {
1716 		PMD_DRV_LOG(DEBUG, "Flow already exists.\n");
1717 		/* Clear the filter that was created as part of
1718 		 * validate_and_parse_flow() above
1719 		 */
1720 		bnxt_hwrm_clear_l2_filter(bp, filter);
1721 		goto free_filter;
1722 	} else if (ret == -EXDEV) {
1723 		PMD_DRV_LOG(DEBUG, "Flow with same pattern exists\n");
1724 		PMD_DRV_LOG(DEBUG, "Updating with different destination\n");
1725 		update_flow = true;
1726 	}
1727 
1728 	/* If tunnel redirection to a VF/PF is specified then only tunnel_type
1729 	 * is set and enable is set to the tunnel type. Issue hwrm cmd directly
1730 	 * in such a case.
1731 	 */
1732 	if (filter->filter_type == HWRM_CFA_TUNNEL_REDIRECT_FILTER &&
1733 	    filter->enables == filter->tunnel_type) {
1734 		ret = bnxt_hwrm_tunnel_redirect_query(bp, &tun_type);
1735 		if (ret) {
1736 			rte_flow_error_set(error, -ret,
1737 					   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1738 					   "Unable to query tunnel to VF");
1739 			goto free_filter;
1740 		}
1741 		if (tun_type == (1U << filter->tunnel_type)) {
1742 			ret =
1743 			bnxt_hwrm_tunnel_redirect_free(bp,
1744 						       filter->tunnel_type);
1745 			if (ret) {
1746 				PMD_DRV_LOG(ERR,
1747 					    "Unable to free existing tunnel\n");
1748 				rte_flow_error_set(error, -ret,
1749 						   RTE_FLOW_ERROR_TYPE_HANDLE,
1750 						   NULL,
1751 						   "Unable to free preexisting "
1752 						   "tunnel on VF");
1753 				goto free_filter;
1754 			}
1755 		}
1756 		ret = bnxt_hwrm_tunnel_redirect(bp, filter->tunnel_type);
1757 		if (ret) {
1758 			rte_flow_error_set(error, -ret,
1759 					   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1760 					   "Unable to redirect tunnel to VF");
1761 			goto free_filter;
1762 		}
1763 		vnic = &bp->vnic_info[0];
1764 		goto done;
1765 	}
1766 
1767 	if (filter->filter_type == HWRM_CFA_EM_FILTER) {
1768 		filter->enables |=
1769 			HWRM_CFA_EM_FLOW_ALLOC_INPUT_ENABLES_L2_FILTER_ID;
1770 		ret = bnxt_hwrm_set_em_filter(bp, filter->dst_id, filter);
1771 	}
1772 
1773 	if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) {
1774 		filter->enables |=
1775 			HWRM_CFA_NTUPLE_FILTER_ALLOC_INPUT_ENABLES_L2_FILTER_ID;
1776 		ret = bnxt_hwrm_set_ntuple_filter(bp, filter->dst_id, filter);
1777 	}
1778 
1779 	vnic = find_matching_vnic(bp, filter);
1780 done:
1781 	if (!ret || update_flow) {
1782 		flow->filter = filter;
1783 		flow->vnic = vnic;
1784 		if (update_flow) {
1785 			ret = -EXDEV;
1786 			goto free_flow;
1787 		}
1788 
1789 		STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
1790 		PMD_DRV_LOG(DEBUG, "Successfully created flow.\n");
1791 		STAILQ_INSERT_TAIL(&vnic->flow_list, flow, next);
1792 		if (filter->valid_flags & BNXT_FLOW_MARK_FLAG) {
1793 			PMD_DRV_LOG(DEBUG,
1794 				    "Mark action: mark id 0x%x, flow id 0x%x\n",
1795 				    filter->mark, filter->flow_id);
1796 
1797 			/* TCAM and EM should be 16-bit only.
1798 			 * Other modes not supported.
1799 			 */
1800 			bp->mark_table[filter->flow_id & BNXT_FLOW_ID_MASK] =
1801 				filter->mark;
1802 		}
1803 		bnxt_release_flow_lock(bp);
1804 		return flow;
1805 	}
1806 
1807 free_filter:
1808 	bnxt_free_filter(bp, filter);
1809 free_flow:
1810 	if (ret == -EEXIST)
1811 		rte_flow_error_set(error, ret,
1812 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1813 				   "Matching Flow exists.");
1814 	else if (ret == -EXDEV)
1815 		rte_flow_error_set(error, 0,
1816 				   RTE_FLOW_ERROR_TYPE_NONE, NULL,
1817 				   "Flow with pattern exists, updating destination queue");
1818 	else if (!rte_errno)
1819 		rte_flow_error_set(error, -ret,
1820 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1821 				   "Failed to create flow.");
1822 	rte_free(flow);
1823 	flow = NULL;
1824 	bnxt_release_flow_lock(bp);
1825 	return flow;
1826 }
1827 
1828 static int bnxt_handle_tunnel_redirect_destroy(struct bnxt *bp,
1829 					       struct bnxt_filter_info *filter,
1830 					       struct rte_flow_error *error)
1831 {
1832 	uint16_t tun_dst_fid;
1833 	uint32_t tun_type;
1834 	int ret = 0;
1835 
1836 	ret = bnxt_hwrm_tunnel_redirect_query(bp, &tun_type);
1837 	if (ret) {
1838 		rte_flow_error_set(error, -ret,
1839 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1840 				   "Unable to query tunnel to VF");
1841 		return ret;
1842 	}
1843 	if (tun_type == (1U << filter->tunnel_type)) {
1844 		ret = bnxt_hwrm_tunnel_redirect_info(bp, filter->tunnel_type,
1845 						     &tun_dst_fid);
1846 		if (ret) {
1847 			rte_flow_error_set(error, -ret,
1848 					   RTE_FLOW_ERROR_TYPE_HANDLE,
1849 					   NULL,
1850 					   "tunnel_redirect info cmd fail");
1851 			return ret;
1852 		}
1853 		PMD_DRV_LOG(INFO, "Pre-existing tunnel fid = %x vf->fid = %x\n",
1854 			    tun_dst_fid + bp->first_vf_id, bp->fw_fid);
1855 
1856 		/* Tunnel doesn't belong to this VF, so don't send HWRM
1857 		 * cmd, just delete the flow from driver
1858 		 */
1859 		if (bp->fw_fid != (tun_dst_fid + bp->first_vf_id))
1860 			PMD_DRV_LOG(ERR,
1861 				    "Tunnel does not belong to this VF, skip hwrm_tunnel_redirect_free\n");
1862 		else
1863 			ret = bnxt_hwrm_tunnel_redirect_free(bp,
1864 							filter->tunnel_type);
1865 	}
1866 	return ret;
1867 }
1868 
1869 static int
1870 _bnxt_flow_destroy(struct bnxt *bp,
1871 		   struct rte_flow *flow,
1872 		    struct rte_flow_error *error)
1873 {
1874 	struct bnxt_filter_info *filter;
1875 	struct bnxt_vnic_info *vnic;
1876 	int ret = 0;
1877 
1878 	filter = flow->filter;
1879 	vnic = flow->vnic;
1880 
1881 	if (filter->filter_type == HWRM_CFA_TUNNEL_REDIRECT_FILTER &&
1882 	    filter->enables == filter->tunnel_type) {
1883 		ret = bnxt_handle_tunnel_redirect_destroy(bp, filter, error);
1884 		if (!ret)
1885 			goto done;
1886 		else
1887 			return ret;
1888 	}
1889 
1890 	ret = bnxt_match_filter(bp, filter);
1891 	if (ret == 0)
1892 		PMD_DRV_LOG(ERR, "Could not find matching flow\n");
1893 
1894 	if (filter->valid_flags & BNXT_FLOW_MARK_FLAG) {
1895 		bp->mark_table[filter->flow_id & BNXT_FLOW_ID_MASK] = 0;
1896 		filter->flow_id = 0;
1897 	}
1898 
1899 	if (filter->filter_type == HWRM_CFA_EM_FILTER)
1900 		ret = bnxt_hwrm_clear_em_filter(bp, filter);
1901 	if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
1902 		ret = bnxt_hwrm_clear_ntuple_filter(bp, filter);
1903 	ret = bnxt_hwrm_clear_l2_filter(bp, filter);
1904 
1905 done:
1906 	if (!ret) {
1907 		/* If it is a L2 drop filter, when the filter is created,
1908 		 * the FW updates the BC/MC records.
1909 		 * Once this filter is removed, issue the set_rx_mask command
1910 		 * to reset the BC/MC records in the HW to the settings
1911 		 * before the drop counter is created.
1912 		 */
1913 		if (filter->valid_flags & BNXT_FLOW_L2_DROP_FLAG)
1914 			bnxt_set_rx_mask_no_vlan(bp, &bp->vnic_info[0]);
1915 
1916 		STAILQ_REMOVE(&vnic->filter, filter, bnxt_filter_info, next);
1917 		bnxt_free_filter(bp, filter);
1918 		STAILQ_REMOVE(&vnic->flow_list, flow, rte_flow, next);
1919 		rte_free(flow);
1920 
1921 		/* If this was the last flow associated with this vnic,
1922 		 * switch the queue back to RSS pool.
1923 		 */
1924 		if (vnic && !vnic->func_default &&
1925 		    STAILQ_EMPTY(&vnic->flow_list)) {
1926 			rte_free(vnic->fw_grp_ids);
1927 			if (vnic->rx_queue_cnt > 1)
1928 				bnxt_hwrm_vnic_ctx_free(bp, vnic);
1929 
1930 			bnxt_hwrm_vnic_free(bp, vnic);
1931 			vnic->rx_queue_cnt = 0;
1932 		}
1933 	} else {
1934 		rte_flow_error_set(error, -ret,
1935 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1936 				   "Failed to destroy flow.");
1937 	}
1938 
1939 	return ret;
1940 }
1941 
1942 static int
1943 bnxt_flow_destroy(struct rte_eth_dev *dev,
1944 		  struct rte_flow *flow,
1945 		  struct rte_flow_error *error)
1946 {
1947 	struct bnxt *bp = dev->data->dev_private;
1948 	int ret = 0;
1949 
1950 	bnxt_acquire_flow_lock(bp);
1951 	if (!flow) {
1952 		rte_flow_error_set(error, EINVAL,
1953 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1954 				   "Invalid flow: failed to destroy flow.");
1955 		bnxt_release_flow_lock(bp);
1956 		return -EINVAL;
1957 	}
1958 
1959 	if (!flow->filter) {
1960 		rte_flow_error_set(error, EINVAL,
1961 				   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
1962 				   "Invalid flow: failed to destroy flow.");
1963 		bnxt_release_flow_lock(bp);
1964 		return -EINVAL;
1965 	}
1966 	ret = _bnxt_flow_destroy(bp, flow, error);
1967 	bnxt_release_flow_lock(bp);
1968 
1969 	return ret;
1970 }
1971 
1972 static int
1973 bnxt_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
1974 {
1975 	struct bnxt *bp = dev->data->dev_private;
1976 	struct bnxt_vnic_info *vnic;
1977 	struct rte_flow *flow;
1978 	unsigned int i;
1979 	int ret = 0;
1980 
1981 	bnxt_acquire_flow_lock(bp);
1982 	for (i = 0; i < bp->max_vnics; i++) {
1983 		vnic = &bp->vnic_info[i];
1984 		if (vnic && vnic->fw_vnic_id == INVALID_VNIC_ID)
1985 			continue;
1986 
1987 		while (!STAILQ_EMPTY(&vnic->flow_list)) {
1988 			flow = STAILQ_FIRST(&vnic->flow_list);
1989 
1990 			if (!flow->filter)
1991 				continue;
1992 
1993 			ret = _bnxt_flow_destroy(bp, flow, error);
1994 			if (ret)
1995 				break;
1996 		}
1997 	}
1998 	bnxt_release_flow_lock(bp);
1999 
2000 	return ret;
2001 }
2002 
2003 const struct rte_flow_ops bnxt_flow_ops = {
2004 	.validate = bnxt_flow_validate,
2005 	.create = bnxt_flow_create,
2006 	.destroy = bnxt_flow_destroy,
2007 	.flush = bnxt_flow_flush,
2008 };
2009