net/i40e: fix Rx packet statistics
[dpdk.git] / drivers / net / dpaa / dpaa_fmc.c
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
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
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
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
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 }