xref: /f-stack/dpdk/examples/ip_pipeline/kni.c (revision 2d9fd380)
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
kni_init(void)23 kni_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 
34 struct kni *
kni_find(const char * name)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_LIB_KNI
50 
51 struct kni *
kni_create(const char * name __rte_unused,struct kni_params * params __rte_unused)52 kni_create(const char *name __rte_unused,
53 	struct kni_params *params __rte_unused)
54 {
55 	return NULL;
56 }
57 
58 void
kni_handle_request(void)59 kni_handle_request(void)
60 {
61 	return;
62 }
63 
64 #else
65 
66 static int
kni_config_network_interface(uint16_t port_id,uint8_t if_up)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
kni_change_mtu(uint16_t port_id,unsigned int new_mtu)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 *
kni_create(const char * name,struct kni_params * params)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
kni_handle_request(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
179