Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2018-2021,2023 NXP
3 : : */
4 : :
5 : : #include <sys/queue.h>
6 : : #include <stdio.h>
7 : : #include <errno.h>
8 : : #include <stdint.h>
9 : : #include <string.h>
10 : : #include <unistd.h>
11 : : #include <stdarg.h>
12 : :
13 : : #include <rte_ethdev.h>
14 : : #include <rte_log.h>
15 : : #include <rte_malloc.h>
16 : : #include <rte_flow_driver.h>
17 : : #include <rte_tailq.h>
18 : :
19 : : #include <bus_fslmc_driver.h>
20 : : #include <fsl_dpdmux.h>
21 : : #include <fsl_dpkg.h>
22 : :
23 : : #include <dpaa2_ethdev.h>
24 : : #include <dpaa2_pmd_logs.h>
25 : :
26 : : struct dpaa2_dpdmux_dev {
27 : : TAILQ_ENTRY(dpaa2_dpdmux_dev) next;
28 : : /**< Pointer to Next device instance */
29 : : struct fsl_mc_io dpdmux; /** handle to DPDMUX portal object */
30 : : uint16_t token;
31 : : uint32_t dpdmux_id; /*HW ID for DPDMUX object */
32 : : uint8_t num_ifs; /* Number of interfaces in DPDMUX */
33 : : };
34 : :
35 : : #define DPAA2_MUX_FLOW_MAX_RULE_NUM 8
36 : : struct dpaa2_mux_flow {
37 : : struct dpdmux_rule_cfg rule[DPAA2_MUX_FLOW_MAX_RULE_NUM];
38 : : };
39 : :
40 : : TAILQ_HEAD(dpdmux_dev_list, dpaa2_dpdmux_dev);
41 : : static struct dpdmux_dev_list dpdmux_dev_list =
42 : : TAILQ_HEAD_INITIALIZER(dpdmux_dev_list); /*!< DPDMUX device list */
43 : :
44 : : static struct dpaa2_dpdmux_dev *get_dpdmux_from_id(uint32_t dpdmux_id)
45 : : {
46 : : struct dpaa2_dpdmux_dev *dpdmux_dev = NULL;
47 : :
48 : : /* Get DPDMUX dev handle from list using index */
49 [ # # # # : 0 : TAILQ_FOREACH(dpdmux_dev, &dpdmux_dev_list, next) {
# # # # #
# ]
50 [ # # # # : 0 : if (dpdmux_dev->dpdmux_id == dpdmux_id)
# # # # #
# ]
51 : : break;
52 : : }
53 : :
54 : : return dpdmux_dev;
55 : : }
56 : :
57 : : int
58 : 0 : rte_pmd_dpaa2_mux_flow_create(uint32_t dpdmux_id,
59 : : struct rte_flow_item pattern[],
60 : : struct rte_flow_action actions[])
61 : : {
62 : : struct dpaa2_dpdmux_dev *dpdmux_dev;
63 : : static struct dpkg_profile_cfg s_kg_cfg;
64 : : struct dpkg_profile_cfg kg_cfg;
65 : : const struct rte_flow_action_vf *vf_conf;
66 : : struct dpdmux_cls_action dpdmux_action;
67 : : uint8_t *key_va = NULL, *mask_va = NULL;
68 : : void *key_cfg_va = NULL;
69 : : uint64_t key_iova, mask_iova, key_cfg_iova;
70 : : uint8_t key_size = 0;
71 : : int ret = 0, loop = 0;
72 : : static int s_i;
73 : : struct dpkg_extract *extract;
74 : : struct dpdmux_rule_cfg rule;
75 : :
76 : : memset(&kg_cfg, 0, sizeof(struct dpkg_profile_cfg));
77 : :
78 : : /* Find the DPDMUX from dpdmux_id in our list */
79 : : dpdmux_dev = get_dpdmux_from_id(dpdmux_id);
80 [ # # ]: 0 : if (!dpdmux_dev) {
81 : 0 : DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id);
82 : : ret = -ENODEV;
83 : 0 : goto creation_error;
84 : : }
85 : :
86 : 0 : key_cfg_va = rte_zmalloc(NULL, DIST_PARAM_IOVA_SIZE,
87 : : RTE_CACHE_LINE_SIZE);
88 [ # # ]: 0 : if (!key_cfg_va) {
89 : 0 : DPAA2_PMD_ERR("Unable to allocate key configure buffer");
90 : : ret = -ENOMEM;
91 : 0 : goto creation_error;
92 : : }
93 : :
94 : 0 : key_cfg_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_cfg_va,
95 : : DIST_PARAM_IOVA_SIZE);
96 [ # # ]: 0 : if (key_cfg_iova == RTE_BAD_IOVA) {
97 : 0 : DPAA2_PMD_ERR("%s: No IOMMU map for key cfg(%p)",
98 : : __func__, key_cfg_va);
99 : : ret = -ENOBUFS;
100 : 0 : goto creation_error;
101 : : }
102 : :
103 : 0 : key_va = rte_zmalloc(NULL, (2 * DIST_PARAM_IOVA_SIZE),
104 : : RTE_CACHE_LINE_SIZE);
105 [ # # ]: 0 : if (!key_va) {
106 : 0 : DPAA2_PMD_ERR("Unable to allocate flow dist parameter");
107 : : ret = -ENOMEM;
108 : 0 : goto creation_error;
109 : : }
110 : :
111 : 0 : key_iova = DPAA2_VADDR_TO_IOVA_AND_CHECK(key_va,
112 : : (2 * DIST_PARAM_IOVA_SIZE));
113 [ # # ]: 0 : if (key_iova == RTE_BAD_IOVA) {
114 : 0 : DPAA2_PMD_ERR("%s: No IOMMU mapping for address(%p)",
115 : : __func__, key_va);
116 : : ret = -ENOBUFS;
117 : 0 : goto creation_error;
118 : : }
119 : :
120 : 0 : mask_va = key_va + DIST_PARAM_IOVA_SIZE;
121 : 0 : mask_iova = key_iova + DIST_PARAM_IOVA_SIZE;
122 : :
123 : : /* Currently taking only IP protocol as an extract type.
124 : : * This can be extended to other fields using pattern->type.
125 : : */
126 : : memset(&kg_cfg, 0, sizeof(struct dpkg_profile_cfg));
127 : :
128 [ # # ]: 0 : while (pattern[loop].type != RTE_FLOW_ITEM_TYPE_END) {
129 [ # # ]: 0 : if (kg_cfg.num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
130 : 0 : DPAA2_PMD_ERR("Too many extracts(%d)",
131 : : kg_cfg.num_extracts);
132 : : ret = -ENOTSUP;
133 : 0 : goto creation_error;
134 : : }
135 [ # # # # : 0 : switch (pattern[loop].type) {
# # ]
136 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
137 : : {
138 : : const struct rte_flow_item_ipv4 *spec;
139 : : const struct rte_flow_item_ipv4 *mask;
140 : :
141 : 0 : extract = &kg_cfg.extracts[kg_cfg.num_extracts];
142 : 0 : extract->type = DPKG_EXTRACT_FROM_HDR;
143 : 0 : extract->extract.from_hdr.prot = NET_PROT_IP;
144 : 0 : extract->extract.from_hdr.field = NH_FLD_IP_PROTO;
145 : 0 : extract->extract.from_hdr.type = DPKG_FULL_FIELD;
146 : :
147 : 0 : kg_cfg.num_extracts++;
148 : :
149 : 0 : spec = pattern[loop].spec;
150 : 0 : mask = pattern[loop].mask;
151 : 0 : rte_memcpy(&key_va[key_size],
152 [ # # ]: 0 : &spec->hdr.next_proto_id, sizeof(uint8_t));
153 [ # # ]: 0 : if (mask) {
154 : 0 : rte_memcpy(&mask_va[key_size],
155 [ # # ]: 0 : &mask->hdr.next_proto_id,
156 : : sizeof(uint8_t));
157 : : } else {
158 : 0 : mask_va[key_size] = 0xff;
159 : : }
160 : 0 : key_size += sizeof(uint8_t);
161 : : }
162 : 0 : break;
163 : :
164 : 0 : case RTE_FLOW_ITEM_TYPE_VLAN:
165 : : {
166 : : const struct rte_flow_item_vlan *spec;
167 : : const struct rte_flow_item_vlan *mask;
168 : :
169 : 0 : extract = &kg_cfg.extracts[kg_cfg.num_extracts];
170 : 0 : extract->type = DPKG_EXTRACT_FROM_HDR;
171 : 0 : extract->extract.from_hdr.prot = NET_PROT_VLAN;
172 : 0 : extract->extract.from_hdr.field = NH_FLD_VLAN_TCI;
173 : 0 : extract->extract.from_hdr.type = DPKG_FULL_FIELD;
174 : :
175 : 0 : kg_cfg.num_extracts++;
176 : :
177 : 0 : spec = pattern[loop].spec;
178 : 0 : mask = pattern[loop].mask;
179 : 0 : rte_memcpy(&key_va[key_size],
180 [ # # ]: 0 : &spec->tci, sizeof(uint16_t));
181 [ # # ]: 0 : if (mask) {
182 : 0 : rte_memcpy(&mask_va[key_size],
183 [ # # ]: 0 : &mask->tci, sizeof(uint16_t));
184 : : } else {
185 : 0 : memset(&mask_va[key_size], 0xff,
186 : : sizeof(rte_be16_t));
187 : : }
188 : 0 : key_size += sizeof(uint16_t);
189 : : }
190 : 0 : break;
191 : :
192 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
193 : : {
194 : : const struct rte_flow_item_udp *spec;
195 : : const struct rte_flow_item_udp *mask;
196 : :
197 : 0 : extract = &kg_cfg.extracts[kg_cfg.num_extracts];
198 : 0 : extract->type = DPKG_EXTRACT_FROM_HDR;
199 : 0 : extract->extract.from_hdr.prot = NET_PROT_UDP;
200 : 0 : extract->extract.from_hdr.type = DPKG_FULL_FIELD;
201 : 0 : extract->extract.from_hdr.field = NH_FLD_UDP_PORT_DST;
202 : 0 : kg_cfg.num_extracts++;
203 : :
204 : 0 : spec = pattern[loop].spec;
205 : 0 : mask = pattern[loop].mask;
206 : 0 : rte_memcpy(&key_va[key_size],
207 [ # # ]: 0 : &spec->hdr.dst_port, sizeof(rte_be16_t));
208 [ # # ]: 0 : if (mask) {
209 : 0 : rte_memcpy(&mask_va[key_size],
210 [ # # ]: 0 : &mask->hdr.dst_port,
211 : : sizeof(rte_be16_t));
212 : : } else {
213 : 0 : memset(&mask_va[key_size], 0xff,
214 : : sizeof(rte_be16_t));
215 : : }
216 : 0 : key_size += sizeof(rte_be16_t);
217 : : }
218 : 0 : break;
219 : :
220 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
221 : : {
222 : : const struct rte_flow_item_eth *spec;
223 : : const struct rte_flow_item_eth *mask;
224 : :
225 : 0 : extract = &kg_cfg.extracts[kg_cfg.num_extracts];
226 : 0 : extract->type = DPKG_EXTRACT_FROM_HDR;
227 : 0 : extract->extract.from_hdr.prot = NET_PROT_ETH;
228 : 0 : extract->extract.from_hdr.type = DPKG_FULL_FIELD;
229 : 0 : extract->extract.from_hdr.field = NH_FLD_ETH_TYPE;
230 : 0 : kg_cfg.num_extracts++;
231 : :
232 : 0 : spec = pattern[loop].spec;
233 : 0 : mask = pattern[loop].mask;
234 : 0 : rte_memcpy(&key_va[key_size],
235 [ # # ]: 0 : &spec->type, sizeof(rte_be16_t));
236 [ # # ]: 0 : if (mask) {
237 : 0 : rte_memcpy(&mask_va[key_size],
238 [ # # ]: 0 : &mask->type, sizeof(rte_be16_t));
239 : : } else {
240 : 0 : memset(&mask_va[key_size], 0xff,
241 : : sizeof(rte_be16_t));
242 : : }
243 : 0 : key_size += sizeof(rte_be16_t);
244 : : }
245 : 0 : break;
246 : :
247 : 0 : case RTE_FLOW_ITEM_TYPE_RAW:
248 : : {
249 : : const struct rte_flow_item_raw *spec;
250 : : const struct rte_flow_item_raw *mask;
251 : :
252 : 0 : spec = pattern[loop].spec;
253 : 0 : mask = pattern[loop].mask;
254 : 0 : extract = &kg_cfg.extracts[kg_cfg.num_extracts];
255 : 0 : extract->type = DPKG_EXTRACT_FROM_DATA;
256 : 0 : extract->extract.from_data.offset = spec->offset;
257 : 0 : extract->extract.from_data.size = spec->length;
258 : 0 : kg_cfg.num_extracts++;
259 : :
260 : 0 : rte_memcpy(&key_va[key_size],
261 [ # # ]: 0 : spec->pattern, spec->length);
262 [ # # # # ]: 0 : if (mask && mask->pattern) {
263 : 0 : rte_memcpy(&mask_va[key_size],
264 [ # # ]: 0 : mask->pattern, spec->length);
265 : : } else {
266 : 0 : memset(&mask_va[key_size], 0xff, spec->length);
267 : : }
268 : :
269 : 0 : key_size += spec->length;
270 : : }
271 : 0 : break;
272 : :
273 : 0 : default:
274 : 0 : DPAA2_PMD_ERR("Not supported pattern[%d] type: %d",
275 : : loop, pattern[loop].type);
276 : : ret = -ENOTSUP;
277 : 0 : goto creation_error;
278 : : }
279 : 0 : loop++;
280 : : }
281 : :
282 : 0 : ret = dpkg_prepare_key_cfg(&kg_cfg, key_cfg_va);
283 [ # # ]: 0 : if (ret) {
284 : 0 : DPAA2_PMD_ERR("dpkg_prepare_key_cfg failed: err(%d)", ret);
285 : 0 : goto creation_error;
286 : : }
287 : :
288 [ # # ]: 0 : if (!s_i) {
289 : 0 : ret = dpdmux_set_custom_key(&dpdmux_dev->dpdmux,
290 : 0 : CMD_PRI_LOW, dpdmux_dev->token, key_cfg_iova);
291 [ # # ]: 0 : if (ret) {
292 : 0 : DPAA2_PMD_ERR("dpdmux_set_custom_key failed: err(%d)",
293 : : ret);
294 : 0 : goto creation_error;
295 : : }
296 : : rte_memcpy(&s_kg_cfg, &kg_cfg, sizeof(struct dpkg_profile_cfg));
297 : : } else {
298 [ # # ]: 0 : if (memcmp(&s_kg_cfg, &kg_cfg,
299 : : sizeof(struct dpkg_profile_cfg))) {
300 : 0 : DPAA2_PMD_ERR("%s: Single flow support only.",
301 : : __func__);
302 : : ret = -ENOTSUP;
303 : 0 : goto creation_error;
304 : : }
305 : : }
306 : :
307 : 0 : vf_conf = actions[0].conf;
308 [ # # # # ]: 0 : if (vf_conf->id == 0 || vf_conf->id > dpdmux_dev->num_ifs) {
309 : 0 : DPAA2_PMD_ERR("Invalid destination id(%d)", vf_conf->id);
310 : 0 : goto creation_error;
311 : : }
312 : 0 : dpdmux_action.dest_if = vf_conf->id;
313 : :
314 : 0 : rule.key_iova = key_iova;
315 : 0 : rule.mask_iova = mask_iova;
316 : 0 : rule.key_size = key_size;
317 : 0 : rule.entry_index = s_i;
318 : 0 : s_i++;
319 : :
320 : : /* As now our key extract parameters are set, let us configure
321 : : * the rule.
322 : : */
323 : 0 : ret = dpdmux_add_custom_cls_entry(&dpdmux_dev->dpdmux,
324 : 0 : CMD_PRI_LOW, dpdmux_dev->token,
325 : : &rule, &dpdmux_action);
326 [ # # ]: 0 : if (ret) {
327 : 0 : DPAA2_PMD_ERR("Add classification entry failed:err(%d)", ret);
328 : 0 : goto creation_error;
329 : : }
330 : :
331 : 0 : creation_error:
332 : 0 : rte_free(key_cfg_va);
333 : 0 : rte_free(key_va);
334 : :
335 : 0 : return ret;
336 : : }
337 : :
338 : : int
339 : 0 : rte_pmd_dpaa2_mux_flow_l2(uint32_t dpdmux_id,
340 : : uint8_t mac_addr[6], uint16_t vlan_id, int dest_if)
341 : : {
342 : : struct dpaa2_dpdmux_dev *dpdmux_dev;
343 : : struct dpdmux_l2_rule rule;
344 : : int ret, i;
345 : :
346 : : /* Find the DPDMUX from dpdmux_id in our list */
347 : : dpdmux_dev = get_dpdmux_from_id(dpdmux_id);
348 [ # # ]: 0 : if (!dpdmux_dev) {
349 : 0 : DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id);
350 : 0 : return -ENODEV;
351 : : }
352 : :
353 [ # # ]: 0 : for (i = 0; i < 6; i++)
354 : 0 : rule.mac_addr[i] = mac_addr[i];
355 : 0 : rule.vlan_id = vlan_id;
356 : :
357 : 0 : ret = dpdmux_if_add_l2_rule(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
358 : 0 : dpdmux_dev->token, dest_if, &rule);
359 [ # # ]: 0 : if (ret) {
360 : 0 : DPAA2_PMD_ERR("dpdmux_if_add_l2_rule failed:err(%d)", ret);
361 : 0 : return ret;
362 : : }
363 : :
364 : : return 0;
365 : : }
366 : :
367 : : int
368 : 0 : rte_pmd_dpaa2_mux_rx_frame_len(uint32_t dpdmux_id, uint16_t max_rx_frame_len)
369 : : {
370 : : struct dpaa2_dpdmux_dev *dpdmux_dev;
371 : : int ret;
372 : :
373 : : /* Find the DPDMUX from dpdmux_id in our list */
374 : : dpdmux_dev = get_dpdmux_from_id(dpdmux_id);
375 [ # # ]: 0 : if (!dpdmux_dev) {
376 : 0 : DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id);
377 : 0 : return -1;
378 : : }
379 : :
380 : 0 : ret = dpdmux_set_max_frame_length(&dpdmux_dev->dpdmux,
381 : 0 : CMD_PRI_LOW, dpdmux_dev->token, max_rx_frame_len);
382 [ # # ]: 0 : if (ret) {
383 : 0 : DPAA2_PMD_ERR("DPDMUX:Unable to set mtu. check config %d", ret);
384 : 0 : return ret;
385 : : }
386 : :
387 : 0 : DPAA2_PMD_INFO("dpdmux mtu set as %u",
388 : : DPAA2_MAX_RX_PKT_LEN - RTE_ETHER_CRC_LEN);
389 : :
390 : 0 : return ret;
391 : : }
392 : :
393 : : /* dump the status of the dpaa2_mux counters on the console */
394 : : void
395 : 0 : rte_pmd_dpaa2_mux_dump_counter(FILE *f, uint32_t dpdmux_id, int num_if)
396 : : {
397 : : struct dpaa2_dpdmux_dev *dpdmux;
398 : : uint64_t counter;
399 : : int ret;
400 : : int if_id;
401 : :
402 : : /* Find the DPDMUX from dpdmux_id in our list */
403 : : dpdmux = get_dpdmux_from_id(dpdmux_id);
404 [ # # ]: 0 : if (!dpdmux) {
405 : 0 : DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id);
406 : 0 : return;
407 : : }
408 : :
409 [ # # ]: 0 : for (if_id = 0; if_id < num_if; if_id++) {
410 : : fprintf(f, "dpdmux.%d\n", if_id);
411 : :
412 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
413 : 0 : dpdmux->token, if_id, DPDMUX_CNT_ING_FRAME, &counter);
414 [ # # ]: 0 : if (!ret)
415 : 0 : fprintf(f, "DPDMUX_CNT_ING_FRAME %" PRIu64 "\n",
416 : : counter);
417 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
418 : 0 : dpdmux->token, if_id, DPDMUX_CNT_ING_BYTE, &counter);
419 [ # # ]: 0 : if (!ret)
420 : 0 : fprintf(f, "DPDMUX_CNT_ING_BYTE %" PRIu64 "\n",
421 : : counter);
422 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
423 : 0 : dpdmux->token, if_id, DPDMUX_CNT_ING_FLTR_FRAME,
424 : : &counter);
425 [ # # ]: 0 : if (!ret)
426 : 0 : fprintf(f, "DPDMUX_CNT_ING_FLTR_FRAME %" PRIu64 "\n",
427 : : counter);
428 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
429 : 0 : dpdmux->token, if_id, DPDMUX_CNT_ING_FRAME_DISCARD,
430 : : &counter);
431 [ # # ]: 0 : if (!ret)
432 : 0 : fprintf(f, "DPDMUX_CNT_ING_FRAME_DISCARD %" PRIu64 "\n",
433 : : counter);
434 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
435 : 0 : dpdmux->token, if_id, DPDMUX_CNT_ING_MCAST_FRAME,
436 : : &counter);
437 [ # # ]: 0 : if (!ret)
438 : 0 : fprintf(f, "DPDMUX_CNT_ING_MCAST_FRAME %" PRIu64 "\n",
439 : : counter);
440 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
441 : 0 : dpdmux->token, if_id, DPDMUX_CNT_ING_MCAST_BYTE,
442 : : &counter);
443 [ # # ]: 0 : if (!ret)
444 : 0 : fprintf(f, "DPDMUX_CNT_ING_MCAST_BYTE %" PRIu64 "\n",
445 : : counter);
446 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
447 : 0 : dpdmux->token, if_id, DPDMUX_CNT_ING_BCAST_FRAME,
448 : : &counter);
449 [ # # ]: 0 : if (!ret)
450 : 0 : fprintf(f, "DPDMUX_CNT_ING_BCAST_FRAME %" PRIu64 "\n",
451 : : counter);
452 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
453 : 0 : dpdmux->token, if_id, DPDMUX_CNT_ING_BCAST_BYTES,
454 : : &counter);
455 [ # # ]: 0 : if (!ret)
456 : 0 : fprintf(f, "DPDMUX_CNT_ING_BCAST_BYTES %" PRIu64 "\n",
457 : : counter);
458 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
459 : 0 : dpdmux->token, if_id, DPDMUX_CNT_EGR_FRAME, &counter);
460 [ # # ]: 0 : if (!ret)
461 : 0 : fprintf(f, "DPDMUX_CNT_EGR_FRAME %" PRIu64 "\n",
462 : : counter);
463 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
464 : 0 : dpdmux->token, if_id, DPDMUX_CNT_EGR_BYTE, &counter);
465 [ # # ]: 0 : if (!ret)
466 : 0 : fprintf(f, "DPDMUX_CNT_EGR_BYTE %" PRIu64 "\n",
467 : : counter);
468 : 0 : ret = dpdmux_if_get_counter(&dpdmux->dpdmux, CMD_PRI_LOW,
469 : 0 : dpdmux->token, if_id, DPDMUX_CNT_EGR_FRAME_DISCARD,
470 : : &counter);
471 [ # # ]: 0 : if (!ret)
472 : 0 : fprintf(f, "DPDMUX_CNT_EGR_FRAME_DISCARD %" PRIu64 "\n",
473 : : counter);
474 : : }
475 : : }
476 : :
477 : : static int
478 : 0 : dpaa2_create_dpdmux_device(int vdev_fd __rte_unused,
479 : : struct vfio_device_info *obj_info __rte_unused,
480 : : struct rte_dpaa2_device *obj)
481 : : {
482 : : struct dpaa2_dpdmux_dev *dpdmux_dev;
483 : : struct dpdmux_attr attr;
484 : 0 : int ret, dpdmux_id = obj->object_id;
485 : : uint16_t maj_ver;
486 : : uint16_t min_ver;
487 : : uint8_t skip_reset_flags;
488 : :
489 : 0 : PMD_INIT_FUNC_TRACE();
490 : :
491 : : /* Allocate DPAA2 dpdmux handle */
492 : 0 : dpdmux_dev = rte_zmalloc(NULL,
493 : : sizeof(struct dpaa2_dpdmux_dev), RTE_CACHE_LINE_SIZE);
494 [ # # ]: 0 : if (!dpdmux_dev) {
495 : 0 : DPAA2_PMD_ERR("Memory allocation failed for DPDMUX Device");
496 : 0 : return -ENOMEM;
497 : : }
498 : :
499 : : /* Open the dpdmux object */
500 : 0 : dpdmux_dev->dpdmux.regs = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX);
501 : 0 : ret = dpdmux_open(&dpdmux_dev->dpdmux, CMD_PRI_LOW, dpdmux_id,
502 : : &dpdmux_dev->token);
503 [ # # ]: 0 : if (ret) {
504 : 0 : DPAA2_PMD_ERR("Unable to open dpdmux object: err(%d)", ret);
505 : 0 : goto init_err;
506 : : }
507 : :
508 : 0 : ret = dpdmux_get_attributes(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
509 : 0 : dpdmux_dev->token, &attr);
510 [ # # ]: 0 : if (ret) {
511 : 0 : DPAA2_PMD_ERR("Unable to get dpdmux attr: err(%d)", ret);
512 : 0 : goto init_err;
513 : : }
514 : :
515 [ # # ]: 0 : if (attr.method != DPDMUX_METHOD_C_VLAN_MAC) {
516 : 0 : ret = dpdmux_if_set_default(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
517 : 0 : dpdmux_dev->token, attr.default_if);
518 [ # # ]: 0 : if (ret) {
519 : 0 : DPAA2_PMD_ERR("setting default interface failed in %s",
520 : : __func__);
521 : 0 : goto init_err;
522 : : }
523 : : skip_reset_flags = DPDMUX_SKIP_DEFAULT_INTERFACE
524 : : | DPDMUX_SKIP_UNICAST_RULES | DPDMUX_SKIP_MULTICAST_RULES;
525 : : } else {
526 : : skip_reset_flags = DPDMUX_SKIP_DEFAULT_INTERFACE;
527 : : }
528 : :
529 : 0 : ret = dpdmux_get_api_version(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
530 : : &maj_ver, &min_ver);
531 [ # # ]: 0 : if (ret) {
532 : 0 : DPAA2_PMD_ERR("setting version failed in %s",
533 : : __func__);
534 : 0 : goto init_err;
535 : : }
536 : :
537 : : /* The new dpdmux_set/get_resetable() API are available starting with
538 : : * DPDMUX_VER_MAJOR==6 and DPDMUX_VER_MINOR==6
539 : : */
540 [ # # # # ]: 0 : if (maj_ver >= 6 && min_ver >= 6) {
541 : 0 : ret = dpdmux_set_resetable(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
542 : 0 : dpdmux_dev->token, skip_reset_flags);
543 [ # # ]: 0 : if (ret) {
544 : 0 : DPAA2_PMD_ERR("setting default interface failed in %s",
545 : : __func__);
546 : 0 : goto init_err;
547 : : }
548 : : }
549 : :
550 [ # # # # ]: 0 : if (maj_ver >= 6 && min_ver >= 9) {
551 : : struct dpdmux_error_cfg mux_err_cfg;
552 : :
553 : : memset(&mux_err_cfg, 0, sizeof(mux_err_cfg));
554 : : /* Note: Discarded flag(DPDMUX_ERROR_DISC) has effect only when
555 : : * ERROR_ACTION is set to DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE.
556 : : */
557 : 0 : mux_err_cfg.errors = DPDMUX_ALL_ERRORS;
558 : 0 : mux_err_cfg.error_action = DPDMUX_ERROR_ACTION_CONTINUE;
559 : :
560 : 0 : ret = dpdmux_if_set_errors_behavior(&dpdmux_dev->dpdmux,
561 : : CMD_PRI_LOW,
562 : 0 : dpdmux_dev->token, DPAA2_DPDMUX_DPMAC_IDX,
563 : : &mux_err_cfg);
564 [ # # ]: 0 : if (ret) {
565 : 0 : DPAA2_PMD_ERR("dpdmux_if_set_errors_behavior %s err %d",
566 : : __func__, ret);
567 : 0 : goto init_err;
568 : : }
569 : : }
570 : :
571 : 0 : dpdmux_dev->dpdmux_id = dpdmux_id;
572 : 0 : dpdmux_dev->num_ifs = attr.num_ifs;
573 : :
574 : 0 : TAILQ_INSERT_TAIL(&dpdmux_dev_list, dpdmux_dev, next);
575 : :
576 : 0 : return 0;
577 : :
578 : 0 : init_err:
579 : 0 : rte_free(dpdmux_dev);
580 : :
581 : 0 : return -1;
582 : : }
583 : :
584 : : static void
585 : 0 : dpaa2_close_dpdmux_device(int object_id)
586 : : {
587 : : struct dpaa2_dpdmux_dev *dpdmux_dev;
588 : :
589 : 0 : dpdmux_dev = get_dpdmux_from_id((uint32_t)object_id);
590 : :
591 [ # # ]: 0 : if (dpdmux_dev) {
592 : 0 : dpdmux_close(&dpdmux_dev->dpdmux, CMD_PRI_LOW,
593 : 0 : dpdmux_dev->token);
594 [ # # ]: 0 : TAILQ_REMOVE(&dpdmux_dev_list, dpdmux_dev, next);
595 : 0 : rte_free(dpdmux_dev);
596 : : }
597 : 0 : }
598 : :
599 : : static struct rte_dpaa2_object rte_dpaa2_dpdmux_obj = {
600 : : .dev_type = DPAA2_MUX,
601 : : .create = dpaa2_create_dpdmux_device,
602 : : .close = dpaa2_close_dpdmux_device,
603 : : };
604 : :
605 : 251 : RTE_PMD_REGISTER_DPAA2_OBJECT(dpdmux, rte_dpaa2_dpdmux_obj);
|