1926629e3SXueming Li /* SPDX-License-Identifier: BSD-3-Clause
2926629e3SXueming Li * Copyright 2021 6WIND S.A.
3926629e3SXueming Li */
4926629e3SXueming Li
5926629e3SXueming Li #include <stdlib.h>
6926629e3SXueming Li #include <stdio.h>
7926629e3SXueming Li #include <string.h>
8926629e3SXueming Li
9926629e3SXueming Li #include <rte_common.h>
10926629e3SXueming Li #include <rte_kvargs.h>
11a04322f6SDavid Marchand #include <bus_driver.h>
12926629e3SXueming Li #include <rte_bus_vdev.h>
13926629e3SXueming Li
14926629e3SXueming Li #include "test.h"
15926629e3SXueming Li
16926629e3SXueming Li #define TEST_VDEV_KEY_NAME "name"
17926629e3SXueming Li
18926629e3SXueming Li static const char * const valid_keys[] = {
19926629e3SXueming Li TEST_VDEV_KEY_NAME,
20926629e3SXueming Li NULL,
21926629e3SXueming Li };
22926629e3SXueming Li
23926629e3SXueming Li static int
cmp_dev_name(const struct rte_device * dev,const void * name)24926629e3SXueming Li cmp_dev_name(const struct rte_device *dev, const void *name)
25926629e3SXueming Li {
26ec5ecd7eSDavid Marchand return strcmp(rte_dev_name(dev), name);
27926629e3SXueming Li }
28926629e3SXueming Li
29926629e3SXueming Li static int
cmp_dev_match(const struct rte_device * dev,const void * _kvlist)30926629e3SXueming Li cmp_dev_match(const struct rte_device *dev, const void *_kvlist)
31926629e3SXueming Li {
32926629e3SXueming Li const struct rte_kvargs *kvlist = _kvlist;
33926629e3SXueming Li const char *key = TEST_VDEV_KEY_NAME;
34926629e3SXueming Li const char *name;
35926629e3SXueming Li
36926629e3SXueming Li /* no kvlist arg, all devices match */
37926629e3SXueming Li if (kvlist == NULL)
38926629e3SXueming Li return 0;
39926629e3SXueming Li
40926629e3SXueming Li /* if key is present in kvlist and does not match, filter device */
41926629e3SXueming Li name = rte_kvargs_get(kvlist, key);
42ec5ecd7eSDavid Marchand if (name != NULL && strcmp(name, rte_dev_name(dev)) != 0)
43926629e3SXueming Li return -1;
44926629e3SXueming Li
45926629e3SXueming Li return 0;
46926629e3SXueming Li }
47926629e3SXueming Li
48926629e3SXueming Li static struct rte_device *
get_matching_vdev(const char * match_str)49926629e3SXueming Li get_matching_vdev(const char *match_str)
50926629e3SXueming Li {
51926629e3SXueming Li struct rte_bus *vdev_bus = rte_bus_find_by_name("vdev");
52926629e3SXueming Li struct rte_kvargs *kvargs = NULL;
53926629e3SXueming Li struct rte_device *dev;
54926629e3SXueming Li
55926629e3SXueming Li if (match_str != NULL) {
56926629e3SXueming Li kvargs = rte_kvargs_parse(match_str, valid_keys);
57926629e3SXueming Li if (kvargs == NULL) {
58926629e3SXueming Li printf("Failed to parse match string\n");
59926629e3SXueming Li return NULL;
60926629e3SXueming Li }
61926629e3SXueming Li }
62926629e3SXueming Li
63926629e3SXueming Li dev = vdev_bus->find_device(NULL, cmp_dev_match, kvargs);
64926629e3SXueming Li rte_kvargs_free(kvargs);
65926629e3SXueming Li
66926629e3SXueming Li return dev;
67926629e3SXueming Li }
68926629e3SXueming Li
69926629e3SXueming Li static int
test_vdev_bus(void)70926629e3SXueming Li test_vdev_bus(void)
71926629e3SXueming Li {
72926629e3SXueming Li struct rte_bus *vdev_bus = rte_bus_find_by_name("vdev");
73926629e3SXueming Li struct rte_dev_iterator dev_iter = { 0 };
74926629e3SXueming Li struct rte_device *dev, *dev0, *dev1;
75926629e3SXueming Li
76926629e3SXueming Li /* not supported */
77926629e3SXueming Li if (vdev_bus == NULL)
78926629e3SXueming Li return 0;
79926629e3SXueming Li
80926629e3SXueming Li /* create first vdev */
81926629e3SXueming Li if (rte_vdev_init("net_null_test0", "") < 0) {
82926629e3SXueming Li printf("Failed to create vdev net_null_test0\n");
83926629e3SXueming Li goto fail;
84926629e3SXueming Li }
85926629e3SXueming Li dev0 = vdev_bus->find_device(NULL, cmp_dev_name, "net_null_test0");
86926629e3SXueming Li if (dev0 == NULL) {
87926629e3SXueming Li printf("Cannot find net_null_test0 vdev\n");
88926629e3SXueming Li goto fail;
89926629e3SXueming Li }
90926629e3SXueming Li
91926629e3SXueming Li /* create second vdev */
92926629e3SXueming Li if (rte_vdev_init("net_null_test1", "") < 0) {
93926629e3SXueming Li printf("Failed to create vdev net_null_test1\n");
94926629e3SXueming Li goto fail;
95926629e3SXueming Li }
96926629e3SXueming Li dev1 = vdev_bus->find_device(NULL, cmp_dev_name, "net_null_test1");
97926629e3SXueming Li if (dev1 == NULL) {
98926629e3SXueming Li printf("Cannot find net_null_test1 vdev\n");
99926629e3SXueming Li goto fail;
100926629e3SXueming Li }
101926629e3SXueming Li
102926629e3SXueming Li /* try to match vdevs */
103926629e3SXueming Li dev = get_matching_vdev("name=net_null_test0");
104926629e3SXueming Li if (dev != dev0) {
105926629e3SXueming Li printf("Cannot match net_null_test0 vdev\n");
106926629e3SXueming Li goto fail;
107926629e3SXueming Li }
108926629e3SXueming Li
109926629e3SXueming Li dev = get_matching_vdev("name=net_null_test1");
110926629e3SXueming Li if (dev != dev1) {
111926629e3SXueming Li printf("Cannot match net_null_test1 vdev\n");
112926629e3SXueming Li goto fail;
113926629e3SXueming Li }
114926629e3SXueming Li
115926629e3SXueming Li dev = get_matching_vdev("name=unexistant");
116926629e3SXueming Li if (dev != NULL) {
117926629e3SXueming Li printf("Unexistant vdev should not match\n");
118926629e3SXueming Li goto fail;
119926629e3SXueming Li }
120926629e3SXueming Li
121926629e3SXueming Li dev = get_matching_vdev("");
122926629e3SXueming Li if (dev == NULL || dev == dev1) {
123926629e3SXueming Li printf("Cannot match any vdev with empty match string\n");
124926629e3SXueming Li goto fail;
125926629e3SXueming Li }
126926629e3SXueming Li
127926629e3SXueming Li dev = get_matching_vdev(NULL);
128926629e3SXueming Li if (dev == NULL || dev == dev1) {
129926629e3SXueming Li printf("Cannot match any vdev with NULL match string\n");
130926629e3SXueming Li goto fail;
131926629e3SXueming Li }
132926629e3SXueming Li
133926629e3SXueming Li /* iterate all vdevs, and ensure we find vdev0 and vdev1 */
134926629e3SXueming Li RTE_DEV_FOREACH(dev, "bus=vdev", &dev_iter) {
135926629e3SXueming Li if (dev == dev0)
136926629e3SXueming Li dev0 = NULL;
137926629e3SXueming Li else if (dev == dev1)
138926629e3SXueming Li dev1 = NULL;
139926629e3SXueming Li }
140926629e3SXueming Li if (dev0 != NULL) {
141926629e3SXueming Li printf("dev0 was not iterated\n");
142926629e3SXueming Li goto fail;
143926629e3SXueming Li }
144926629e3SXueming Li if (dev1 != NULL) {
145926629e3SXueming Li printf("dev1 was not iterated\n");
146926629e3SXueming Li goto fail;
147926629e3SXueming Li }
148926629e3SXueming Li
149926629e3SXueming Li rte_vdev_uninit("net_null_test0");
150926629e3SXueming Li rte_vdev_uninit("net_null_test1");
151926629e3SXueming Li
152926629e3SXueming Li return 0;
153926629e3SXueming Li
154926629e3SXueming Li fail:
155926629e3SXueming Li rte_vdev_uninit("net_null_test0");
156926629e3SXueming Li rte_vdev_uninit("net_null_test1");
157926629e3SXueming Li return -1;
158926629e3SXueming Li }
159926629e3SXueming Li
160926629e3SXueming Li static int
test_vdev(void)161926629e3SXueming Li test_vdev(void)
162926629e3SXueming Li {
163926629e3SXueming Li printf("== test vdev bus ==\n");
164926629e3SXueming Li if (test_vdev_bus() < 0)
165926629e3SXueming Li return -1;
166926629e3SXueming Li return 0;
167926629e3SXueming Li }
168926629e3SXueming Li
169*d83fb967SDavid Marchand REGISTER_FAST_TEST(vdev_autotest, true, true, test_vdev);
170