15571e8c9SPieter Jansen van Vuuren /*
25571e8c9SPieter Jansen van Vuuren  * Copyright (C) 2017 Netronome Systems, Inc.
35571e8c9SPieter Jansen van Vuuren  *
45571e8c9SPieter Jansen van Vuuren  * This software is dual licensed under the GNU General License Version 2,
55571e8c9SPieter Jansen van Vuuren  * June 1991 as shown in the file COPYING in the top-level directory of this
65571e8c9SPieter Jansen van Vuuren  * source tree or the BSD 2-Clause License provided below.  You have the
75571e8c9SPieter Jansen van Vuuren  * option to license this software under the complete terms of either license.
85571e8c9SPieter Jansen van Vuuren  *
95571e8c9SPieter Jansen van Vuuren  * The BSD 2-Clause License:
105571e8c9SPieter Jansen van Vuuren  *
115571e8c9SPieter Jansen van Vuuren  *     Redistribution and use in source and binary forms, with or
125571e8c9SPieter Jansen van Vuuren  *     without modification, are permitted provided that the following
135571e8c9SPieter Jansen van Vuuren  *     conditions are met:
145571e8c9SPieter Jansen van Vuuren  *
155571e8c9SPieter Jansen van Vuuren  *      1. Redistributions of source code must retain the above
165571e8c9SPieter Jansen van Vuuren  *         copyright notice, this list of conditions and the following
175571e8c9SPieter Jansen van Vuuren  *         disclaimer.
185571e8c9SPieter Jansen van Vuuren  *
195571e8c9SPieter Jansen van Vuuren  *      2. Redistributions in binary form must reproduce the above
205571e8c9SPieter Jansen van Vuuren  *         copyright notice, this list of conditions and the following
215571e8c9SPieter Jansen van Vuuren  *         disclaimer in the documentation and/or other materials
225571e8c9SPieter Jansen van Vuuren  *         provided with the distribution.
235571e8c9SPieter Jansen van Vuuren  *
245571e8c9SPieter Jansen van Vuuren  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
255571e8c9SPieter Jansen van Vuuren  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
265571e8c9SPieter Jansen van Vuuren  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
275571e8c9SPieter Jansen van Vuuren  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
285571e8c9SPieter Jansen van Vuuren  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
295571e8c9SPieter Jansen van Vuuren  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
305571e8c9SPieter Jansen van Vuuren  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
315571e8c9SPieter Jansen van Vuuren  * SOFTWARE.
325571e8c9SPieter Jansen van Vuuren  */
335571e8c9SPieter Jansen van Vuuren 
345571e8c9SPieter Jansen van Vuuren #include <linux/bitfield.h>
355571e8c9SPieter Jansen van Vuuren #include <net/pkt_cls.h>
365571e8c9SPieter Jansen van Vuuren 
375571e8c9SPieter Jansen van Vuuren #include "cmsg.h"
385571e8c9SPieter Jansen van Vuuren #include "main.h"
395571e8c9SPieter Jansen van Vuuren 
405571e8c9SPieter Jansen van Vuuren static void
415571e8c9SPieter Jansen van Vuuren nfp_flower_compile_meta_tci(struct nfp_flower_meta_two *frame,
425571e8c9SPieter Jansen van Vuuren 			    struct tc_cls_flower_offload *flow, u8 key_type,
435571e8c9SPieter Jansen van Vuuren 			    bool mask_version)
445571e8c9SPieter Jansen van Vuuren {
456afd33e4SPieter Jansen van Vuuren 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
465571e8c9SPieter Jansen van Vuuren 	struct flow_dissector_key_vlan *flow_vlan;
475571e8c9SPieter Jansen van Vuuren 	u16 tmp_tci;
485571e8c9SPieter Jansen van Vuuren 
49a7cd39e0SPieter Jansen van Vuuren 	memset(frame, 0, sizeof(struct nfp_flower_meta_two));
505571e8c9SPieter Jansen van Vuuren 	/* Populate the metadata frame. */
515571e8c9SPieter Jansen van Vuuren 	frame->nfp_flow_key_layer = key_type;
525571e8c9SPieter Jansen van Vuuren 	frame->mask_id = ~0;
535571e8c9SPieter Jansen van Vuuren 
54a7cd39e0SPieter Jansen van Vuuren 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
555571e8c9SPieter Jansen van Vuuren 		flow_vlan = skb_flow_dissector_target(flow->dissector,
565571e8c9SPieter Jansen van Vuuren 						      FLOW_DISSECTOR_KEY_VLAN,
576afd33e4SPieter Jansen van Vuuren 						      target);
585571e8c9SPieter Jansen van Vuuren 		/* Populate the tci field. */
59a7cd39e0SPieter Jansen van Vuuren 		if (flow_vlan->vlan_id) {
605571e8c9SPieter Jansen van Vuuren 			tmp_tci = FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
615571e8c9SPieter Jansen van Vuuren 					     flow_vlan->vlan_priority) |
625571e8c9SPieter Jansen van Vuuren 				  FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
635571e8c9SPieter Jansen van Vuuren 					     flow_vlan->vlan_id) |
645571e8c9SPieter Jansen van Vuuren 				  NFP_FLOWER_MASK_VLAN_CFI;
655571e8c9SPieter Jansen van Vuuren 			frame->tci = cpu_to_be16(tmp_tci);
665571e8c9SPieter Jansen van Vuuren 		}
67a7cd39e0SPieter Jansen van Vuuren 	}
68a7cd39e0SPieter Jansen van Vuuren }
695571e8c9SPieter Jansen van Vuuren 
705571e8c9SPieter Jansen van Vuuren static void
715571e8c9SPieter Jansen van Vuuren nfp_flower_compile_meta(struct nfp_flower_meta_one *frame, u8 key_type)
725571e8c9SPieter Jansen van Vuuren {
735571e8c9SPieter Jansen van Vuuren 	frame->nfp_flow_key_layer = key_type;
745571e8c9SPieter Jansen van Vuuren 	frame->mask_id = 0;
755571e8c9SPieter Jansen van Vuuren 	frame->reserved = 0;
765571e8c9SPieter Jansen van Vuuren }
775571e8c9SPieter Jansen van Vuuren 
785571e8c9SPieter Jansen van Vuuren static int
795571e8c9SPieter Jansen van Vuuren nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port,
80611aec10SJohn Hurley 			bool mask_version, enum nfp_flower_tun_type tun_type)
815571e8c9SPieter Jansen van Vuuren {
825571e8c9SPieter Jansen van Vuuren 	if (mask_version) {
835571e8c9SPieter Jansen van Vuuren 		frame->in_port = cpu_to_be32(~0);
845571e8c9SPieter Jansen van Vuuren 		return 0;
855571e8c9SPieter Jansen van Vuuren 	}
865571e8c9SPieter Jansen van Vuuren 
87611aec10SJohn Hurley 	if (tun_type)
88611aec10SJohn Hurley 		frame->in_port = cpu_to_be32(NFP_FL_PORT_TYPE_TUN | tun_type);
89611aec10SJohn Hurley 	else
905571e8c9SPieter Jansen van Vuuren 		frame->in_port = cpu_to_be32(cmsg_port);
915571e8c9SPieter Jansen van Vuuren 
925571e8c9SPieter Jansen van Vuuren 	return 0;
935571e8c9SPieter Jansen van Vuuren }
945571e8c9SPieter Jansen van Vuuren 
955571e8c9SPieter Jansen van Vuuren static void
965571e8c9SPieter Jansen van Vuuren nfp_flower_compile_mac(struct nfp_flower_mac_mpls *frame,
975571e8c9SPieter Jansen van Vuuren 		       struct tc_cls_flower_offload *flow,
985571e8c9SPieter Jansen van Vuuren 		       bool mask_version)
995571e8c9SPieter Jansen van Vuuren {
1005571e8c9SPieter Jansen van Vuuren 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
101a7cd39e0SPieter Jansen van Vuuren 	struct flow_dissector_key_eth_addrs *addr;
1025571e8c9SPieter Jansen van Vuuren 
1035571e8c9SPieter Jansen van Vuuren 	memset(frame, 0, sizeof(struct nfp_flower_mac_mpls));
1045571e8c9SPieter Jansen van Vuuren 
105a7cd39e0SPieter Jansen van Vuuren 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
106a7cd39e0SPieter Jansen van Vuuren 		addr = skb_flow_dissector_target(flow->dissector,
107a7cd39e0SPieter Jansen van Vuuren 						 FLOW_DISSECTOR_KEY_ETH_ADDRS,
108a7cd39e0SPieter Jansen van Vuuren 						 target);
1095571e8c9SPieter Jansen van Vuuren 		/* Populate mac frame. */
110a7cd39e0SPieter Jansen van Vuuren 		ether_addr_copy(frame->mac_dst, &addr->dst[0]);
111a7cd39e0SPieter Jansen van Vuuren 		ether_addr_copy(frame->mac_src, &addr->src[0]);
112a7cd39e0SPieter Jansen van Vuuren 	}
1135571e8c9SPieter Jansen van Vuuren 
1145571e8c9SPieter Jansen van Vuuren 	if (mask_version)
1155571e8c9SPieter Jansen van Vuuren 		frame->mpls_lse = cpu_to_be32(~0);
1165571e8c9SPieter Jansen van Vuuren }
1175571e8c9SPieter Jansen van Vuuren 
1185571e8c9SPieter Jansen van Vuuren static void
1195571e8c9SPieter Jansen van Vuuren nfp_flower_compile_tport(struct nfp_flower_tp_ports *frame,
1205571e8c9SPieter Jansen van Vuuren 			 struct tc_cls_flower_offload *flow,
1215571e8c9SPieter Jansen van Vuuren 			 bool mask_version)
1225571e8c9SPieter Jansen van Vuuren {
1235571e8c9SPieter Jansen van Vuuren 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
124a7cd39e0SPieter Jansen van Vuuren 	struct flow_dissector_key_ports *tp;
1255571e8c9SPieter Jansen van Vuuren 
126a7cd39e0SPieter Jansen van Vuuren 	memset(frame, 0, sizeof(struct nfp_flower_tp_ports));
127a7cd39e0SPieter Jansen van Vuuren 
128a7cd39e0SPieter Jansen van Vuuren 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
129a7cd39e0SPieter Jansen van Vuuren 		tp = skb_flow_dissector_target(flow->dissector,
1305571e8c9SPieter Jansen van Vuuren 					       FLOW_DISSECTOR_KEY_PORTS,
1315571e8c9SPieter Jansen van Vuuren 					       target);
132a7cd39e0SPieter Jansen van Vuuren 		frame->port_src = tp->src;
133a7cd39e0SPieter Jansen van Vuuren 		frame->port_dst = tp->dst;
134a7cd39e0SPieter Jansen van Vuuren 	}
1355571e8c9SPieter Jansen van Vuuren }
1365571e8c9SPieter Jansen van Vuuren 
1375571e8c9SPieter Jansen van Vuuren static void
1385571e8c9SPieter Jansen van Vuuren nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
1395571e8c9SPieter Jansen van Vuuren 			struct tc_cls_flower_offload *flow,
1405571e8c9SPieter Jansen van Vuuren 			bool mask_version)
1415571e8c9SPieter Jansen van Vuuren {
1425571e8c9SPieter Jansen van Vuuren 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
143a7cd39e0SPieter Jansen van Vuuren 	struct flow_dissector_key_ipv4_addrs *addr;
144a7cd39e0SPieter Jansen van Vuuren 	struct flow_dissector_key_basic *basic;
1455571e8c9SPieter Jansen van Vuuren 
146a7cd39e0SPieter Jansen van Vuuren 	/* Wildcard TOS/TTL for now. */
147a7cd39e0SPieter Jansen van Vuuren 	memset(frame, 0, sizeof(struct nfp_flower_ipv4));
148a7cd39e0SPieter Jansen van Vuuren 
149a7cd39e0SPieter Jansen van Vuuren 	if (dissector_uses_key(flow->dissector,
150a7cd39e0SPieter Jansen van Vuuren 			       FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
151a7cd39e0SPieter Jansen van Vuuren 		addr = skb_flow_dissector_target(flow->dissector,
1525571e8c9SPieter Jansen van Vuuren 						 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
1535571e8c9SPieter Jansen van Vuuren 						 target);
154a7cd39e0SPieter Jansen van Vuuren 		frame->ipv4_src = addr->src;
155a7cd39e0SPieter Jansen van Vuuren 		frame->ipv4_dst = addr->dst;
156a7cd39e0SPieter Jansen van Vuuren 	}
1575571e8c9SPieter Jansen van Vuuren 
158a7cd39e0SPieter Jansen van Vuuren 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
159a7cd39e0SPieter Jansen van Vuuren 		basic = skb_flow_dissector_target(flow->dissector,
1605571e8c9SPieter Jansen van Vuuren 						  FLOW_DISSECTOR_KEY_BASIC,
1615571e8c9SPieter Jansen van Vuuren 						  target);
162a7cd39e0SPieter Jansen van Vuuren 		frame->proto = basic->ip_proto;
163a7cd39e0SPieter Jansen van Vuuren 	}
1645571e8c9SPieter Jansen van Vuuren }
1655571e8c9SPieter Jansen van Vuuren 
1665571e8c9SPieter Jansen van Vuuren static void
1675571e8c9SPieter Jansen van Vuuren nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
1685571e8c9SPieter Jansen van Vuuren 			struct tc_cls_flower_offload *flow,
1695571e8c9SPieter Jansen van Vuuren 			bool mask_version)
1705571e8c9SPieter Jansen van Vuuren {
1715571e8c9SPieter Jansen van Vuuren 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
172a7cd39e0SPieter Jansen van Vuuren 	struct flow_dissector_key_ipv6_addrs *addr;
173a7cd39e0SPieter Jansen van Vuuren 	struct flow_dissector_key_basic *basic;
1745571e8c9SPieter Jansen van Vuuren 
175a7cd39e0SPieter Jansen van Vuuren 	/* Wildcard LABEL/TOS/TTL for now. */
176a7cd39e0SPieter Jansen van Vuuren 	memset(frame, 0, sizeof(struct nfp_flower_ipv6));
177a7cd39e0SPieter Jansen van Vuuren 
178a7cd39e0SPieter Jansen van Vuuren 	if (dissector_uses_key(flow->dissector,
179a7cd39e0SPieter Jansen van Vuuren 			       FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
180a7cd39e0SPieter Jansen van Vuuren 		addr = skb_flow_dissector_target(flow->dissector,
1815571e8c9SPieter Jansen van Vuuren 						 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
1825571e8c9SPieter Jansen van Vuuren 						 target);
183a7cd39e0SPieter Jansen van Vuuren 		frame->ipv6_src = addr->src;
184a7cd39e0SPieter Jansen van Vuuren 		frame->ipv6_dst = addr->dst;
185a7cd39e0SPieter Jansen van Vuuren 	}
1865571e8c9SPieter Jansen van Vuuren 
187a7cd39e0SPieter Jansen van Vuuren 	if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
188a7cd39e0SPieter Jansen van Vuuren 		basic = skb_flow_dissector_target(flow->dissector,
1895571e8c9SPieter Jansen van Vuuren 						  FLOW_DISSECTOR_KEY_BASIC,
1905571e8c9SPieter Jansen van Vuuren 						  target);
191a7cd39e0SPieter Jansen van Vuuren 		frame->proto = basic->ip_proto;
192a7cd39e0SPieter Jansen van Vuuren 	}
1935571e8c9SPieter Jansen van Vuuren }
1945571e8c9SPieter Jansen van Vuuren 
195611aec10SJohn Hurley static void
196611aec10SJohn Hurley nfp_flower_compile_vxlan(struct nfp_flower_vxlan *frame,
197611aec10SJohn Hurley 			 struct tc_cls_flower_offload *flow,
198611aec10SJohn Hurley 			 bool mask_version)
199611aec10SJohn Hurley {
200611aec10SJohn Hurley 	struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
201611aec10SJohn Hurley 	struct flow_dissector_key_ipv4_addrs *vxlan_ips;
202611aec10SJohn Hurley 	struct flow_dissector_key_keyid *vni;
203611aec10SJohn Hurley 
204611aec10SJohn Hurley 	/* Wildcard TOS/TTL/GPE_FLAGS/NXT_PROTO for now. */
205611aec10SJohn Hurley 	memset(frame, 0, sizeof(struct nfp_flower_vxlan));
206611aec10SJohn Hurley 
207611aec10SJohn Hurley 	if (dissector_uses_key(flow->dissector,
208611aec10SJohn Hurley 			       FLOW_DISSECTOR_KEY_ENC_KEYID)) {
209611aec10SJohn Hurley 		u32 temp_vni;
210611aec10SJohn Hurley 
211611aec10SJohn Hurley 		vni = skb_flow_dissector_target(flow->dissector,
212611aec10SJohn Hurley 						FLOW_DISSECTOR_KEY_ENC_KEYID,
213611aec10SJohn Hurley 						target);
214611aec10SJohn Hurley 		temp_vni = be32_to_cpu(vni->keyid) << NFP_FL_TUN_VNI_OFFSET;
215611aec10SJohn Hurley 		frame->tun_id = cpu_to_be32(temp_vni);
216611aec10SJohn Hurley 	}
217611aec10SJohn Hurley 
218611aec10SJohn Hurley 	if (dissector_uses_key(flow->dissector,
219611aec10SJohn Hurley 			       FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
220611aec10SJohn Hurley 		vxlan_ips =
221611aec10SJohn Hurley 		   skb_flow_dissector_target(flow->dissector,
222611aec10SJohn Hurley 					     FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
223611aec10SJohn Hurley 					     target);
224611aec10SJohn Hurley 		frame->ip_src = vxlan_ips->src;
225611aec10SJohn Hurley 		frame->ip_dst = vxlan_ips->dst;
226611aec10SJohn Hurley 	}
227611aec10SJohn Hurley }
228611aec10SJohn Hurley 
2295571e8c9SPieter Jansen van Vuuren int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,
2305571e8c9SPieter Jansen van Vuuren 				  struct nfp_fl_key_ls *key_ls,
2315571e8c9SPieter Jansen van Vuuren 				  struct net_device *netdev,
2325571e8c9SPieter Jansen van Vuuren 				  struct nfp_fl_payload *nfp_flow)
2335571e8c9SPieter Jansen van Vuuren {
234611aec10SJohn Hurley 	enum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE;
235fd0dd1abSJohn Hurley 	struct nfp_repr *netdev_repr;
2365571e8c9SPieter Jansen van Vuuren 	int err;
2375571e8c9SPieter Jansen van Vuuren 	u8 *ext;
2385571e8c9SPieter Jansen van Vuuren 	u8 *msk;
2395571e8c9SPieter Jansen van Vuuren 
240611aec10SJohn Hurley 	if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN)
241611aec10SJohn Hurley 		tun_type = NFP_FL_TUNNEL_VXLAN;
242611aec10SJohn Hurley 
2435571e8c9SPieter Jansen van Vuuren 	memset(nfp_flow->unmasked_data, 0, key_ls->key_size);
2445571e8c9SPieter Jansen van Vuuren 	memset(nfp_flow->mask_data, 0, key_ls->key_size);
2455571e8c9SPieter Jansen van Vuuren 
2465571e8c9SPieter Jansen van Vuuren 	ext = nfp_flow->unmasked_data;
2475571e8c9SPieter Jansen van Vuuren 	msk = nfp_flow->mask_data;
2485571e8c9SPieter Jansen van Vuuren 	if (NFP_FLOWER_LAYER_PORT & key_ls->key_layer) {
2495571e8c9SPieter Jansen van Vuuren 		/* Populate Exact Metadata. */
2505571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_meta_tci((struct nfp_flower_meta_two *)ext,
2515571e8c9SPieter Jansen van Vuuren 					    flow, key_ls->key_layer, false);
2525571e8c9SPieter Jansen van Vuuren 		/* Populate Mask Metadata. */
2535571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_meta_tci((struct nfp_flower_meta_two *)msk,
2545571e8c9SPieter Jansen van Vuuren 					    flow, key_ls->key_layer, true);
2555571e8c9SPieter Jansen van Vuuren 		ext += sizeof(struct nfp_flower_meta_two);
2565571e8c9SPieter Jansen van Vuuren 		msk += sizeof(struct nfp_flower_meta_two);
2575571e8c9SPieter Jansen van Vuuren 
2585571e8c9SPieter Jansen van Vuuren 		/* Populate Exact Port data. */
2595571e8c9SPieter Jansen van Vuuren 		err = nfp_flower_compile_port((struct nfp_flower_in_port *)ext,
2605571e8c9SPieter Jansen van Vuuren 					      nfp_repr_get_port_id(netdev),
261611aec10SJohn Hurley 					      false, tun_type);
2625571e8c9SPieter Jansen van Vuuren 		if (err)
2635571e8c9SPieter Jansen van Vuuren 			return err;
2645571e8c9SPieter Jansen van Vuuren 
2655571e8c9SPieter Jansen van Vuuren 		/* Populate Mask Port Data. */
2665571e8c9SPieter Jansen van Vuuren 		err = nfp_flower_compile_port((struct nfp_flower_in_port *)msk,
2675571e8c9SPieter Jansen van Vuuren 					      nfp_repr_get_port_id(netdev),
268611aec10SJohn Hurley 					      true, tun_type);
2695571e8c9SPieter Jansen van Vuuren 		if (err)
2705571e8c9SPieter Jansen van Vuuren 			return err;
2715571e8c9SPieter Jansen van Vuuren 
2725571e8c9SPieter Jansen van Vuuren 		ext += sizeof(struct nfp_flower_in_port);
2735571e8c9SPieter Jansen van Vuuren 		msk += sizeof(struct nfp_flower_in_port);
2745571e8c9SPieter Jansen van Vuuren 	} else {
2755571e8c9SPieter Jansen van Vuuren 		/* Populate Exact Metadata. */
2765571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_meta((struct nfp_flower_meta_one *)ext,
2775571e8c9SPieter Jansen van Vuuren 					key_ls->key_layer);
2785571e8c9SPieter Jansen van Vuuren 		/* Populate Mask Metadata. */
2795571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_meta((struct nfp_flower_meta_one *)msk,
2805571e8c9SPieter Jansen van Vuuren 					key_ls->key_layer);
2815571e8c9SPieter Jansen van Vuuren 		ext += sizeof(struct nfp_flower_meta_one);
2825571e8c9SPieter Jansen van Vuuren 		msk += sizeof(struct nfp_flower_meta_one);
2835571e8c9SPieter Jansen van Vuuren 	}
2845571e8c9SPieter Jansen van Vuuren 
2855571e8c9SPieter Jansen van Vuuren 	if (NFP_FLOWER_LAYER_META & key_ls->key_layer) {
2865571e8c9SPieter Jansen van Vuuren 		/* Additional Metadata Fields.
2875571e8c9SPieter Jansen van Vuuren 		 * Currently unsupported.
2885571e8c9SPieter Jansen van Vuuren 		 */
2895571e8c9SPieter Jansen van Vuuren 		return -EOPNOTSUPP;
2905571e8c9SPieter Jansen van Vuuren 	}
2915571e8c9SPieter Jansen van Vuuren 
2925571e8c9SPieter Jansen van Vuuren 	if (NFP_FLOWER_LAYER_MAC & key_ls->key_layer) {
2935571e8c9SPieter Jansen van Vuuren 		/* Populate Exact MAC Data. */
2945571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)ext,
2955571e8c9SPieter Jansen van Vuuren 				       flow, false);
2965571e8c9SPieter Jansen van Vuuren 		/* Populate Mask MAC Data. */
2975571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)msk,
2985571e8c9SPieter Jansen van Vuuren 				       flow, true);
2995571e8c9SPieter Jansen van Vuuren 		ext += sizeof(struct nfp_flower_mac_mpls);
3005571e8c9SPieter Jansen van Vuuren 		msk += sizeof(struct nfp_flower_mac_mpls);
3015571e8c9SPieter Jansen van Vuuren 	}
3025571e8c9SPieter Jansen van Vuuren 
3035571e8c9SPieter Jansen van Vuuren 	if (NFP_FLOWER_LAYER_TP & key_ls->key_layer) {
3045571e8c9SPieter Jansen van Vuuren 		/* Populate Exact TP Data. */
3055571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_tport((struct nfp_flower_tp_ports *)ext,
3065571e8c9SPieter Jansen van Vuuren 					 flow, false);
3075571e8c9SPieter Jansen van Vuuren 		/* Populate Mask TP Data. */
3085571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_tport((struct nfp_flower_tp_ports *)msk,
3095571e8c9SPieter Jansen van Vuuren 					 flow, true);
3105571e8c9SPieter Jansen van Vuuren 		ext += sizeof(struct nfp_flower_tp_ports);
3115571e8c9SPieter Jansen van Vuuren 		msk += sizeof(struct nfp_flower_tp_ports);
3125571e8c9SPieter Jansen van Vuuren 	}
3135571e8c9SPieter Jansen van Vuuren 
3145571e8c9SPieter Jansen van Vuuren 	if (NFP_FLOWER_LAYER_IPV4 & key_ls->key_layer) {
3155571e8c9SPieter Jansen van Vuuren 		/* Populate Exact IPv4 Data. */
3165571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)ext,
3175571e8c9SPieter Jansen van Vuuren 					flow, false);
3185571e8c9SPieter Jansen van Vuuren 		/* Populate Mask IPv4 Data. */
3195571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)msk,
3205571e8c9SPieter Jansen van Vuuren 					flow, true);
3215571e8c9SPieter Jansen van Vuuren 		ext += sizeof(struct nfp_flower_ipv4);
3225571e8c9SPieter Jansen van Vuuren 		msk += sizeof(struct nfp_flower_ipv4);
3235571e8c9SPieter Jansen van Vuuren 	}
3245571e8c9SPieter Jansen van Vuuren 
3255571e8c9SPieter Jansen van Vuuren 	if (NFP_FLOWER_LAYER_IPV6 & key_ls->key_layer) {
3265571e8c9SPieter Jansen van Vuuren 		/* Populate Exact IPv4 Data. */
3275571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)ext,
3285571e8c9SPieter Jansen van Vuuren 					flow, false);
3295571e8c9SPieter Jansen van Vuuren 		/* Populate Mask IPv4 Data. */
3305571e8c9SPieter Jansen van Vuuren 		nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)msk,
3315571e8c9SPieter Jansen van Vuuren 					flow, true);
3325571e8c9SPieter Jansen van Vuuren 		ext += sizeof(struct nfp_flower_ipv6);
3335571e8c9SPieter Jansen van Vuuren 		msk += sizeof(struct nfp_flower_ipv6);
3345571e8c9SPieter Jansen van Vuuren 	}
3355571e8c9SPieter Jansen van Vuuren 
336611aec10SJohn Hurley 	if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN) {
337611aec10SJohn Hurley 		/* Populate Exact VXLAN Data. */
338611aec10SJohn Hurley 		nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)ext,
339611aec10SJohn Hurley 					 flow, false);
340611aec10SJohn Hurley 		/* Populate Mask VXLAN Data. */
341611aec10SJohn Hurley 		nfp_flower_compile_vxlan((struct nfp_flower_vxlan *)msk,
342611aec10SJohn Hurley 					 flow, true);
343611aec10SJohn Hurley 		ext += sizeof(struct nfp_flower_vxlan);
344611aec10SJohn Hurley 		msk += sizeof(struct nfp_flower_vxlan);
345fd0dd1abSJohn Hurley 
346fd0dd1abSJohn Hurley 		/* Configure tunnel end point MAC. */
347fd0dd1abSJohn Hurley 		if (nfp_netdev_is_nfp_repr(netdev)) {
348fd0dd1abSJohn Hurley 			netdev_repr = netdev_priv(netdev);
349fd0dd1abSJohn Hurley 			nfp_tunnel_write_macs(netdev_repr->app);
350fd0dd1abSJohn Hurley 		}
351611aec10SJohn Hurley 	}
352611aec10SJohn Hurley 
3535571e8c9SPieter Jansen van Vuuren 	return 0;
3545571e8c9SPieter Jansen van Vuuren }
355