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 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 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 * 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 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 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