ethdev: support representor id as iterator filter
[dpdk.git] / lib / librte_ethdev / rte_class_eth.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 GaĆ«tan Rivet
3  */
4
5 #include <string.h>
6
7 #include <rte_class.h>
8 #include <rte_compat.h>
9 #include <rte_errno.h>
10 #include <rte_kvargs.h>
11 #include <rte_log.h>
12
13 #include "rte_ethdev.h"
14 #include "rte_ethdev_core.h"
15 #include "rte_ethdev_driver.h"
16 #include "ethdev_private.h"
17
18 enum eth_params {
19         RTE_ETH_PARAM_REPRESENTOR,
20         RTE_ETH_PARAM_MAX,
21 };
22
23 static const char * const eth_params_keys[] = {
24         [RTE_ETH_PARAM_REPRESENTOR] = "representor",
25         [RTE_ETH_PARAM_MAX] = NULL,
26 };
27
28 struct eth_dev_match_arg {
29         struct rte_device *device;
30         struct rte_kvargs *kvlist;
31 };
32
33 #define eth_dev_match_arg(d, k) \
34         (&(const struct eth_dev_match_arg) { \
35                 .device = (d), \
36                 .kvlist = (k), \
37         })
38
39 static int
40 eth_representor_cmp(const char *key __rte_unused,
41                 const char *value, void *opaque)
42 {
43         int ret;
44         char *values;
45         const struct rte_eth_dev_data *data = opaque;
46         struct rte_eth_devargs representors;
47         uint16_t index;
48
49         if ((data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0)
50                 return -1; /* not a representor port */
51
52         /* Parse devargs representor values. */
53         values = strdup(value);
54         if (values == NULL)
55                 return -1;
56         memset(&representors, 0, sizeof(representors));
57         ret = rte_eth_devargs_parse_list(values,
58                         rte_eth_devargs_parse_representor_ports,
59                         &representors);
60         free(values);
61         if (ret != 0)
62                 return -1; /* invalid devargs value */
63
64         /* Return 0 if representor id is matching one of the values. */
65         for (index = 0; index < representors.nb_representor_ports; index++)
66                 if (data->representor_id ==
67                                 representors.representor_ports[index])
68                         return 0;
69         return -1; /* no match */
70 }
71
72 static int
73 eth_dev_match(const struct rte_eth_dev *edev,
74               const void *_arg)
75 {
76         int ret;
77         const struct eth_dev_match_arg *arg = _arg;
78         const struct rte_kvargs *kvlist = arg->kvlist;
79
80         if (edev->state == RTE_ETH_DEV_UNUSED)
81                 return -1;
82         if (arg->device != NULL && arg->device != edev->device)
83                 return -1;
84         if (kvlist == NULL)
85                 /* Empty string matches everything. */
86                 return 0;
87
88         ret = rte_kvargs_process(kvlist,
89                         eth_params_keys[RTE_ETH_PARAM_REPRESENTOR],
90                         eth_representor_cmp, edev->data);
91         if (ret != 0)
92                 return -1;
93
94         return 0;
95 }
96
97 static void *
98 eth_dev_iterate(const void *start,
99                 const char *str,
100                 const struct rte_dev_iterator *it)
101 {
102         struct rte_kvargs *kvargs = NULL;
103         struct rte_eth_dev *edev = NULL;
104         const char * const *valid_keys = NULL;
105
106         if (str != NULL) {
107                 if (str[0] == '+') /* no validation of keys */
108                         str++;
109                 else
110                         valid_keys = eth_params_keys;
111                 kvargs = rte_kvargs_parse(str, valid_keys);
112                 if (kvargs == NULL) {
113                         RTE_LOG(ERR, EAL, "cannot parse argument list\n");
114                         rte_errno = EINVAL;
115                         return NULL;
116                 }
117         }
118         edev = eth_find_device(start, eth_dev_match,
119                                eth_dev_match_arg(it->device, kvargs));
120         rte_kvargs_free(kvargs);
121         return edev;
122 }
123
124 struct rte_class rte_class_eth = {
125         .dev_iterate = eth_dev_iterate,
126 };
127
128 RTE_REGISTER_CLASS(eth, rte_class_eth);