dpdk/drivers/net/dpaa/fmlib/fm_lib.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright 2008-2016 Freescale Semiconductor Inc.
   3 * Copyright 2017-2020 NXP
   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/* 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
  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        /* 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);
 270
 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);
 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        /* increase owners only if a new scheme is created */
 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;      /**< Port type */
 327        uint8_t         port_id;        /**< Port Id - relative to type */
 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        /* correct h_net_env param from t_fm_portPcdParams */
 457        DEV_TO_ID(p->net_env_id);
 458
 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);
 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