1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2017-2021 NXP
3 */
4
5 /* System headers */
6 #include <stdio.h>
7 #include <inttypes.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10
11 #include <dpaa_ethdev.h>
12 #include <dpaa_flow.h>
13 #include <rte_dpaa_logs.h>
14 #include <fmlib/fm_port_ext.h>
15 #include <fmlib/fm_vsp_ext.h>
16
17 #define FMC_OUTPUT_FORMAT_VER 0x106
18
19 #define FMC_NAME_LEN 64
20 #define FMC_FMAN_NUM 2
21 #define FMC_PORTS_PER_FMAN 16
22 #define FMC_SCHEMES_NUM 32
23 #define FMC_SCHEME_PROTOCOLS_NUM 16
24 #define FMC_CC_NODES_NUM 512
25 #define FMC_REPLICATORS_NUM 16
26 #define FMC_PLC_NUM 64
27 #define MAX_SP_CODE_SIZE 0x7C0
28 #define FMC_MANIP_MAX 64
29 #define FMC_HMANIP_MAX 512
30 #define FMC_INSERT_MAX 56
31 #define FM_PCD_MAX_REPS 64
32
33 typedef struct fmc_port_t {
34 e_fm_port_type type;
35 unsigned int number;
36 struct fm_pcd_net_env_params_t distinction_units;
37 struct ioc_fm_port_pcd_params_t pcd_param;
38 struct ioc_fm_port_pcd_prs_params_t prs_param;
39 struct ioc_fm_port_pcd_kg_params_t kg_param;
40 struct ioc_fm_port_pcd_cc_params_t cc_param;
41 char name[FMC_NAME_LEN];
42 char cctree_name[FMC_NAME_LEN];
43 t_handle handle;
44 t_handle env_id_handle;
45 t_handle env_id_dev_id;
46 t_handle cctree_handle;
47 t_handle cctree_dev_id;
48
49 unsigned int schemes_count;
50 unsigned int schemes[FMC_SCHEMES_NUM];
51 unsigned int ccnodes_count;
52 unsigned int ccnodes[FMC_CC_NODES_NUM];
53 unsigned int htnodes_count;
54 unsigned int htnodes[FMC_CC_NODES_NUM];
55
56 unsigned int replicators_count;
57 unsigned int replicators[FMC_REPLICATORS_NUM];
58 ioc_fm_port_vsp_alloc_params_t vsp_param;
59
60 unsigned int ccroot_count;
61 unsigned int ccroot[FMC_CC_NODES_NUM];
62 enum ioc_fm_pcd_engine ccroot_type[FMC_CC_NODES_NUM];
63 unsigned int ccroot_manip[FMC_CC_NODES_NUM];
64
65 unsigned int reasm_index;
66 } fmc_port;
67
68 typedef struct fmc_fman_t {
69 unsigned int number;
70 unsigned int port_count;
71 unsigned int ports[FMC_PORTS_PER_FMAN];
72 char name[FMC_NAME_LEN];
73 t_handle handle;
74 char pcd_name[FMC_NAME_LEN];
75 t_handle pcd_handle;
76 unsigned int kg_payload_offset;
77
78 unsigned int offload_support;
79
80 unsigned int reasm_count;
81 struct fm_pcd_manip_params_t reasm[FMC_MANIP_MAX];
82 char reasm_name[FMC_MANIP_MAX][FMC_NAME_LEN];
83 t_handle reasm_handle[FMC_MANIP_MAX];
84 t_handle reasm_dev_id[FMC_MANIP_MAX];
85
86 unsigned int frag_count;
87 struct fm_pcd_manip_params_t frag[FMC_MANIP_MAX];
88 char frag_name[FMC_MANIP_MAX][FMC_NAME_LEN];
89 t_handle frag_handle[FMC_MANIP_MAX];
90 t_handle frag_dev_id[FMC_MANIP_MAX];
91
92 unsigned int hdr_count;
93 struct fm_pcd_manip_params_t hdr[FMC_HMANIP_MAX];
94 uint8_t insert_data[FMC_HMANIP_MAX][FMC_INSERT_MAX];
95 char hdr_name[FMC_HMANIP_MAX][FMC_NAME_LEN];
96 t_handle hdr_handle[FMC_HMANIP_MAX];
97 t_handle hdr_dev_id[FMC_HMANIP_MAX];
98 unsigned int hdr_has_next[FMC_HMANIP_MAX];
99 unsigned int hdr_next[FMC_HMANIP_MAX];
100 } fmc_fman;
101
102 typedef enum fmc_apply_order_e {
103 fmcengine_start,
104 fmcengine_end,
105 fmcport_start,
106 fmcport_end,
107 fmcscheme,
108 fmcccnode,
109 fmchtnode,
110 fmccctree,
111 fmcpolicer,
112 fmcreplicator,
113 fmcmanipulation
114 } fmc_apply_order_e;
115
116 typedef struct fmc_apply_order_t {
117 fmc_apply_order_e type;
118 unsigned int index;
119 } fmc_apply_order;
120
121 struct fmc_model_t {
122 unsigned int format_version;
123 unsigned int sp_enable;
124 t_fm_pcd_prs_sw_params sp;
125 uint8_t spcode[MAX_SP_CODE_SIZE];
126
127 unsigned int fman_count;
128 fmc_fman fman[FMC_FMAN_NUM];
129
130 unsigned int port_count;
131 fmc_port port[FMC_FMAN_NUM * FMC_PORTS_PER_FMAN];
132
133 unsigned int scheme_count;
134 char scheme_name[FMC_SCHEMES_NUM][FMC_NAME_LEN];
135 t_handle scheme_handle[FMC_SCHEMES_NUM];
136 t_handle scheme_dev_id[FMC_SCHEMES_NUM];
137 struct fm_pcd_kg_scheme_params_t scheme[FMC_SCHEMES_NUM];
138
139 unsigned int ccnode_count;
140 char ccnode_name[FMC_CC_NODES_NUM][FMC_NAME_LEN];
141 t_handle ccnode_handle[FMC_CC_NODES_NUM];
142 t_handle ccnode_dev_id[FMC_CC_NODES_NUM];
143 struct fm_pcd_cc_node_params_t ccnode[FMC_CC_NODES_NUM];
144 uint8_t cckeydata[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]
145 [FM_PCD_MAX_SIZE_OF_KEY];
146 unsigned char ccmask[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]
147 [FM_PCD_MAX_SIZE_OF_KEY];
148 unsigned int
149 ccentry_action_index[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
150 enum ioc_fm_pcd_engine
151 ccentry_action_type[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
152 unsigned char ccentry_frag[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
153 unsigned int ccentry_manip[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
154 unsigned int ccmiss_action_index[FMC_CC_NODES_NUM];
155 enum ioc_fm_pcd_engine ccmiss_action_type[FMC_CC_NODES_NUM];
156 unsigned char ccmiss_frag[FMC_CC_NODES_NUM];
157 unsigned int ccmiss_manip[FMC_CC_NODES_NUM];
158
159 unsigned int htnode_count;
160 char htnode_name[FMC_CC_NODES_NUM][FMC_NAME_LEN];
161 t_handle htnode_handle[FMC_CC_NODES_NUM];
162 t_handle htnode_dev_id[FMC_CC_NODES_NUM];
163 struct fm_pcd_hash_table_params_t htnode[FMC_CC_NODES_NUM];
164
165 unsigned int htentry_count[FMC_CC_NODES_NUM];
166 struct ioc_fm_pcd_cc_key_params_t
167 htentry[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
168 uint8_t htkeydata[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]
169 [FM_PCD_MAX_SIZE_OF_KEY];
170 unsigned int
171 htentry_action_index[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
172 enum ioc_fm_pcd_engine
173 htentry_action_type[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
174 unsigned char htentry_frag[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
175 unsigned int htentry_manip[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
176
177 unsigned int htmiss_action_index[FMC_CC_NODES_NUM];
178 enum ioc_fm_pcd_engine htmiss_action_type[FMC_CC_NODES_NUM];
179 unsigned char htmiss_frag[FMC_CC_NODES_NUM];
180 unsigned int htmiss_manip[FMC_CC_NODES_NUM];
181
182 unsigned int replicator_count;
183 char replicator_name[FMC_REPLICATORS_NUM][FMC_NAME_LEN];
184 t_handle replicator_handle[FMC_REPLICATORS_NUM];
185 t_handle replicator_dev_id[FMC_REPLICATORS_NUM];
186 struct fm_pcd_frm_replic_group_params_t replicator[FMC_REPLICATORS_NUM];
187 unsigned int
188 repentry_action_index[FMC_REPLICATORS_NUM][FM_PCD_MAX_REPS];
189 unsigned char repentry_frag[FMC_REPLICATORS_NUM][FM_PCD_MAX_REPS];
190 unsigned int repentry_manip[FMC_REPLICATORS_NUM][FM_PCD_MAX_REPS];
191
192 unsigned int policer_count;
193 char policer_name[FMC_PLC_NUM][FMC_NAME_LEN];
194 struct fm_pcd_plcr_profile_params_t policer[FMC_PLC_NUM];
195 t_handle policer_handle[FMC_PLC_NUM];
196 t_handle policer_dev_id[FMC_PLC_NUM];
197 unsigned int policer_action_index[FMC_PLC_NUM][3];
198
199 unsigned int apply_order_count;
200 fmc_apply_order apply_order[FMC_FMAN_NUM *
201 FMC_PORTS_PER_FMAN *
202 (FMC_SCHEMES_NUM + FMC_CC_NODES_NUM)];
203 };
204
205 struct fmc_model_t *g_fmc_model;
206
dpaa_port_fmc_port_parse(struct fman_if * fif,const struct fmc_model_t * fmc_model,int apply_idx)207 static int dpaa_port_fmc_port_parse(struct fman_if *fif,
208 const struct fmc_model_t *fmc_model,
209 int apply_idx)
210 {
211 int current_port = fmc_model->apply_order[apply_idx].index;
212 const fmc_port *pport = &fmc_model->port[current_port];
213 const uint8_t mac_idx[] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1};
214 const uint8_t mac_type[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
215
216 if (mac_idx[fif->mac_idx] != pport->number ||
217 mac_type[fif->mac_idx] != pport->type)
218 return -1;
219
220 return current_port;
221 }
222
dpaa_port_fmc_scheme_parse(struct fman_if * fif,const struct fmc_model_t * fmc,int apply_idx,uint16_t * rxq_idx,int max_nb_rxq,uint32_t * fqids,int8_t * vspids)223 static int dpaa_port_fmc_scheme_parse(struct fman_if *fif,
224 const struct fmc_model_t *fmc,
225 int apply_idx,
226 uint16_t *rxq_idx, int max_nb_rxq,
227 uint32_t *fqids, int8_t *vspids)
228 {
229 int idx = fmc->apply_order[apply_idx].index;
230 uint32_t i;
231
232 if (!fmc->scheme[idx].override_storage_profile &&
233 fif->is_shared_mac) {
234 DPAA_PMD_WARN("No VSP assigned to scheme %d for sharemac %d!",
235 idx, fif->mac_idx);
236 DPAA_PMD_WARN("Risk to receive pkts from skb pool to CRASH!");
237 }
238
239 if (e_IOC_FM_PCD_DONE ==
240 fmc->scheme[idx].next_engine) {
241 for (i = 0; i < fmc->scheme[idx]
242 .key_ext_and_hash.hash_dist_num_of_fqids; i++) {
243 uint32_t fqid = fmc->scheme[idx].base_fqid + i;
244 int k, found = 0;
245
246 if (fqid == fif->fqid_rx_def ||
247 (fqid >= fif->fqid_rx_pcd &&
248 fqid < (fif->fqid_rx_pcd +
249 fif->fqid_rx_pcd_count))) {
250 if (fif->is_shared_mac &&
251 fmc->scheme[idx].override_storage_profile &&
252 fmc->scheme[idx].storage_profile.direct &&
253 fmc->scheme[idx].storage_profile
254 .profile_select.direct_relative_profile_id !=
255 fif->base_profile_id) {
256 DPAA_PMD_ERR("Def RXQ must be associated with def VSP on sharemac!");
257
258 return -1;
259 }
260 continue;
261 }
262
263 if (fif->is_shared_mac &&
264 !fmc->scheme[idx].override_storage_profile) {
265 DPAA_PMD_ERR("RXQ to DPDK must be associated with VSP on sharemac!");
266 return -1;
267 }
268
269 if (fif->is_shared_mac &&
270 fmc->scheme[idx].override_storage_profile &&
271 fmc->scheme[idx].storage_profile.direct &&
272 fmc->scheme[idx].storage_profile
273 .profile_select.direct_relative_profile_id ==
274 fif->base_profile_id) {
275 DPAA_PMD_ERR("RXQ can't be associated with default VSP on sharemac!");
276
277 return -1;
278 }
279
280 if ((*rxq_idx) >= max_nb_rxq) {
281 DPAA_PMD_DEBUG("Too many queues in FMC policy"
282 "%d overflow %d",
283 (*rxq_idx), max_nb_rxq);
284
285 continue;
286 }
287
288 for (k = 0; k < (*rxq_idx); k++) {
289 if (fqids[k] == fqid) {
290 found = 1;
291 break;
292 }
293 }
294
295 if (found)
296 continue;
297 fqids[(*rxq_idx)] = fqid;
298 if (fmc->scheme[idx].override_storage_profile) {
299 if (fmc->scheme[idx].storage_profile.direct) {
300 vspids[(*rxq_idx)] =
301 fmc->scheme[idx].storage_profile
302 .profile_select
303 .direct_relative_profile_id;
304 } else {
305 vspids[(*rxq_idx)] = -1;
306 }
307 } else {
308 vspids[(*rxq_idx)] = -1;
309 }
310 (*rxq_idx)++;
311 }
312 }
313
314 return 0;
315 }
316
dpaa_port_fmc_ccnode_parse(struct fman_if * fif,const struct fmc_model_t * fmc_model,int apply_idx,uint16_t * rxq_idx,int max_nb_rxq,uint32_t * fqids,int8_t * vspids)317 static int dpaa_port_fmc_ccnode_parse(struct fman_if *fif,
318 const struct fmc_model_t *fmc_model,
319 int apply_idx,
320 uint16_t *rxq_idx, int max_nb_rxq,
321 uint32_t *fqids, int8_t *vspids)
322 {
323 uint16_t j, k, found = 0;
324 const struct ioc_keys_params_t *keys_params;
325 uint32_t fqid, cc_idx = fmc_model->apply_order[apply_idx].index;
326
327 keys_params = &fmc_model->ccnode[cc_idx].keys_params;
328
329 if ((*rxq_idx) >= max_nb_rxq) {
330 DPAA_PMD_WARN("Too many queues in FMC policy %d overflow %d",
331 (*rxq_idx), max_nb_rxq);
332
333 return 0;
334 }
335
336 for (j = 0; j < keys_params->num_of_keys; ++j) {
337 found = 0;
338 fqid = keys_params->key_params[j].cc_next_engine_params
339 .params.enqueue_params.new_fqid;
340
341 /* We read DPDK queue from last classification rule present in
342 * FMC policy file. Hence, this check is required here.
343 * Also, the last classification rule in FMC policy file must
344 * have userspace queue so that it can be used by DPDK
345 * application.
346 */
347 if (keys_params->key_params[j].cc_next_engine_params
348 .next_engine != e_IOC_FM_PCD_DONE) {
349 DPAA_PMD_WARN("FMC CC next engine not support");
350 continue;
351 }
352 if (keys_params->key_params[j].cc_next_engine_params
353 .params.enqueue_params.action !=
354 e_IOC_FM_PCD_ENQ_FRAME)
355 continue;
356 for (k = 0; k < (*rxq_idx); k++) {
357 if (fqids[k] == fqid) {
358 found = 1;
359 break;
360 }
361 }
362 if (found)
363 continue;
364
365 if ((*rxq_idx) >= max_nb_rxq) {
366 DPAA_PMD_WARN("Too many queues in FMC policy %d overflow %d",
367 (*rxq_idx), max_nb_rxq);
368
369 return 0;
370 }
371
372 fqids[(*rxq_idx)] = fqid;
373 vspids[(*rxq_idx)] =
374 keys_params->key_params[j].cc_next_engine_params
375 .params.enqueue_params
376 .new_relative_storage_profile_id;
377
378 if (vspids[(*rxq_idx)] == fif->base_profile_id &&
379 fif->is_shared_mac) {
380 DPAA_PMD_ERR("VSP %d can NOT be used on DPDK.",
381 vspids[(*rxq_idx)]);
382 DPAA_PMD_ERR("It is associated to skb pool of shared interface.");
383 return -1;
384 }
385 (*rxq_idx)++;
386 }
387
388 return 0;
389 }
390
dpaa_port_fmc_init(struct fman_if * fif,uint32_t * fqids,int8_t * vspids,int max_nb_rxq)391 int dpaa_port_fmc_init(struct fman_if *fif,
392 uint32_t *fqids, int8_t *vspids, int max_nb_rxq)
393 {
394 int current_port = -1, ret;
395 uint16_t rxq_idx = 0;
396 const struct fmc_model_t *fmc_model;
397 uint32_t i;
398
399 if (!g_fmc_model) {
400 size_t bytes_read;
401 FILE *fp = fopen(FMC_FILE, "rb");
402
403 if (!fp) {
404 DPAA_PMD_ERR("%s not exists", FMC_FILE);
405 return -1;
406 }
407
408 g_fmc_model = rte_malloc(NULL, sizeof(struct fmc_model_t), 64);
409 if (!g_fmc_model) {
410 DPAA_PMD_ERR("FMC memory alloc failed");
411 fclose(fp);
412 return -1;
413 }
414
415 bytes_read = fread(g_fmc_model,
416 sizeof(struct fmc_model_t), 1, fp);
417 if (!bytes_read) {
418 DPAA_PMD_ERR("No bytes read");
419 fclose(fp);
420 rte_free(g_fmc_model);
421 g_fmc_model = NULL;
422 return -1;
423 }
424 fclose(fp);
425 }
426
427 fmc_model = g_fmc_model;
428
429 if (fmc_model->format_version != FMC_OUTPUT_FORMAT_VER)
430 return -1;
431
432 for (i = 0; i < fmc_model->apply_order_count; i++) {
433 switch (fmc_model->apply_order[i].type) {
434 case fmcengine_start:
435 break;
436 case fmcengine_end:
437 break;
438 case fmcport_start:
439 current_port = dpaa_port_fmc_port_parse(fif,
440 fmc_model, i);
441 break;
442 case fmcport_end:
443 break;
444 case fmcscheme:
445 if (current_port < 0)
446 break;
447
448 ret = dpaa_port_fmc_scheme_parse(fif, fmc_model,
449 i, &rxq_idx,
450 max_nb_rxq,
451 fqids, vspids);
452 if (ret)
453 return ret;
454
455 break;
456 case fmcccnode:
457 if (current_port < 0)
458 break;
459
460 ret = dpaa_port_fmc_ccnode_parse(fif, fmc_model,
461 i, &rxq_idx,
462 max_nb_rxq, fqids,
463 vspids);
464 if (ret)
465 return ret;
466
467 break;
468 case fmchtnode:
469 break;
470 case fmcreplicator:
471 break;
472 case fmccctree:
473 break;
474 case fmcpolicer:
475 break;
476 case fmcmanipulation:
477 break;
478 default:
479 break;
480 }
481 }
482
483 return rxq_idx;
484 }
485