Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Gaƫtan Rivet
3 : : */
4 : :
5 : : #include <stdlib.h>
6 : : #include <string.h>
7 : :
8 : : #include <rte_class.h>
9 : : #include <rte_errno.h>
10 : : #include <rte_kvargs.h>
11 : : #include <rte_log.h>
12 : :
13 : : #include "rte_ethdev.h"
14 : : #include "ethdev_driver.h"
15 : : #include "ethdev_private.h"
16 : :
17 : : enum eth_params {
18 : : RTE_ETH_PARAM_MAC,
19 : : RTE_ETH_PARAM_REPRESENTOR,
20 : : RTE_ETH_PARAM_MAX,
21 : : };
22 : :
23 : : static const char * const eth_params_keys[] = {
24 : : [RTE_ETH_PARAM_MAC] = "mac",
25 : : [RTE_ETH_PARAM_REPRESENTOR] = "representor",
26 : : [RTE_ETH_PARAM_MAX] = NULL,
27 : : };
28 : :
29 : : struct eth_dev_match_arg {
30 : : struct rte_device *device;
31 : : struct rte_kvargs *kvlist;
32 : : };
33 : :
34 : : #define eth_dev_match_arg(d, k) \
35 : : (&(const struct eth_dev_match_arg) { \
36 : : .device = (d), \
37 : : .kvlist = (k), \
38 : : })
39 : :
40 : : static int
41 : 0 : eth_mac_cmp(const char *key __rte_unused,
42 : : const char *value, void *opaque)
43 : : {
44 : : struct rte_ether_addr mac;
45 : : const struct rte_eth_dev_data *data = opaque;
46 : : struct rte_eth_dev_info dev_info;
47 : : uint32_t index;
48 : :
49 : : /* Parse devargs MAC address. */
50 [ # # ]: 0 : if (rte_ether_unformat_addr(value, &mac) < 0)
51 : : return -1; /* invalid devargs value */
52 : :
53 : : /* Return 0 if devargs MAC is matching one of the device MACs. */
54 : 0 : rte_eth_dev_info_get(data->port_id, &dev_info);
55 [ # # ]: 0 : for (index = 0; index < dev_info.max_mac_addrs; index++)
56 [ # # ]: 0 : if (rte_is_same_ether_addr(&mac, &data->mac_addrs[index]))
57 : : return 0;
58 : : return -1; /* no match */
59 : : }
60 : :
61 : : static int
62 : 0 : eth_representor_cmp(const char *key __rte_unused,
63 : : const char *value, void *opaque)
64 : : {
65 : : int ret;
66 : : char *values;
67 : : const struct rte_eth_dev *edev = opaque;
68 : 0 : const struct rte_eth_dev_data *data = edev->data;
69 : : struct rte_eth_devargs eth_da;
70 : 0 : uint16_t id = 0, nc, np, nf, i, c, p, f;
71 : :
72 [ # # ]: 0 : if ((data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0)
73 : : return -1; /* not a representor port */
74 : :
75 : : /* Parse devargs representor values. */
76 : 0 : values = strdup(value);
77 [ # # ]: 0 : if (values == NULL)
78 : : return -1;
79 : : memset(ð_da, 0, sizeof(eth_da));
80 : 0 : ret = rte_eth_devargs_parse_representor_ports(values, ð_da);
81 : 0 : free(values);
82 [ # # ]: 0 : if (ret != 0)
83 : : return -1; /* invalid devargs value */
84 : :
85 [ # # # # ]: 0 : if (eth_da.nb_mh_controllers == 0 && eth_da.nb_ports == 0 &&
86 [ # # ]: 0 : eth_da.nb_representor_ports == 0)
87 : : return -1;
88 : : nc = eth_da.nb_mh_controllers > 0 ? eth_da.nb_mh_controllers : 1;
89 : 0 : np = eth_da.nb_ports > 0 ? eth_da.nb_ports : 1;
90 : 0 : nf = eth_da.nb_representor_ports > 0 ? eth_da.nb_representor_ports : 1;
91 : :
92 : : /* Return 0 if representor ID is matching one of the values. */
93 [ # # ]: 0 : for (i = 0; i < nc * np * nf; ++i) {
94 : 0 : c = i / (np * nf);
95 : 0 : p = (i / nf) % np;
96 : 0 : f = i % nf;
97 [ # # ]: 0 : if (rte_eth_representor_id_get(edev->data->backer_port_id,
98 : : eth_da.type,
99 [ # # ]: 0 : eth_da.nb_mh_controllers == 0 ? -1 :
100 : 0 : eth_da.mh_controllers[c],
101 [ # # ]: 0 : eth_da.nb_ports == 0 ? -1 : eth_da.ports[p],
102 [ # # ]: 0 : eth_da.nb_representor_ports == 0 ? -1 :
103 : 0 : eth_da.representor_ports[f],
104 : : &id) < 0)
105 : 0 : continue;
106 [ # # ]: 0 : if (data->representor_id == id)
107 : : return 0;
108 : : }
109 : : return -1; /* no match */
110 : : }
111 : :
112 : : static int
113 : 0 : eth_dev_match(const struct rte_eth_dev *edev,
114 : : const void *_arg)
115 : : {
116 : : int ret;
117 : : const struct eth_dev_match_arg *arg = _arg;
118 : 0 : const struct rte_kvargs *kvlist = arg->kvlist;
119 : : unsigned int pair;
120 : :
121 [ # # ]: 0 : if (edev->state == RTE_ETH_DEV_UNUSED)
122 : : return -1;
123 [ # # # # ]: 0 : if (arg->device != NULL && arg->device != edev->device)
124 : : return -1;
125 : :
126 : 0 : ret = rte_kvargs_process(kvlist,
127 : : eth_params_keys[RTE_ETH_PARAM_MAC],
128 : 0 : eth_mac_cmp, edev->data);
129 [ # # ]: 0 : if (ret != 0)
130 : : return -1;
131 : :
132 : 0 : ret = rte_kvargs_process(kvlist,
133 : : eth_params_keys[RTE_ETH_PARAM_REPRESENTOR],
134 : : eth_representor_cmp, (void *)(uintptr_t)edev);
135 [ # # ]: 0 : if (ret != 0)
136 : : return -1;
137 : : /* search for representor key */
138 [ # # ]: 0 : for (pair = 0; pair < kvlist->count; pair++) {
139 : 0 : ret = strcmp(kvlist->pairs[pair].key,
140 : : eth_params_keys[RTE_ETH_PARAM_REPRESENTOR]);
141 [ # # ]: 0 : if (ret == 0)
142 : : break; /* there is a representor key */
143 : : }
144 : : /* if no representor key, default is to not match representor ports */
145 [ # # ]: 0 : if (ret != 0)
146 [ # # ]: 0 : if ((edev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0)
147 : 0 : return -1; /* do not match any representor */
148 : :
149 : : return 0;
150 : : }
151 : :
152 : : static void *
153 : 0 : eth_dev_iterate(const void *start,
154 : : const char *str,
155 : : const struct rte_dev_iterator *it)
156 : : {
157 : : struct rte_kvargs *kvargs = NULL;
158 : : struct rte_eth_dev *edev = NULL;
159 : : const char * const *valid_keys = NULL;
160 : :
161 [ # # ]: 0 : if (str != NULL) {
162 [ # # ]: 0 : if (str[0] == '+') /* no validation of keys */
163 : 0 : str++;
164 : : else
165 : : valid_keys = eth_params_keys;
166 : 0 : kvargs = rte_kvargs_parse(str, valid_keys);
167 [ # # ]: 0 : if (kvargs == NULL) {
168 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "cannot parse argument list");
169 : 0 : rte_errno = EINVAL;
170 : 0 : return NULL;
171 : : }
172 : : }
173 : 0 : edev = eth_find_device(start, eth_dev_match,
174 : 0 : eth_dev_match_arg(it->device, kvargs));
175 : 0 : rte_kvargs_free(kvargs);
176 : 0 : return edev;
177 : : }
178 : :
179 : : static struct rte_class rte_class_eth = {
180 : : .dev_iterate = eth_dev_iterate,
181 : : };
182 : :
183 : 235 : RTE_REGISTER_CLASS(eth, rte_class_eth);
|