1 /* SPDX-License-Identifier: BSD-3-Clause
13 #include <rte_ethdev.h>
15 #include <rte_malloc.h>
16 #include <rte_flow_driver.h>
17 #include <rte_tailq.h>
19 #include <rte_fslmc.h>
20 #include <fsl_dpdmux.h>
23 #include <dpaa2_ethdev.h>
24 #include <dpaa2_pmd_logs.h>
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 */
31 uint32_t dpdmux_id
; /*HW ID for DPDMUX object */
32 uint8_t num_ifs
; /* Number of interfaces in DPDMUX */
36 struct dpdmux_rule_cfg rule
;
39 TAILQ_HEAD(dpdmux_dev_list
, dpaa2_dpdmux_dev
);
40 static struct dpdmux_dev_list dpdmux_dev_list
=
41 TAILQ_HEAD_INITIALIZER(dpdmux_dev_list
); /*!< DPDMUX device list */
43 static struct dpaa2_dpdmux_dev
*get_dpdmux_from_id(uint32_t dpdmux_id
)
45 struct dpaa2_dpdmux_dev
*dpdmux_dev
= NULL
;
47 /* Get DPBP dev handle from list using index */
48 TAILQ_FOREACH(dpdmux_dev
, &dpdmux_dev_list
, next
) {
49 if (dpdmux_dev
->dpdmux_id
== dpdmux_id
)
57 rte_pmd_dpaa2_mux_flow_create(uint32_t dpdmux_id
,
58 struct rte_flow_item
*pattern
[],
59 struct rte_flow_action
*actions
[])
61 struct dpaa2_dpdmux_dev
*dpdmux_dev
;
62 struct dpkg_profile_cfg kg_cfg
;
63 const struct rte_flow_item_ipv4
*spec
;
64 const struct rte_flow_action_vf
*vf_conf
;
65 struct dpdmux_cls_action dpdmux_action
;
66 struct rte_flow
*flow
= NULL
;
67 void *key_iova
, *mask_iova
, *key_cfg_iova
= NULL
;
70 if (pattern
[0]->type
!= RTE_FLOW_ITEM_TYPE_IPV4
) {
71 DPAA2_PMD_ERR("Not supported pattern type: %d",
76 /* Find the DPDMUX from dpdmux_id in our list */
77 dpdmux_dev
= get_dpdmux_from_id(dpdmux_id
);
79 DPAA2_PMD_ERR("Invalid dpdmux_id: %d", dpdmux_id
);
83 key_cfg_iova
= rte_zmalloc(NULL
, DIST_PARAM_IOVA_SIZE
,
86 DPAA2_PMD_ERR("Unable to allocate flow-dist parameters");
90 /* Currently taking only IP protocol as an extract type.
91 * This can be exended to other fields using pattern->type.
93 memset(&kg_cfg
, 0, sizeof(struct dpkg_profile_cfg
));
94 kg_cfg
.extracts
[0].extract
.from_hdr
.prot
= NET_PROT_IP
;
95 kg_cfg
.extracts
[0].extract
.from_hdr
.field
= NH_FLD_IP_PROTO
;
96 kg_cfg
.extracts
[0].type
= DPKG_EXTRACT_FROM_HDR
;
97 kg_cfg
.extracts
[0].extract
.from_hdr
.type
= DPKG_FULL_FIELD
;
98 kg_cfg
.num_extracts
= 1;
100 ret
= dpkg_prepare_key_cfg(&kg_cfg
, key_cfg_iova
);
102 DPAA2_PMD_ERR("dpkg_prepare_key_cfg failed: err(%d)", ret
);
106 ret
= dpdmux_set_custom_key(&dpdmux_dev
->dpdmux
, CMD_PRI_LOW
,
108 (uint64_t)(DPAA2_VADDR_TO_IOVA(key_cfg_iova
)));
110 DPAA2_PMD_ERR("dpdmux_set_custom_key failed: err(%d)", ret
);
114 /* As now our key extract parameters are set, let us configure
117 flow
= rte_zmalloc(NULL
, sizeof(struct rte_flow
) +
118 (2 * DIST_PARAM_IOVA_SIZE
), RTE_CACHE_LINE_SIZE
);
121 "Memory allocation failure for rule configration\n");
124 key_iova
= (void *)((size_t)flow
+ sizeof(struct rte_flow
));
125 mask_iova
= (void *)((size_t)key_iova
+ DIST_PARAM_IOVA_SIZE
);
127 spec
= (const struct rte_flow_item_ipv4
*)pattern
[0]->spec
;
128 memcpy(key_iova
, (const void *)&spec
->hdr
.next_proto_id
,
130 memcpy(mask_iova
, pattern
[0]->mask
, sizeof(uint8_t));
132 flow
->rule
.key_iova
= (uint64_t)(DPAA2_VADDR_TO_IOVA(key_iova
));
133 flow
->rule
.mask_iova
= (uint64_t)(DPAA2_VADDR_TO_IOVA(mask_iova
));
134 flow
->rule
.key_size
= sizeof(uint8_t);
136 vf_conf
= (const struct rte_flow_action_vf
*)(actions
[0]->conf
);
137 if (vf_conf
->id
== 0 || vf_conf
->id
> dpdmux_dev
->num_ifs
) {
138 DPAA2_PMD_ERR("Invalid destination id\n");
141 dpdmux_action
.dest_if
= vf_conf
->id
;
143 ret
= dpdmux_add_custom_cls_entry(&dpdmux_dev
->dpdmux
, CMD_PRI_LOW
,
144 dpdmux_dev
->token
, &flow
->rule
,
147 DPAA2_PMD_ERR("dpdmux_add_custom_cls_entry failed: err(%d)",
155 rte_free((void *)key_cfg_iova
);
156 rte_free((void *)flow
);
161 dpaa2_create_dpdmux_device(int vdev_fd __rte_unused
,
162 struct vfio_device_info
*obj_info __rte_unused
,
165 struct dpaa2_dpdmux_dev
*dpdmux_dev
;
166 struct dpdmux_attr attr
;
169 PMD_INIT_FUNC_TRACE();
171 /* Allocate DPAA2 dpdmux handle */
172 dpdmux_dev
= rte_malloc(NULL
, sizeof(struct dpaa2_dpdmux_dev
), 0);
174 DPAA2_PMD_ERR("Memory allocation failed for DPDMUX Device");
178 /* Open the dpdmux object */
179 dpdmux_dev
->dpdmux
.regs
= rte_mcp_ptr_list
[MC_PORTAL_INDEX
];
180 ret
= dpdmux_open(&dpdmux_dev
->dpdmux
, CMD_PRI_LOW
, dpdmux_id
,
183 DPAA2_PMD_ERR("Unable to open dpdmux object: err(%d)", ret
);
187 ret
= dpdmux_get_attributes(&dpdmux_dev
->dpdmux
, CMD_PRI_LOW
,
188 dpdmux_dev
->token
, &attr
);
190 DPAA2_PMD_ERR("Unable to get dpdmux attr: err(%d)", ret
);
194 ret
= dpdmux_if_set_default(&dpdmux_dev
->dpdmux
, CMD_PRI_LOW
,
195 dpdmux_dev
->token
, 1);
197 DPAA2_PMD_ERR("setting default interface failed in %s",
202 dpdmux_dev
->dpdmux_id
= dpdmux_id
;
203 dpdmux_dev
->num_ifs
= attr
.num_ifs
;
205 TAILQ_INSERT_TAIL(&dpdmux_dev_list
, dpdmux_dev
, next
);
211 rte_free(dpdmux_dev
);
216 static struct rte_dpaa2_object rte_dpaa2_dpdmux_obj
= {
217 .dev_type
= DPAA2_MUX
,
218 .create
= dpaa2_create_dpdmux_device
,
221 RTE_PMD_REGISTER_DPAA2_OBJECT(dpdmux
, rte_dpaa2_dpdmux_obj
);