1
2
3
4
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <fcntl.h>
10#include <errno.h>
11#include <unistd.h>
12#include <termios.h>
13#include <sys/ioctl.h>
14#include <stdbool.h>
15#include <rte_common.h>
16
17#include "fm_ext.h"
18#include "fm_pcd_ext.h"
19#include "fm_port_ext.h"
20#include <dpaa_ethdev.h>
21
22#define DEV_TO_ID(p) \
23 do { \
24 t_device *p_dev = (t_device *)p; \
25 p = UINT_TO_PTR(p_dev->id); \
26 } while (0)
27
28
29#define FM_LIB_VERSION_MAJOR 21
30#define FM_LIB_VERSION_MINOR 1
31#define FM_LIB_VERSION_RESPIN 0
32
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
36#endif
37
38t_handle
39fm_open(uint8_t id)
40{
41 t_device *p_dev;
42 int fd;
43 char dev_name[20];
44 static bool called;
45 ioc_fm_api_version_t ver;
46
47 _fml_dbg("Calling...\n");
48
49 p_dev = (t_device *)malloc(sizeof(t_device));
50 if (p_dev == NULL)
51 return NULL;
52
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);
56 if (fd < 0) {
57 free(p_dev);
58 return NULL;
59 }
60
61 p_dev->id = id;
62 p_dev->fd = fd;
63 if (!called) {
64 called = true;
65 fm_get_api_version((t_handle)p_dev, &ver);
66
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,
75 ver.version.respin);
76 }
77 }
78 _fml_dbg("Finishing.\n");
79
80 return (t_handle)p_dev;
81}
82
83void fm_close(t_handle h_fm)
84{
85 t_device *p_dev = (t_device *)h_fm;
86
87 _fml_dbg("Calling...\n");
88
89 close(p_dev->fd);
90 free(p_dev);
91
92 _fml_dbg("Finishing.\n");
93}
94
95uint32_t
96fm_get_api_version(t_handle h_fm, ioc_fm_api_version_t *p_version)
97{
98 t_device *p_dev = (t_device *)h_fm;
99 int ret;
100
101 _fml_dbg("Calling...\n");
102
103 ret = ioctl(p_dev->fd, FM_IOC_GET_API_VERSION, p_version);
104 if (ret) {
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);
108 }
109 _fml_dbg("Finishing.\n");
110
111 return E_OK;
112}
113
114t_handle
115fm_pcd_open(t_fm_pcd_params *p_fm_pcd_params)
116{
117 t_device *p_dev;
118 int fd;
119 char dev_name[20];
120
121 _fml_dbg("Calling...\n");
122
123 p_dev = (t_device *)malloc(sizeof(t_device));
124 if (p_dev == NULL)
125 return NULL;
126
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);
131 if (fd < 0) {
132 free(p_dev);
133 return NULL;
134 }
135
136 p_dev->id = ((t_device *)p_fm_pcd_params->h_fm)->id;
137 p_dev->fd = fd;
138 p_dev->owners = 0;
139
140 _fml_dbg("Finishing.\n");
141
142 return (t_handle)p_dev;
143}
144
145void
146fm_pcd_close(t_handle h_fm_pcd)
147{
148 t_device *p_dev = (t_device *)h_fm_pcd;
149
150 _fml_dbg("Calling...\n");
151
152 close(p_dev->fd);
153
154 if (p_dev->owners) {
155 printf("\nTry delete a prev created pcd handler(owners:%u)!\n",
156 p_dev->owners);
157 return;
158 }
159
160 free(p_dev);
161
162 _fml_dbg("Finishing.\n");
163}
164
165uint32_t
166fm_pcd_enable(t_handle h_fm_pcd)
167{
168 t_device *p_dev = (t_device *)h_fm_pcd;
169
170 _fml_dbg("Calling...\n");
171
172 if (ioctl(p_dev->fd, FM_PCD_IOC_ENABLE))
173 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
174
175 _fml_dbg("Finishing.\n");
176
177 return E_OK;
178}
179
180uint32_t
181fm_pcd_disable(t_handle h_fm_pcd)
182{
183 t_device *p_dev = (t_device *)h_fm_pcd;
184
185 _fml_dbg("Calling...\n");
186
187 if (ioctl(p_dev->fd, FM_PCD_IOC_DISABLE))
188 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
189
190 _fml_dbg("Finishing.\n");
191
192 return E_OK;
193}
194
195t_handle
196fm_pcd_net_env_characteristics_set(t_handle h_fm_pcd,
197 ioc_fm_pcd_net_env_params_t *params)
198{
199 t_device *p_pcd_dev = (t_device *)h_fm_pcd;
200 t_device *p_dev = NULL;
201
202 _fml_dbg("Calling...\n");
203
204 params->id = NULL;
205
206 if (ioctl(p_pcd_dev->fd, FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET,
207 params))
208 return NULL;
209
210 p_dev = (t_device *)malloc(sizeof(t_device));
211 if (p_dev == NULL)
212 return NULL;
213
214 memset(p_dev, 0, sizeof(t_device));
215 p_dev->h_user_priv = (t_handle)p_pcd_dev;
216 p_pcd_dev->owners++;
217 p_dev->id = PTR_TO_UINT(params->id);
218
219 _fml_dbg("Finishing.\n");
220
221 return (t_handle)p_dev;
222}
223
224uint32_t
225fm_pcd_net_env_characteristics_delete(t_handle h_net_env)
226{
227 t_device *p_dev = (t_device *)h_net_env;
228 t_device *p_pcd_dev = NULL;
229 ioc_fm_obj_t id;
230
231 _fml_dbg("Calling...\n");
232
233 p_pcd_dev = (t_device *)p_dev->h_user_priv;
234 id.obj = UINT_TO_PTR(p_dev->id);
235
236 if (ioctl(p_pcd_dev->fd, FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE,
237 &id))
238 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
239
240 p_pcd_dev->owners--;
241 free(p_dev);
242
243 _fml_dbg("Finishing.\n");
244
245 return E_OK;
246}
247
248t_handle
249fm_pcd_kg_scheme_set(t_handle h_fm_pcd,
250 ioc_fm_pcd_kg_scheme_params_t *params)
251{
252 t_device *p_pcd_dev = (t_device *)h_fm_pcd;
253 t_device *p_dev = NULL;
254 int ret;
255
256 _fml_dbg("Calling...\n");
257
258 params->id = NULL;
259
260 if (params->param.modify) {
261 if (params->param.scm_id.scheme_id)
262 DEV_TO_ID(params->param.scm_id.scheme_id);
263 else
264 return NULL;
265 }
266
267
268 if (params->param.net_env_params.net_env_id)
269 DEV_TO_ID(params->param.net_env_params.net_env_id);
270
271
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);
275
276 ret = ioctl(p_pcd_dev->fd, FM_PCD_IOC_KG_SCHEME_SET, params);
277 if (ret) {
278 DPAA_PMD_ERR(" cannot set kg scheme, error %i (%s)\n",
279 errno, strerror(errno));
280 return NULL;
281 }
282
283 p_dev = (t_device *)malloc(sizeof(t_device));
284 if (p_dev == NULL)
285 return NULL;
286
287 memset(p_dev, 0, sizeof(t_device));
288 p_dev->h_user_priv = (t_handle)p_pcd_dev;
289
290 if (!params->param.modify)
291 p_pcd_dev->owners++;
292 p_dev->id = PTR_TO_UINT(params->id);
293
294 _fml_dbg("Finishing.\n");
295
296 return (t_handle)p_dev;
297}
298
299uint32_t
300fm_pcd_kg_scheme_delete(t_handle h_scheme)
301{
302 t_device *p_dev = (t_device *)h_scheme;
303 t_device *p_pcd_dev = NULL;
304 ioc_fm_obj_t id;
305
306 _fml_dbg("Calling...\n");
307
308 p_pcd_dev = (t_device *)p_dev->h_user_priv;
309 id.obj = UINT_TO_PTR(p_dev->id);
310
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);
315 }
316
317 p_pcd_dev->owners--;
318 free(p_dev);
319
320 _fml_dbg("Finishing.\n");
321
322 return E_OK;
323}
324
325typedef struct {
326 e_fm_port_type port_type;
327 uint8_t port_id;
328} t_fm_port;
329
330t_handle
331fm_port_open(t_fm_port_params *p_fm_port_params)
332{
333 t_device *p_dev;
334 int fd;
335 char dev_name[30];
336 t_fm_port *p_fm_port;
337
338 _fml_dbg("Calling...\n");
339
340 p_dev = (t_device *)malloc(sizeof(t_device));
341 if (p_dev == NULL)
342 return NULL;
343
344 memset(p_dev, 0, sizeof(t_device));
345
346 p_fm_port = (t_fm_port *)malloc(sizeof(t_fm_port));
347 if (!p_fm_port) {
348 free(p_dev);
349 return NULL;
350 }
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);
358 break;
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);
363 break;
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);
368 break;
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);
373 break;
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);
378 break;
379 default:
380 free(p_fm_port);
381 free(p_dev);
382 return NULL;
383 }
384
385 fd = open(dev_name, O_RDWR);
386 if (fd < 0) {
387 free(p_fm_port);
388 free(p_dev);
389 return NULL;
390 }
391
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;
395 p_dev->fd = fd;
396 p_dev->h_user_priv = (t_handle)p_fm_port;
397
398 _fml_dbg("Finishing.\n");
399
400 return (t_handle)p_dev;
401}
402
403void
404fm_port_close(t_handle h_fm_port)
405{
406 t_device *p_dev = (t_device *)h_fm_port;
407
408 _fml_dbg("Calling...\n");
409
410 close(p_dev->fd);
411 if (p_dev->h_user_priv)
412 free(p_dev->h_user_priv);
413 free(p_dev);
414
415 _fml_dbg("Finishing.\n");
416}
417
418uint32_t
419fm_port_disable(t_handle h_fm_port)
420{
421 t_device *p_dev = (t_device *)h_fm_port;
422
423 _fml_dbg("Calling...\n");
424
425 if (ioctl(p_dev->fd, FM_PORT_IOC_DISABLE))
426 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
427
428 _fml_dbg("Finishing.\n");
429
430 return E_OK;
431}
432
433uint32_t
434fm_port_enable(t_handle h_fm_port)
435{
436 t_device *p_dev = (t_device *)h_fm_port;
437
438 _fml_dbg("Calling...\n");
439
440 if (ioctl(p_dev->fd, FM_PORT_IOC_ENABLE))
441 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
442
443 _fml_dbg("Finishing.\n");
444
445 return E_OK;
446}
447
448uint32_t
449fm_port_set_pcd(t_handle h_fm_port,
450 ioc_fm_port_pcd_params_t *p)
451{
452 t_device *p_dev = (t_device *)h_fm_port;
453
454 _fml_dbg("Calling...\n");
455
456
457 DEV_TO_ID(p->net_env_id);
458
459
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);
465 else
466 DPAA_PMD_WARN("Coarse Classification not set !");
467 }
468
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) {
474 uint32_t i;
475 ioc_fm_port_pcd_kg_params_t *kg_params;
476
477 kg_params = p->p_kg_params;
478
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]);
482 else
483 DPAA_PMD_WARN("Scheme:%u not set!!", i);
484
485 if (kg_params->direct_scheme)
486 DEV_TO_ID(kg_params->direct_scheme_id);
487 } else {
488 DPAA_PMD_WARN("KeyGen not set !");
489 }
490 }
491
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);
499 else
500 DPAA_PMD_WARN("Policer not set !");
501 }
502 }
503
504 if (p->p_ip_reassembly_manip)
505 DEV_TO_ID(p->p_ip_reassembly_manip);
506
507 if (p->p_capwap_reassembly_manip)
508 DEV_TO_ID(p->p_capwap_reassembly_manip);
509
510 if (ioctl(p_dev->fd, FM_PORT_IOC_SET_PCD, p))
511 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
512
513 _fml_dbg("Finishing.\n");
514
515 return E_OK;
516}
517
518uint32_t
519fm_port_delete_pcd(t_handle h_fm_port)
520{
521 t_device *p_dev = (t_device *)h_fm_port;
522
523 _fml_dbg("Calling...\n");
524
525 if (ioctl(p_dev->fd, FM_PORT_IOC_DELETE_PCD))
526 RETURN_ERROR(MINOR, E_INVALID_OPERATION, NO_MSG);
527
528 _fml_dbg("Finishing.\n");
529
530 return E_OK;
531}
532
533t_handle
534create_device(t_handle h_user_priv, t_handle h_dev_id)
535{
536 t_device *p_user_priv_dev = (t_device *)h_user_priv;
537 t_device *p_dev = NULL;
538
539 _fml_dbg("Calling...\n");
540
541 p_dev = (t_device *)malloc(sizeof(t_device));
542 if (p_dev == NULL)
543 return NULL;
544
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);
549
550 _fml_dbg("Finishing.\n");
551
552 return (t_handle)p_dev;
553}
554
555t_handle
556get_device_id(t_handle h_dev)
557{
558 t_device *p_dev = (t_device *)h_dev;
559
560 return (t_handle)p_dev->id;
561}
562