examples/l3fwd-power: disable interrupts by default
[dpdk.git] / examples / ip_pipeline / kni.c
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
16 static struct kni_list kni_list;
17
18 #ifndef KNI_MAX
19 #define KNI_MAX                                            16
20 #endif
21
22 int
23 kni_init(void)
24 {
25         TAILQ_INIT(&kni_list);
26
27 #ifdef RTE_LIBRTE_KNI
28         rte_kni_init(KNI_MAX);
29 #endif
30
31         return 0;
32 }
33
34 struct kni *
35 kni_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_LIBRTE_KNI
50
51 struct kni *
52 kni_create(const char *name __rte_unused,
53         struct kni_params *params __rte_unused)
54 {
55         return NULL;
56 }
57
58 void
59 kni_handle_request(void)
60 {
61         return;
62 }
63
64 #else
65
66 static int
67 kni_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
81 static int
82 kni_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
100 struct kni *
101 kni_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
169 void
170 kni_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