xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_def_rules.c (revision cfe4ca10)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 Broadcom
3  * All rights reserved.
4  */
5 
6 #include "bnxt_tf_common.h"
7 #include "ulp_template_struct.h"
8 #include "ulp_template_db_enum.h"
9 #include "ulp_template_db_field.h"
10 #include "ulp_utils.h"
11 #include "ulp_port_db.h"
12 #include "ulp_flow_db.h"
13 #include "ulp_mapper.h"
14 
15 #define BNXT_ULP_FREE_PARIF_BASE 11
16 
17 struct bnxt_ulp_def_param_handler {
18 	int32_t (*vfr_func)(struct bnxt_ulp_context *ulp_ctx,
19 			    struct ulp_tlv_param *param,
20 			    struct bnxt_ulp_mapper_create_parms *mapper_params);
21 };
22 
23 static int32_t
24 ulp_set_svif_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
25 			 uint32_t  ifindex, uint8_t svif_type,
26 			 struct bnxt_ulp_mapper_create_parms *mapper_params)
27 {
28 	uint16_t svif;
29 	uint8_t idx;
30 	int rc;
31 
32 	rc = ulp_port_db_svif_get(ulp_ctx, ifindex, svif_type, &svif);
33 	if (rc)
34 		return rc;
35 
36 	if (svif_type == BNXT_ULP_PHY_PORT_SVIF)
37 		idx = BNXT_ULP_CF_IDX_PHY_PORT_SVIF;
38 	else if (svif_type == BNXT_ULP_DRV_FUNC_SVIF)
39 		idx = BNXT_ULP_CF_IDX_DRV_FUNC_SVIF;
40 	else
41 		idx = BNXT_ULP_CF_IDX_VF_FUNC_SVIF;
42 
43 	ULP_COMP_FLD_IDX_WR(mapper_params, idx, svif);
44 
45 	return 0;
46 }
47 
48 static int32_t
49 ulp_set_spif_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
50 			 uint32_t  ifindex, uint8_t spif_type,
51 			 struct bnxt_ulp_mapper_create_parms *mapper_params)
52 {
53 	uint16_t spif;
54 	uint8_t idx;
55 	int rc;
56 
57 	rc = ulp_port_db_spif_get(ulp_ctx, ifindex, spif_type, &spif);
58 	if (rc)
59 		return rc;
60 
61 	if (spif_type == BNXT_ULP_PHY_PORT_SPIF)
62 		idx = BNXT_ULP_CF_IDX_PHY_PORT_SPIF;
63 	else if (spif_type == BNXT_ULP_DRV_FUNC_SPIF)
64 		idx = BNXT_ULP_CF_IDX_DRV_FUNC_SPIF;
65 	else
66 		idx = BNXT_ULP_CF_IDX_VF_FUNC_SPIF;
67 
68 	ULP_COMP_FLD_IDX_WR(mapper_params, idx, spif);
69 
70 	return 0;
71 }
72 
73 static int32_t
74 ulp_set_parif_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
75 			  uint32_t  ifindex, uint8_t parif_type,
76 			  struct bnxt_ulp_mapper_create_parms *mapper_params)
77 {
78 	uint16_t parif;
79 	uint8_t idx;
80 	int rc;
81 
82 	rc = ulp_port_db_parif_get(ulp_ctx, ifindex, parif_type, &parif);
83 	if (rc)
84 		return rc;
85 
86 	if (parif_type == BNXT_ULP_PHY_PORT_PARIF) {
87 		idx = BNXT_ULP_CF_IDX_PHY_PORT_PARIF;
88 	} else if (parif_type == BNXT_ULP_DRV_FUNC_PARIF) {
89 		idx = BNXT_ULP_CF_IDX_DRV_FUNC_PARIF;
90 		/* Parif needs to be reset to a free partition */
91 		parif += BNXT_ULP_FREE_PARIF_BASE;
92 	} else {
93 		idx = BNXT_ULP_CF_IDX_VF_FUNC_PARIF;
94 	}
95 
96 	ULP_COMP_FLD_IDX_WR(mapper_params, idx, parif);
97 
98 	return 0;
99 }
100 
101 static int32_t
102 ulp_set_vport_in_comp_fld(struct bnxt_ulp_context *ulp_ctx, uint32_t ifindex,
103 			  struct bnxt_ulp_mapper_create_parms *mapper_params)
104 {
105 	uint16_t vport;
106 	int rc;
107 
108 	rc = ulp_port_db_vport_get(ulp_ctx, ifindex, &vport);
109 	if (rc)
110 		return rc;
111 
112 	ULP_COMP_FLD_IDX_WR(mapper_params, BNXT_ULP_CF_IDX_PHY_PORT_VPORT,
113 			    vport);
114 	return 0;
115 }
116 
117 static int32_t
118 ulp_set_vnic_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
119 			 uint32_t  ifindex, uint8_t vnic_type,
120 			 struct bnxt_ulp_mapper_create_parms *mapper_params)
121 {
122 	uint16_t vnic;
123 	uint8_t idx;
124 	int rc;
125 
126 	rc = ulp_port_db_default_vnic_get(ulp_ctx, ifindex, vnic_type, &vnic);
127 	if (rc)
128 		return rc;
129 
130 	if (vnic_type == BNXT_ULP_DRV_FUNC_VNIC)
131 		idx = BNXT_ULP_CF_IDX_DRV_FUNC_VNIC;
132 	else
133 		idx = BNXT_ULP_CF_IDX_VF_FUNC_VNIC;
134 
135 	ULP_COMP_FLD_IDX_WR(mapper_params, idx, vnic);
136 
137 	return 0;
138 }
139 
140 static int32_t
141 ulp_set_vlan_in_act_prop(uint16_t port_id,
142 			 struct bnxt_ulp_mapper_create_parms *mapper_params)
143 {
144 	struct ulp_rte_act_prop *act_prop = mapper_params->act_prop;
145 
146 	if (ULP_BITMAP_ISSET(mapper_params->act->bits,
147 			     BNXT_ULP_ACTION_BIT_SET_VLAN_VID)) {
148 		BNXT_TF_DBG(ERR,
149 			    "VLAN already set, multiple VLANs unsupported\n");
150 		return BNXT_TF_RC_ERROR;
151 	}
152 
153 	port_id = rte_cpu_to_be_16(port_id);
154 
155 	ULP_BITMAP_SET(mapper_params->act->bits,
156 		       BNXT_ULP_ACTION_BIT_SET_VLAN_VID);
157 
158 	memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG],
159 	       &port_id, sizeof(port_id));
160 
161 	return 0;
162 }
163 
164 static int32_t
165 ulp_set_mark_in_act_prop(uint16_t port_id,
166 			 struct bnxt_ulp_mapper_create_parms *mapper_params)
167 {
168 	if (ULP_BITMAP_ISSET(mapper_params->act->bits,
169 			     BNXT_ULP_ACTION_BIT_MARK)) {
170 		BNXT_TF_DBG(ERR,
171 			    "MARK already set, multiple MARKs unsupported\n");
172 		return BNXT_TF_RC_ERROR;
173 	}
174 
175 	ULP_COMP_FLD_IDX_WR(mapper_params, BNXT_ULP_CF_IDX_DEV_PORT_ID,
176 			    port_id);
177 
178 	return 0;
179 }
180 
181 static int32_t
182 ulp_df_dev_port_handler(struct bnxt_ulp_context *ulp_ctx,
183 			struct ulp_tlv_param *param,
184 			struct bnxt_ulp_mapper_create_parms *mapper_params)
185 {
186 	uint16_t port_id;
187 	uint32_t ifindex;
188 	int rc;
189 
190 	port_id = param->value[0] | param->value[1];
191 
192 	rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctx, port_id, &ifindex);
193 	if (rc) {
194 		BNXT_TF_DBG(ERR,
195 				"Invalid port id\n");
196 		return BNXT_TF_RC_ERROR;
197 	}
198 
199 	/* Set port SVIF */
200 	rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_PHY_PORT_SVIF,
201 				      mapper_params);
202 	if (rc)
203 		return rc;
204 
205 	/* Set DRV Func SVIF */
206 	rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SVIF,
207 				      mapper_params);
208 	if (rc)
209 		return rc;
210 
211 	/* Set VF Func SVIF */
212 	rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_VF_FUNC_SVIF,
213 				      mapper_params);
214 	if (rc)
215 		return rc;
216 
217 	/* Set port SPIF */
218 	rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_PHY_PORT_SPIF,
219 				      mapper_params);
220 	if (rc)
221 		return rc;
222 
223 	/* Set DRV Func SPIF */
224 	rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SPIF,
225 				      mapper_params);
226 	if (rc)
227 		return rc;
228 
229 	/* Set VF Func SPIF */
230 	rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SPIF,
231 				      mapper_params);
232 	if (rc)
233 		return rc;
234 
235 	/* Set port PARIF */
236 	rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex,
237 				       BNXT_ULP_PHY_PORT_PARIF, mapper_params);
238 	if (rc)
239 		return rc;
240 
241 	/* Set DRV Func PARIF */
242 	rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex,
243 				       BNXT_ULP_DRV_FUNC_PARIF, mapper_params);
244 	if (rc)
245 		return rc;
246 
247 	/* Set VF Func PARIF */
248 	rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_VF_FUNC_PARIF,
249 				       mapper_params);
250 	if (rc)
251 		return rc;
252 
253 	/* Set uplink VNIC */
254 	rc = ulp_set_vnic_in_comp_fld(ulp_ctx, ifindex, true, mapper_params);
255 	if (rc)
256 		return rc;
257 
258 	/* Set VF VNIC */
259 	rc = ulp_set_vnic_in_comp_fld(ulp_ctx, ifindex, false, mapper_params);
260 	if (rc)
261 		return rc;
262 
263 	/* Set VPORT */
264 	rc = ulp_set_vport_in_comp_fld(ulp_ctx, ifindex, mapper_params);
265 	if (rc)
266 		return rc;
267 
268 	/* Set VLAN */
269 	rc = ulp_set_vlan_in_act_prop(port_id, mapper_params);
270 	if (rc)
271 		return rc;
272 
273 	/* Set MARK */
274 	rc = ulp_set_mark_in_act_prop(port_id, mapper_params);
275 	if (rc)
276 		return rc;
277 
278 	return 0;
279 }
280 
281 struct bnxt_ulp_def_param_handler ulp_def_handler_tbl[] = {
282 	[BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID] = {
283 			.vfr_func = ulp_df_dev_port_handler }
284 };
285 
286 /*
287  * Function to create default rules for the following paths
288  * 1) Device PORT to DPDK App
289  * 2) DPDK App to Device PORT
290  * 3) VF Representor to VF
291  * 4) VF to VF Representor
292  *
293  * eth_dev [in] Ptr to rte eth device.
294  * param_list [in] Ptr to a list of parameters (Currently, only DPDK port_id).
295  * ulp_class_tid [in] Class template ID number.
296  * flow_id [out] Ptr to flow identifier.
297  *
298  * Returns 0 on success or negative number on failure.
299  */
300 int32_t
301 ulp_default_flow_create(struct rte_eth_dev *eth_dev,
302 			struct ulp_tlv_param *param_list,
303 			uint32_t ulp_class_tid,
304 			uint32_t *flow_id)
305 {
306 	struct ulp_rte_hdr_field	hdr_field[BNXT_ULP_PROTO_HDR_MAX];
307 	uint32_t			comp_fld[BNXT_ULP_CF_IDX_LAST];
308 	struct bnxt_ulp_mapper_create_parms mapper_params = { 0 };
309 	struct ulp_rte_act_prop		act_prop;
310 	struct ulp_rte_act_bitmap	act = { 0 };
311 	struct bnxt_ulp_context		*ulp_ctx;
312 	uint32_t type;
313 	int rc;
314 
315 	memset(&mapper_params, 0, sizeof(mapper_params));
316 	memset(hdr_field, 0, sizeof(hdr_field));
317 	memset(comp_fld, 0, sizeof(comp_fld));
318 	memset(&act_prop, 0, sizeof(act_prop));
319 
320 	mapper_params.hdr_field = hdr_field;
321 	mapper_params.act = &act;
322 	mapper_params.act_prop = &act_prop;
323 	mapper_params.comp_fld = comp_fld;
324 
325 	ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
326 	if (!ulp_ctx) {
327 		BNXT_TF_DBG(ERR, "ULP context is not initialized. "
328 				 "Failed to create default flow.\n");
329 		return -EINVAL;
330 	}
331 
332 	type = param_list->type;
333 	while (type != BNXT_ULP_DF_PARAM_TYPE_LAST) {
334 		if (ulp_def_handler_tbl[type].vfr_func) {
335 			rc = ulp_def_handler_tbl[type].vfr_func(ulp_ctx,
336 								param_list,
337 								&mapper_params);
338 			if (rc) {
339 				BNXT_TF_DBG(ERR,
340 					    "Failed to create default flow.\n");
341 				return rc;
342 			}
343 		}
344 
345 		param_list++;
346 		type = param_list->type;
347 	}
348 
349 	mapper_params.class_tid = ulp_class_tid;
350 
351 	rc = ulp_mapper_flow_create(ulp_ctx, &mapper_params, flow_id);
352 	if (rc) {
353 		BNXT_TF_DBG(ERR, "Failed to create default flow.\n");
354 		return rc;
355 	}
356 
357 	return 0;
358 }
359 
360 /*
361  * Function to destroy default rules for the following paths
362  * 1) Device PORT to DPDK App
363  * 2) DPDK App to Device PORT
364  * 3) VF Representor to VF
365  * 4) VF to VF Representor
366  *
367  * eth_dev [in] Ptr to rte eth device.
368  * flow_id [in] Flow identifier.
369  *
370  * Returns 0 on success or negative number on failure.
371  */
372 int32_t
373 ulp_default_flow_destroy(struct rte_eth_dev *eth_dev, uint32_t flow_id)
374 {
375 	struct bnxt_ulp_context *ulp_ctx;
376 	int rc;
377 
378 	ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
379 	if (!ulp_ctx) {
380 		BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
381 		return -EINVAL;
382 	}
383 
384 	rc = ulp_mapper_flow_destroy(ulp_ctx, flow_id,
385 				     BNXT_ULP_DEFAULT_FLOW_TABLE);
386 	if (rc)
387 		BNXT_TF_DBG(ERR, "Failed to destroy flow.\n");
388 
389 	return rc;
390 }
391