dpdk/examples/ip_pipeline/kni.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2010-2018 Intel Corporation
   3 */
   4
   5#include <stdlib.h>
   6#include <string.h>
   7
   8#include <rte_ethdev.h>
   9#include <rte_bus_pci.h>
  10#include <rte_string_fns.h>
  11
  12#include "kni.h"
  13#include "mempool.h"
  14#include "link.h"
  15
  16static struct kni_list kni_list;
  17
  18#ifndef KNI_MAX
  19#define KNI_MAX                                            16
  20#endif
  21
  22int
  23kni_init(void)
  24{
  25        TAILQ_INIT(&kni_list);
  26
  27#ifdef RTE_LIB_KNI
  28        rte_kni_init(KNI_MAX);
  29#endif
  30
  31        return 0;
  32}
  33
  34struct kni *
  35kni_find(const char *name)
  36{
  37        struct kni *kni;
  38
  39        if (name == NULL)
  40                return NULL;
  41
  42        TAILQ_FOREACH(kni, &kni_list, node)
  43                if (strcmp(kni->name, name) == 0)
  44                        return kni;
  45
  46        return NULL;
  47}
  48
  49#ifndef RTE_LIB_KNI
  50
  51struct kni *
  52kni_create(const char *name __rte_unused,
  53        struct kni_params *params __rte_unused)
  54{
  55        return NULL;
  56}
  57
  58void
  59kni_handle_request(void)
  60{
  61        return;
  62}
  63
  64#else
  65
  66static int
  67kni_config_network_interface(uint16_t port_id, uint8_t if_up)
  68{
  69        int ret = 0;
  70
  71        if (!rte_eth_dev_is_valid_port(port_id))
  72                return -EINVAL;
  73
  74        ret = (if_up) ?
  75                rte_eth_dev_set_link_up(port_id) :
  76                rte_eth_dev_set_link_down(port_id);
  77
  78        return ret;
  79}
  80
  81static int
  82kni_change_mtu(uint16_t port_id, unsigned int new_mtu)
  83{
  84        int ret;
  85
  86        if (!rte_eth_dev_is_valid_port(port_id))
  87                return -EINVAL;
  88
  89        if (new_mtu > RTE_ETHER_MAX_LEN)
  90                return -EINVAL;
  91
  92        /* Set new MTU */
  93        ret = rte_eth_dev_set_mtu(port_id, new_mtu);
  94        if (ret < 0)
  95                return ret;
  96
  97        return 0;
  98}
  99
 100struct kni *
 101kni_create(const char *name, struct kni_params *params)
 102{
 103        struct rte_eth_dev_info dev_info;
 104        struct rte_kni_conf kni_conf;
 105        struct rte_kni_ops kni_ops;
 106        struct kni *kni;
 107        struct mempool *mempool;
 108        struct link *link;
 109        struct rte_kni *k;
 110        const struct rte_pci_device *pci_dev;
 111        const struct rte_bus *bus = NULL;
 112        int ret;
 113
 114        /* Check input params */
 115        if ((name == NULL) ||
 116                kni_find(name) ||
 117                (params == NULL))
 118                return NULL;
 119
 120        mempool = mempool_find(params->mempool_name);
 121        link = link_find(params->link_name);
 122        if ((mempool == NULL) ||
 123                (link == NULL))
 124                return NULL;
 125
 126        /* Resource create */
 127        ret = rte_eth_dev_info_get(link->port_id, &dev_info);
 128        if (ret != 0)
 129                return NULL;
 130
 131        memset(&kni_conf, 0, sizeof(kni_conf));
 132        strlcpy(kni_conf.name, name, RTE_KNI_NAMESIZE);
 133        kni_conf.force_bind = params->force_bind;
 134        kni_conf.core_id = params->thread_id;
 135        kni_conf.group_id = link->port_id;
 136        kni_conf.mbuf_size = mempool->buffer_size;
 137        if (dev_info.device)
 138                bus = rte_bus_find_by_device(dev_info.device);
 139        if (bus && !strcmp(bus->name, "pci")) {
 140                pci_dev = RTE_DEV_TO_PCI(dev_info.device);
 141                kni_conf.addr = pci_dev->addr;
 142                kni_conf.id = pci_dev->id;
 143        }
 144
 145        memset(&kni_ops, 0, sizeof(kni_ops));
 146        kni_ops.port_id = link->port_id;
 147        kni_ops.config_network_if = kni_config_network_interface;
 148        kni_ops.change_mtu = kni_change_mtu;
 149
 150        k = rte_kni_alloc(mempool->m, &kni_conf, &kni_ops);
 151        if (k == NULL)
 152                return NULL;
 153
 154        /* Node allocation */
 155        kni = calloc(1, sizeof(struct kni));
 156        if (kni == NULL)
 157                return NULL;
 158
 159        /* Node fill in */
 160        strlcpy(kni->name, name, sizeof(kni->name));
 161        kni->k = k;
 162
 163        /* Node add to list */
 164        TAILQ_INSERT_TAIL(&kni_list, kni, node);
 165
 166        return kni;
 167}
 168
 169void
 170kni_handle_request(void)
 171{
 172        struct kni *kni;
 173
 174        TAILQ_FOREACH(kni, &kni_list, node)
 175                rte_kni_handle_request(kni->k);
 176}
 177
 178#endif
 179