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 [ # # ]: 0 : if (rte_eth_dev_info_get(data->port_id, &dev_info) != 0)
54 : : return -1; /* device MAC address unavailable */
55 : :
56 : : /* Return 0 if devargs MAC is matching one of the device MACs. */
57 [ # # ]: 0 : for (index = 0; index < dev_info.max_mac_addrs; index++)
58 [ # # ]: 0 : if (rte_is_same_ether_addr(&mac, &data->mac_addrs[index]))
59 : : return 0;
60 : : return -1; /* no match */
61 : : }
62 : :
63 : : static int
64 : 0 : eth_representor_cmp(const char *key __rte_unused,
65 : : const char *value, void *opaque)
66 : : {
67 : : int ret;
68 : : char *values;
69 : : const struct rte_eth_dev *edev = opaque;
70 : 0 : const struct rte_eth_dev_data *data = edev->data;
71 : : struct rte_eth_devargs eth_da;
72 [ # # ]: 0 : uint16_t id = 0, nc, np, nf, i, c, p, f;
73 : :
74 [ # # ]: 0 : if (!rte_eth_dev_is_repr(edev))
75 : : return -1; /* not a representor port */
76 : :
77 : : /* Parse devargs representor values. */
78 : 0 : values = strdup(value);
79 [ # # ]: 0 : if (values == NULL)
80 : : return -1;
81 : : memset(ð_da, 0, sizeof(eth_da));
82 : 0 : ret = rte_eth_devargs_parse_representor_ports(values, ð_da);
83 : 0 : free(values);
84 [ # # ]: 0 : if (ret != 0)
85 : : return -1; /* invalid devargs value */
86 : :
87 [ # # # # ]: 0 : if (eth_da.nb_mh_controllers == 0 && eth_da.nb_ports == 0 &&
88 [ # # ]: 0 : eth_da.nb_representor_ports == 0)
89 : : return -1;
90 : : nc = eth_da.nb_mh_controllers > 0 ? eth_da.nb_mh_controllers : 1;
91 : 0 : np = eth_da.nb_ports > 0 ? eth_da.nb_ports : 1;
92 : 0 : nf = eth_da.nb_representor_ports > 0 ? eth_da.nb_representor_ports : 1;
93 : :
94 : : /* Return 0 if representor ID is matching one of the values. */
95 [ # # ]: 0 : for (i = 0; i < nc * np * nf; ++i) {
96 : 0 : c = i / (np * nf);
97 : 0 : p = (i / nf) % np;
98 : 0 : f = i % nf;
99 [ # # ]: 0 : if (rte_eth_representor_id_get(edev->data->backer_port_id,
100 : : eth_da.type,
101 [ # # ]: 0 : eth_da.nb_mh_controllers == 0 ? -1 :
102 : 0 : eth_da.mh_controllers[c],
103 [ # # ]: 0 : eth_da.nb_ports == 0 ? -1 : eth_da.ports[p],
104 [ # # ]: 0 : eth_da.nb_representor_ports == 0 ? -1 :
105 : 0 : eth_da.representor_ports[f],
106 : : &id) < 0)
107 : 0 : continue;
108 [ # # ]: 0 : if (data->representor_id == id)
109 : : return 0;
110 : : }
111 : : return -1; /* no match */
112 : : }
113 : :
114 : : static int
115 : 0 : eth_dev_match(const struct rte_eth_dev *edev,
116 : : const void *_arg)
117 : : {
118 : : int ret;
119 : : const struct eth_dev_match_arg *arg = _arg;
120 : 0 : const struct rte_kvargs *kvlist = arg->kvlist;
121 : : unsigned int pair;
122 : :
123 [ # # ]: 0 : if (edev->state == RTE_ETH_DEV_UNUSED)
124 : : return -1;
125 [ # # # # ]: 0 : if (arg->device != NULL && arg->device != edev->device)
126 : : return -1;
127 : :
128 : 0 : ret = rte_kvargs_process(kvlist,
129 : : eth_params_keys[RTE_ETH_PARAM_MAC],
130 : 0 : eth_mac_cmp, edev->data);
131 [ # # ]: 0 : if (ret != 0)
132 : : return -1;
133 : :
134 : 0 : ret = rte_kvargs_process(kvlist,
135 : : eth_params_keys[RTE_ETH_PARAM_REPRESENTOR],
136 : : eth_representor_cmp, (void *)(uintptr_t)edev);
137 [ # # ]: 0 : if (ret != 0)
138 : : return -1;
139 : : /* search for representor key */
140 [ # # ]: 0 : for (pair = 0; pair < kvlist->count; pair++) {
141 : 0 : ret = strcmp(kvlist->pairs[pair].key,
142 : : eth_params_keys[RTE_ETH_PARAM_REPRESENTOR]);
143 [ # # ]: 0 : if (ret == 0)
144 : : break; /* there is a representor key */
145 : : }
146 : : /* if no representor key, default is to not match representor ports */
147 [ # # ]: 0 : if (ret != 0)
148 [ # # ]: 0 : if (rte_eth_dev_is_repr(edev))
149 : 0 : return -1; /* do not match any representor */
150 : :
151 : : return 0;
152 : : }
153 : :
154 : : static void *
155 : 0 : eth_dev_iterate(const void *start,
156 : : const char *str,
157 : : const struct rte_dev_iterator *it)
158 : : {
159 : : struct rte_kvargs *kvargs = NULL;
160 : : struct rte_eth_dev *edev = NULL;
161 : : const char * const *valid_keys = NULL;
162 : :
163 [ # # ]: 0 : if (str != NULL) {
164 [ # # ]: 0 : if (str[0] == '+') /* no validation of keys */
165 : 0 : str++;
166 : : else
167 : : valid_keys = eth_params_keys;
168 : 0 : kvargs = rte_kvargs_parse(str, valid_keys);
169 [ # # ]: 0 : if (kvargs == NULL) {
170 : 0 : RTE_ETHDEV_LOG_LINE(ERR, "cannot parse argument list");
171 : 0 : rte_errno = EINVAL;
172 : 0 : return NULL;
173 : : }
174 : : }
175 : 0 : edev = eth_find_device(start, eth_dev_match,
176 : 0 : eth_dev_match_arg(it->device, kvargs));
177 : 0 : rte_kvargs_free(kvargs);
178 : 0 : return edev;
179 : : }
180 : :
181 : : static struct rte_class rte_class_eth = {
182 : : .dev_iterate = eth_dev_iterate,
183 : : };
184 : :
185 : 252 : RTE_REGISTER_CLASS(eth, rte_class_eth);
|