1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2021 6WIND S.A.
3 */
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8
9 #include <rte_common.h>
10 #include <rte_kvargs.h>
11 #include <bus_driver.h>
12 #include <rte_bus_vdev.h>
13
14 #include "test.h"
15
16 #define TEST_VDEV_KEY_NAME "name"
17
18 static const char * const valid_keys[] = {
19 TEST_VDEV_KEY_NAME,
20 NULL,
21 };
22
23 static int
cmp_dev_name(const struct rte_device * dev,const void * name)24 cmp_dev_name(const struct rte_device *dev, const void *name)
25 {
26 return strcmp(rte_dev_name(dev), name);
27 }
28
29 static int
cmp_dev_match(const struct rte_device * dev,const void * _kvlist)30 cmp_dev_match(const struct rte_device *dev, const void *_kvlist)
31 {
32 const struct rte_kvargs *kvlist = _kvlist;
33 const char *key = TEST_VDEV_KEY_NAME;
34 const char *name;
35
36 /* no kvlist arg, all devices match */
37 if (kvlist == NULL)
38 return 0;
39
40 /* if key is present in kvlist and does not match, filter device */
41 name = rte_kvargs_get(kvlist, key);
42 if (name != NULL && strcmp(name, rte_dev_name(dev)) != 0)
43 return -1;
44
45 return 0;
46 }
47
48 static struct rte_device *
get_matching_vdev(const char * match_str)49 get_matching_vdev(const char *match_str)
50 {
51 struct rte_bus *vdev_bus = rte_bus_find_by_name("vdev");
52 struct rte_kvargs *kvargs = NULL;
53 struct rte_device *dev;
54
55 if (match_str != NULL) {
56 kvargs = rte_kvargs_parse(match_str, valid_keys);
57 if (kvargs == NULL) {
58 printf("Failed to parse match string\n");
59 return NULL;
60 }
61 }
62
63 dev = vdev_bus->find_device(NULL, cmp_dev_match, kvargs);
64 rte_kvargs_free(kvargs);
65
66 return dev;
67 }
68
69 static int
test_vdev_bus(void)70 test_vdev_bus(void)
71 {
72 struct rte_bus *vdev_bus = rte_bus_find_by_name("vdev");
73 struct rte_dev_iterator dev_iter = { 0 };
74 struct rte_device *dev, *dev0, *dev1;
75
76 /* not supported */
77 if (vdev_bus == NULL)
78 return 0;
79
80 /* create first vdev */
81 if (rte_vdev_init("net_null_test0", "") < 0) {
82 printf("Failed to create vdev net_null_test0\n");
83 goto fail;
84 }
85 dev0 = vdev_bus->find_device(NULL, cmp_dev_name, "net_null_test0");
86 if (dev0 == NULL) {
87 printf("Cannot find net_null_test0 vdev\n");
88 goto fail;
89 }
90
91 /* create second vdev */
92 if (rte_vdev_init("net_null_test1", "") < 0) {
93 printf("Failed to create vdev net_null_test1\n");
94 goto fail;
95 }
96 dev1 = vdev_bus->find_device(NULL, cmp_dev_name, "net_null_test1");
97 if (dev1 == NULL) {
98 printf("Cannot find net_null_test1 vdev\n");
99 goto fail;
100 }
101
102 /* try to match vdevs */
103 dev = get_matching_vdev("name=net_null_test0");
104 if (dev != dev0) {
105 printf("Cannot match net_null_test0 vdev\n");
106 goto fail;
107 }
108
109 dev = get_matching_vdev("name=net_null_test1");
110 if (dev != dev1) {
111 printf("Cannot match net_null_test1 vdev\n");
112 goto fail;
113 }
114
115 dev = get_matching_vdev("name=unexistant");
116 if (dev != NULL) {
117 printf("Unexistant vdev should not match\n");
118 goto fail;
119 }
120
121 dev = get_matching_vdev("");
122 if (dev == NULL || dev == dev1) {
123 printf("Cannot match any vdev with empty match string\n");
124 goto fail;
125 }
126
127 dev = get_matching_vdev(NULL);
128 if (dev == NULL || dev == dev1) {
129 printf("Cannot match any vdev with NULL match string\n");
130 goto fail;
131 }
132
133 /* iterate all vdevs, and ensure we find vdev0 and vdev1 */
134 RTE_DEV_FOREACH(dev, "bus=vdev", &dev_iter) {
135 if (dev == dev0)
136 dev0 = NULL;
137 else if (dev == dev1)
138 dev1 = NULL;
139 }
140 if (dev0 != NULL) {
141 printf("dev0 was not iterated\n");
142 goto fail;
143 }
144 if (dev1 != NULL) {
145 printf("dev1 was not iterated\n");
146 goto fail;
147 }
148
149 rte_vdev_uninit("net_null_test0");
150 rte_vdev_uninit("net_null_test1");
151
152 return 0;
153
154 fail:
155 rte_vdev_uninit("net_null_test0");
156 rte_vdev_uninit("net_null_test1");
157 return -1;
158 }
159
160 static int
test_vdev(void)161 test_vdev(void)
162 {
163 printf("== test vdev bus ==\n");
164 if (test_vdev_bus() < 0)
165 return -1;
166 return 0;
167 }
168
169 REGISTER_FAST_TEST(vdev_autotest, true, true, test_vdev);
170