1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2008-2016 Freescale Semiconductor Inc.
3 * Copyright 2017-2020 NXP
13 #include <sys/ioctl.h>
15 #include <rte_common.h>
18 #include "fm_pcd_ext.h"
19 #include "fm_port_ext.h"
20 #include <dpaa_ethdev.h>
22 #define DEV_TO_ID(p) \
24 t_device *p_dev = (t_device *)p; \
25 p = UINT_TO_PTR(p_dev->id); \
28 /* Major and minor are in sync with FMD, respin is for fmlib identification */
29 #define FM_LIB_VERSION_MAJOR 21
30 #define FM_LIB_VERSION_MINOR 1
31 #define FM_LIB_VERSION_RESPIN 0
33 #if (FMD_API_VERSION_MAJOR != FM_LIB_VERSION_MAJOR) || \
34 (FMD_API_VERSION_MINOR != FM_LIB_VERSION_MINOR)
35 #warning FMD and FMLIB version mismatch
45 ioc_fm_api_version_t ver;
47 _fml_dbg("Calling...\n");
49 p_dev = (t_device *)malloc(sizeof(t_device));
53 memset(dev_name, 0, 20);
54 sprintf(dev_name, "%s%s%d", "/dev/", DEV_FM_NAME, id);
55 fd = open(dev_name, O_RDWR);
65 fm_get_api_version((t_handle)p_dev, &ver);
67 if (ver.version.major != FMD_API_VERSION_MAJOR ||
68 ver.version.minor != FMD_API_VERSION_MINOR ||
69 ver.version.respin != FMD_API_VERSION_RESPIN) {
70 DPAA_PMD_WARN("Compiled against FMD API ver %u.%u.%u",
71 FMD_API_VERSION_MAJOR,
72 FMD_API_VERSION_MINOR, FMD_API_VERSION_RESPIN);
73 DPAA_PMD_WARN("Running with FMD API ver %u.%u.%u",
74 ver.version.major, ver.version.minor,
78 _fml_dbg("Finishing.\n");
80 return (t_handle)p_dev;
83 void fm_close(t_handle h_fm)
85 t_device *p_dev = (t_device *)h_fm;
87 _fml_dbg("Calling...\n");
92 _fml_dbg("Finishing.\n");
96 fm_get_api_version(t_handle h_fm, ioc_fm_api_version_t *p_version)
98 t_device *p_dev = (t_device *)h_fm;
101 _fml_dbg("Calling...\n");
103 ret = ioctl(p_dev->fd, FM_IOC_GET_API_VERSION, p_version);
105 DPAA_PMD_ERR("cannot get API version, error %i (%s)\n",
106 errno, strerror(errno));
107 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
109 _fml_dbg("Finishing.\n");
115 fm_pcd_open(t_fm_pcd_params *p_fm_pcd_params)
121 _fml_dbg("Calling...\n");
123 p_dev = (t_device *)malloc(sizeof(t_device));
127 memset(dev_name, 0, 20);
128 sprintf(dev_name, "%s%s%u-pcd", "/dev/", DEV_FM_NAME,
129 (uint32_t)((t_device *)p_fm_pcd_params->h_fm)->id);
130 fd = open(dev_name, O_RDWR);
136 p_dev->id = ((t_device *)p_fm_pcd_params->h_fm)->id;
140 _fml_dbg("Finishing.\n");
142 return (t_handle)p_dev;
146 fm_pcd_close(t_handle h_fm_pcd)
148 t_device *p_dev = (t_device *)h_fm_pcd;
150 _fml_dbg("Calling...\n");
155 printf("\nTry delete a prev created pcd handler(owners:%u)!\n",
162 _fml_dbg("Finishing.\n");
166 fm_pcd_enable(t_handle h_fm_pcd)
168 t_device *p_dev = (t_device *)h_fm_pcd;
170 _fml_dbg("Calling...\n");
172 if (ioctl(p_dev->fd, FM_PCD_IOC_ENABLE))
173 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
175 _fml_dbg("Finishing.\n");
181 fm_pcd_disable(t_handle h_fm_pcd)
183 t_device *p_dev = (t_device *)h_fm_pcd;
185 _fml_dbg("Calling...\n");
187 if (ioctl(p_dev->fd, FM_PCD_IOC_DISABLE))
188 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
190 _fml_dbg("Finishing.\n");
196 fm_pcd_net_env_characteristics_set(t_handle h_fm_pcd,
197 ioc_fm_pcd_net_env_params_t *params)
199 t_device *p_pcd_dev = (t_device *)h_fm_pcd;
200 t_device *p_dev = NULL;
202 _fml_dbg("Calling...\n");
206 if (ioctl(p_pcd_dev->fd, FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET,
210 p_dev = (t_device *)malloc(sizeof(t_device));
214 memset(p_dev, 0, sizeof(t_device));
215 p_dev->h_user_priv = (t_handle)p_pcd_dev;
217 p_dev->id = PTR_TO_UINT(params->id);
219 _fml_dbg("Finishing.\n");
221 return (t_handle)p_dev;
225 fm_pcd_net_env_characteristics_delete(t_handle h_net_env)
227 t_device *p_dev = (t_device *)h_net_env;
228 t_device *p_pcd_dev = NULL;
231 _fml_dbg("Calling...\n");
233 p_pcd_dev = (t_device *)p_dev->h_user_priv;
234 id.obj = UINT_TO_PTR(p_dev->id);
236 if (ioctl(p_pcd_dev->fd, FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE,
238 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
243 _fml_dbg("Finishing.\n");
249 fm_pcd_kg_scheme_set(t_handle h_fm_pcd,
250 ioc_fm_pcd_kg_scheme_params_t *params)
252 t_device *p_pcd_dev = (t_device *)h_fm_pcd;
253 t_device *p_dev = NULL;
256 _fml_dbg("Calling...\n");
260 if (params->param.modify) {
261 if (params->param.scm_id.scheme_id)
262 DEV_TO_ID(params->param.scm_id.scheme_id);
267 /* correct h_net_env param from scheme */
268 if (params->param.net_env_params.net_env_id)
269 DEV_TO_ID(params->param.net_env_params.net_env_id);
271 /* correct next engine params handlers: cc*/
272 if (params->param.next_engine == e_IOC_FM_PCD_CC &&
273 params->param.kg_next_engine_params.cc.tree_id)
274 DEV_TO_ID(params->param.kg_next_engine_params.cc.tree_id);
276 ret = ioctl(p_pcd_dev->fd, FM_PCD_IOC_KG_SCHEME_SET, params);
278 DPAA_PMD_ERR(" cannot set kg scheme, error %i (%s)\n",
279 errno, strerror(errno));
283 p_dev = (t_device *)malloc(sizeof(t_device));
287 memset(p_dev, 0, sizeof(t_device));
288 p_dev->h_user_priv = (t_handle)p_pcd_dev;
289 /* increase owners only if a new scheme is created */
290 if (!params->param.modify)
292 p_dev->id = PTR_TO_UINT(params->id);
294 _fml_dbg("Finishing.\n");
296 return (t_handle)p_dev;
300 fm_pcd_kg_scheme_delete(t_handle h_scheme)
302 t_device *p_dev = (t_device *)h_scheme;
303 t_device *p_pcd_dev = NULL;
306 _fml_dbg("Calling...\n");
308 p_pcd_dev = (t_device *)p_dev->h_user_priv;
309 id.obj = UINT_TO_PTR(p_dev->id);
311 if (ioctl(p_pcd_dev->fd, FM_PCD_IOC_KG_SCHEME_DELETE, &id)) {
312 DPAA_PMD_WARN("cannot delete kg scheme, error %i (%s)\n",
313 errno, strerror(errno));
314 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
320 _fml_dbg("Finishing.\n");
326 e_fm_port_type port_type; /**< Port type */
327 uint8_t port_id; /**< Port Id - relative to type */
331 fm_port_open(t_fm_port_params *p_fm_port_params)
336 t_fm_port *p_fm_port;
338 _fml_dbg("Calling...\n");
340 p_dev = (t_device *)malloc(sizeof(t_device));
344 memset(p_dev, 0, sizeof(t_device));
346 p_fm_port = (t_fm_port *)malloc(sizeof(t_fm_port));
351 memset(p_fm_port, 0, sizeof(t_fm_port));
352 memset(dev_name, 0, sizeof(dev_name));
353 switch (p_fm_port_params->port_type) {
354 case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
355 sprintf(dev_name, "%s%s%u-port-oh%d", "/dev/", DEV_FM_NAME,
356 (uint32_t)((t_device *)p_fm_port_params->h_fm)->id,
357 p_fm_port_params->port_id);
359 case e_FM_PORT_TYPE_RX:
360 sprintf(dev_name, "%s%s%u-port-rx%d", "/dev/", DEV_FM_NAME,
361 (uint32_t)((t_device *)p_fm_port_params->h_fm)->id,
362 p_fm_port_params->port_id);
364 case e_FM_PORT_TYPE_RX_10G:
365 sprintf(dev_name, "%s%s%u-port-rx%d", "/dev/", DEV_FM_NAME,
366 (uint32_t)((t_device *)p_fm_port_params->h_fm)->id,
367 FM_MAX_NUM_OF_1G_RX_PORTS + p_fm_port_params->port_id);
369 case e_FM_PORT_TYPE_TX:
370 sprintf(dev_name, "%s%s%u-port-tx%d", "/dev/", DEV_FM_NAME,
371 (uint32_t)((t_device *)p_fm_port_params->h_fm)->id,
372 p_fm_port_params->port_id);
374 case e_FM_PORT_TYPE_TX_10G:
375 sprintf(dev_name, "%s%s%u-port-tx%d", "/dev/", DEV_FM_NAME,
376 (uint32_t)((t_device *)p_fm_port_params->h_fm)->id,
377 FM_MAX_NUM_OF_1G_TX_PORTS + p_fm_port_params->port_id);
385 fd = open(dev_name, O_RDWR);
392 p_fm_port->port_type = p_fm_port_params->port_type;
393 p_fm_port->port_id = p_fm_port_params->port_id;
394 p_dev->id = p_fm_port_params->port_id;
396 p_dev->h_user_priv = (t_handle)p_fm_port;
398 _fml_dbg("Finishing.\n");
400 return (t_handle)p_dev;
404 fm_port_close(t_handle h_fm_port)
406 t_device *p_dev = (t_device *)h_fm_port;
408 _fml_dbg("Calling...\n");
411 if (p_dev->h_user_priv)
412 free(p_dev->h_user_priv);
415 _fml_dbg("Finishing.\n");
419 fm_port_disable(t_handle h_fm_port)
421 t_device *p_dev = (t_device *)h_fm_port;
423 _fml_dbg("Calling...\n");
425 if (ioctl(p_dev->fd, FM_PORT_IOC_DISABLE))
426 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
428 _fml_dbg("Finishing.\n");
434 fm_port_enable(t_handle h_fm_port)
436 t_device *p_dev = (t_device *)h_fm_port;
438 _fml_dbg("Calling...\n");
440 if (ioctl(p_dev->fd, FM_PORT_IOC_ENABLE))
441 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
443 _fml_dbg("Finishing.\n");
449 fm_port_set_pcd(t_handle h_fm_port,
450 ioc_fm_port_pcd_params_t *p)
452 t_device *p_dev = (t_device *)h_fm_port;
454 _fml_dbg("Calling...\n");
456 /* correct h_net_env param from t_fm_portPcdParams */
457 DEV_TO_ID(p->net_env_id);
459 /* correct pcd structures according to what support was set */
460 if (p->pcd_support == e_IOC_FM_PCD_PRS_KG_AND_CC ||
461 p->pcd_support == e_IOC_FM_PCD_PRS_KG_AND_CC_AND_PLCR ||
462 p->pcd_support == e_IOC_FM_PCD_PRS_CC) {
463 if (p->p_cc_params && p->p_cc_params->cc_tree_id)
464 DEV_TO_ID(p->p_cc_params->cc_tree_id);
466 DPAA_PMD_WARN("Coarse Classification not set !");
469 if (p->pcd_support == e_IOC_FM_PCD_PRS_KG ||
470 p->pcd_support == e_IOC_FM_PCD_PRS_KG_AND_CC ||
471 p->pcd_support == e_IOC_FM_PCD_PRS_KG_AND_CC_AND_PLCR ||
472 p->pcd_support == e_IOC_FM_PCD_PRS_KG_AND_PLCR){
473 if (p->p_kg_params) {
475 ioc_fm_port_pcd_kg_params_t *kg_params;
477 kg_params = p->p_kg_params;
479 for (i = 0; i < kg_params->num_schemes; i++)
480 if (kg_params->scheme_ids[i])
481 DEV_TO_ID(kg_params->scheme_ids[i]);
483 DPAA_PMD_WARN("Scheme:%u not set!!", i);
485 if (kg_params->direct_scheme)
486 DEV_TO_ID(kg_params->direct_scheme_id);
488 DPAA_PMD_WARN("KeyGen not set !");
492 if (p->pcd_support == e_IOC_FM_PCD_PLCR_ONLY ||
493 p->pcd_support == e_IOC_FM_PCD_PRS_PLCR ||
494 p->pcd_support == e_IOC_FM_PCD_PRS_KG_AND_CC_AND_PLCR ||
495 p->pcd_support == e_IOC_FM_PCD_PRS_KG_AND_PLCR) {
496 if (p->p_plcr_params) {
497 if (p->p_plcr_params->plcr_profile_id)
498 DEV_TO_ID(p->p_plcr_params->plcr_profile_id);
500 DPAA_PMD_WARN("Policer not set !");
504 if (p->p_ip_reassembly_manip)
505 DEV_TO_ID(p->p_ip_reassembly_manip);
507 if (p->p_capwap_reassembly_manip)
508 DEV_TO_ID(p->p_capwap_reassembly_manip);
510 if (ioctl(p_dev->fd, FM_PORT_IOC_SET_PCD, p))
511 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
513 _fml_dbg("Finishing.\n");
519 fm_port_delete_pcd(t_handle h_fm_port)
521 t_device *p_dev = (t_device *)h_fm_port;
523 _fml_dbg("Calling...\n");
525 if (ioctl(p_dev->fd, FM_PORT_IOC_DELETE_PCD))
526 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
528 _fml_dbg("Finishing.\n");
534 create_device(t_handle h_user_priv, t_handle h_dev_id)
536 t_device *p_user_priv_dev = (t_device *)h_user_priv;
537 t_device *p_dev = NULL;
539 _fml_dbg("Calling...\n");
541 p_dev = (t_device *)malloc(sizeof(t_device));
545 memset(p_dev, 0, sizeof(t_device));
546 p_dev->h_user_priv = h_user_priv;
547 p_user_priv_dev->owners++;
548 p_dev->id = PTR_TO_UINT(h_dev_id);
550 _fml_dbg("Finishing.\n");
552 return (t_handle)p_dev;
556 get_device_id(t_handle h_dev)
558 t_device *p_dev = (t_device *)h_dev;
560 return (t_handle)p_dev->id;