4d4f7c4eaff66d6be12a498c9f272f50947c8598
[dpdk.git] / drivers / net / bnxt / tf_ulp / ulp_def_rules.c
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, ulp_flags = 0;
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         /* update the vf rep flag */
333         if (bnxt_ulp_cntxt_ptr2_ulp_flags_get(ulp_ctx, &ulp_flags)) {
334                 BNXT_TF_DBG(ERR, "Error in getting ULP context flags\n");
335                 return -EINVAL;
336         }
337         if (ULP_VF_REP_IS_ENABLED(ulp_flags))
338                 ULP_COMP_FLD_IDX_WR(&mapper_params,
339                                     BNXT_ULP_CF_IDX_VFR_MODE, 1);
340
341         type = param_list->type;
342         while (type != BNXT_ULP_DF_PARAM_TYPE_LAST) {
343                 if (ulp_def_handler_tbl[type].vfr_func) {
344                         rc = ulp_def_handler_tbl[type].vfr_func(ulp_ctx,
345                                                                 param_list,
346                                                                 &mapper_params);
347                         if (rc) {
348                                 BNXT_TF_DBG(ERR,
349                                             "Failed to create default flow.\n");
350                                 return rc;
351                         }
352                 }
353
354                 param_list++;
355                 type = param_list->type;
356         }
357
358         mapper_params.class_tid = ulp_class_tid;
359
360         rc = ulp_mapper_flow_create(ulp_ctx, &mapper_params, flow_id);
361         if (rc) {
362                 BNXT_TF_DBG(ERR, "Failed to create default flow.\n");
363                 return rc;
364         }
365
366         return 0;
367 }
368
369 /*
370  * Function to destroy default rules for the following paths
371  * 1) Device PORT to DPDK App
372  * 2) DPDK App to Device PORT
373  * 3) VF Representor to VF
374  * 4) VF to VF Representor
375  *
376  * eth_dev [in] Ptr to rte eth device.
377  * flow_id [in] Flow identifier.
378  *
379  * Returns 0 on success or negative number on failure.
380  */
381 int32_t
382 ulp_default_flow_destroy(struct rte_eth_dev *eth_dev, uint32_t flow_id)
383 {
384         struct bnxt_ulp_context *ulp_ctx;
385         int rc;
386
387         ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
388         if (!ulp_ctx) {
389                 BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
390                 return -EINVAL;
391         }
392
393         rc = ulp_mapper_flow_destroy(ulp_ctx, flow_id,
394                                      BNXT_ULP_DEFAULT_FLOW_TABLE);
395         if (rc)
396                 BNXT_TF_DBG(ERR, "Failed to destroy flow.\n");
397
398         return rc;
399 }