xref: /dpdk/lib/ethdev/rte_class_eth.c (revision 5906be5a)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2018 Gaëtan Rivet
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #include <string.h>
699a2dd95SBruce Richardson 
799a2dd95SBruce Richardson #include <rte_class.h>
899a2dd95SBruce Richardson #include <rte_compat.h>
999a2dd95SBruce Richardson #include <rte_errno.h>
1099a2dd95SBruce Richardson #include <rte_kvargs.h>
1199a2dd95SBruce Richardson #include <rte_log.h>
1299a2dd95SBruce Richardson 
1399a2dd95SBruce Richardson #include "rte_ethdev.h"
1499a2dd95SBruce Richardson #include "rte_ethdev_core.h"
1599a2dd95SBruce Richardson #include "ethdev_driver.h"
1699a2dd95SBruce Richardson #include "ethdev_private.h"
1799a2dd95SBruce Richardson 
1899a2dd95SBruce Richardson enum eth_params {
1999a2dd95SBruce Richardson 	RTE_ETH_PARAM_MAC,
2099a2dd95SBruce Richardson 	RTE_ETH_PARAM_REPRESENTOR,
2199a2dd95SBruce Richardson 	RTE_ETH_PARAM_MAX,
2299a2dd95SBruce Richardson };
2399a2dd95SBruce Richardson 
2499a2dd95SBruce Richardson static const char * const eth_params_keys[] = {
2599a2dd95SBruce Richardson 	[RTE_ETH_PARAM_MAC] = "mac",
2699a2dd95SBruce Richardson 	[RTE_ETH_PARAM_REPRESENTOR] = "representor",
2799a2dd95SBruce Richardson 	[RTE_ETH_PARAM_MAX] = NULL,
2899a2dd95SBruce Richardson };
2999a2dd95SBruce Richardson 
3099a2dd95SBruce Richardson struct eth_dev_match_arg {
3199a2dd95SBruce Richardson 	struct rte_device *device;
3299a2dd95SBruce Richardson 	struct rte_kvargs *kvlist;
3399a2dd95SBruce Richardson };
3499a2dd95SBruce Richardson 
3599a2dd95SBruce Richardson #define eth_dev_match_arg(d, k) \
3699a2dd95SBruce Richardson 	(&(const struct eth_dev_match_arg) { \
3799a2dd95SBruce Richardson 		.device = (d), \
3899a2dd95SBruce Richardson 		.kvlist = (k), \
3999a2dd95SBruce Richardson 	})
4099a2dd95SBruce Richardson 
4199a2dd95SBruce Richardson static int
eth_mac_cmp(const char * key __rte_unused,const char * value,void * opaque)4299a2dd95SBruce Richardson eth_mac_cmp(const char *key __rte_unused,
4399a2dd95SBruce Richardson 		const char *value, void *opaque)
4499a2dd95SBruce Richardson {
4599a2dd95SBruce Richardson 	struct rte_ether_addr mac;
4699a2dd95SBruce Richardson 	const struct rte_eth_dev_data *data = opaque;
4799a2dd95SBruce Richardson 	struct rte_eth_dev_info dev_info;
4899a2dd95SBruce Richardson 	uint32_t index;
4999a2dd95SBruce Richardson 
5099a2dd95SBruce Richardson 	/* Parse devargs MAC address. */
5199a2dd95SBruce Richardson 	if (rte_ether_unformat_addr(value, &mac) < 0)
5299a2dd95SBruce Richardson 		return -1; /* invalid devargs value */
5399a2dd95SBruce Richardson 
5499a2dd95SBruce Richardson 	/* Return 0 if devargs MAC is matching one of the device MACs. */
5599a2dd95SBruce Richardson 	rte_eth_dev_info_get(data->port_id, &dev_info);
5699a2dd95SBruce Richardson 	for (index = 0; index < dev_info.max_mac_addrs; index++)
5799a2dd95SBruce Richardson 		if (rte_is_same_ether_addr(&mac, &data->mac_addrs[index]))
5899a2dd95SBruce Richardson 			return 0;
5999a2dd95SBruce Richardson 	return -1; /* no match */
6099a2dd95SBruce Richardson }
6199a2dd95SBruce Richardson 
6299a2dd95SBruce Richardson static int
eth_representor_cmp(const char * key __rte_unused,const char * value,void * opaque)6399a2dd95SBruce Richardson eth_representor_cmp(const char *key __rte_unused,
6499a2dd95SBruce Richardson 		const char *value, void *opaque)
6599a2dd95SBruce Richardson {
6699a2dd95SBruce Richardson 	int ret;
6799a2dd95SBruce Richardson 	char *values;
6899a2dd95SBruce Richardson 	const struct rte_eth_dev *edev = opaque;
6999a2dd95SBruce Richardson 	const struct rte_eth_dev_data *data = edev->data;
7099a2dd95SBruce Richardson 	struct rte_eth_devargs eth_da;
7199a2dd95SBruce Richardson 	uint16_t id, nc, np, nf, i, c, p, f;
7299a2dd95SBruce Richardson 
7399a2dd95SBruce Richardson 	if ((data->dev_flags & RTE_ETH_DEV_REPRESENTOR) == 0)
7499a2dd95SBruce Richardson 		return -1; /* not a representor port */
7599a2dd95SBruce Richardson 
7699a2dd95SBruce Richardson 	/* Parse devargs representor values. */
7799a2dd95SBruce Richardson 	values = strdup(value);
7899a2dd95SBruce Richardson 	if (values == NULL)
7999a2dd95SBruce Richardson 		return -1;
8099a2dd95SBruce Richardson 	memset(&eth_da, 0, sizeof(eth_da));
8199a2dd95SBruce Richardson 	ret = rte_eth_devargs_parse_representor_ports(values, &eth_da);
8299a2dd95SBruce Richardson 	free(values);
8399a2dd95SBruce Richardson 	if (ret != 0)
8499a2dd95SBruce Richardson 		return -1; /* invalid devargs value */
8599a2dd95SBruce Richardson 
8699a2dd95SBruce Richardson 	if (eth_da.nb_mh_controllers == 0 && eth_da.nb_ports == 0 &&
8799a2dd95SBruce Richardson 	    eth_da.nb_representor_ports == 0)
8899a2dd95SBruce Richardson 		return -1;
8999a2dd95SBruce Richardson 	nc = eth_da.nb_mh_controllers > 0 ? eth_da.nb_mh_controllers : 1;
9099a2dd95SBruce Richardson 	np = eth_da.nb_ports > 0 ? eth_da.nb_ports : 1;
9199a2dd95SBruce Richardson 	nf = eth_da.nb_representor_ports > 0 ? eth_da.nb_representor_ports : 1;
9299a2dd95SBruce Richardson 
93*5906be5aSAndrew Rybchenko 	/* Return 0 if representor ID is matching one of the values. */
9499a2dd95SBruce Richardson 	for (i = 0; i < nc * np * nf; ++i) {
9599a2dd95SBruce Richardson 		c = i / (np * nf);
9699a2dd95SBruce Richardson 		p = (i / nf) % np;
9799a2dd95SBruce Richardson 		f = i % nf;
98ff4e52efSViacheslav Galaktionov 		if (rte_eth_representor_id_get(edev->data->backer_port_id,
9999a2dd95SBruce Richardson 			eth_da.type,
10099a2dd95SBruce Richardson 			eth_da.nb_mh_controllers == 0 ? -1 :
10199a2dd95SBruce Richardson 					eth_da.mh_controllers[c],
10299a2dd95SBruce Richardson 			eth_da.nb_ports == 0 ? -1 : eth_da.ports[p],
10399a2dd95SBruce Richardson 			eth_da.nb_representor_ports == 0 ? -1 :
10499a2dd95SBruce Richardson 					eth_da.representor_ports[f],
10599a2dd95SBruce Richardson 			&id) < 0)
10699a2dd95SBruce Richardson 			continue;
10799a2dd95SBruce Richardson 		if (data->representor_id == id)
10899a2dd95SBruce Richardson 			return 0;
10999a2dd95SBruce Richardson 	}
11099a2dd95SBruce Richardson 	return -1; /* no match */
11199a2dd95SBruce Richardson }
11299a2dd95SBruce Richardson 
11399a2dd95SBruce Richardson static int
eth_dev_match(const struct rte_eth_dev * edev,const void * _arg)11499a2dd95SBruce Richardson eth_dev_match(const struct rte_eth_dev *edev,
11599a2dd95SBruce Richardson 	      const void *_arg)
11699a2dd95SBruce Richardson {
11799a2dd95SBruce Richardson 	int ret;
11899a2dd95SBruce Richardson 	const struct eth_dev_match_arg *arg = _arg;
11999a2dd95SBruce Richardson 	const struct rte_kvargs *kvlist = arg->kvlist;
12099a2dd95SBruce Richardson 	unsigned int pair;
12199a2dd95SBruce Richardson 
12299a2dd95SBruce Richardson 	if (edev->state == RTE_ETH_DEV_UNUSED)
12399a2dd95SBruce Richardson 		return -1;
12499a2dd95SBruce Richardson 	if (arg->device != NULL && arg->device != edev->device)
12599a2dd95SBruce Richardson 		return -1;
12699a2dd95SBruce Richardson 
12799a2dd95SBruce Richardson 	ret = rte_kvargs_process(kvlist,
12899a2dd95SBruce Richardson 			eth_params_keys[RTE_ETH_PARAM_MAC],
12999a2dd95SBruce Richardson 			eth_mac_cmp, edev->data);
13099a2dd95SBruce Richardson 	if (ret != 0)
13199a2dd95SBruce Richardson 		return -1;
13299a2dd95SBruce Richardson 
13399a2dd95SBruce Richardson 	ret = rte_kvargs_process(kvlist,
13499a2dd95SBruce Richardson 			eth_params_keys[RTE_ETH_PARAM_REPRESENTOR],
13599a2dd95SBruce Richardson 			eth_representor_cmp, (void *)(uintptr_t)edev);
13699a2dd95SBruce Richardson 	if (ret != 0)
13799a2dd95SBruce Richardson 		return -1;
13899a2dd95SBruce Richardson 	/* search for representor key */
13999a2dd95SBruce Richardson 	for (pair = 0; pair < kvlist->count; pair++) {
14099a2dd95SBruce Richardson 		ret = strcmp(kvlist->pairs[pair].key,
14199a2dd95SBruce Richardson 				eth_params_keys[RTE_ETH_PARAM_REPRESENTOR]);
14299a2dd95SBruce Richardson 		if (ret == 0)
14399a2dd95SBruce Richardson 			break; /* there is a representor key */
14499a2dd95SBruce Richardson 	}
14599a2dd95SBruce Richardson 	/* if no representor key, default is to not match representor ports */
14699a2dd95SBruce Richardson 	if (ret != 0)
14799a2dd95SBruce Richardson 		if ((edev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0)
14899a2dd95SBruce Richardson 			return -1; /* do not match any representor */
14999a2dd95SBruce Richardson 
15099a2dd95SBruce Richardson 	return 0;
15199a2dd95SBruce Richardson }
15299a2dd95SBruce Richardson 
15399a2dd95SBruce Richardson static void *
eth_dev_iterate(const void * start,const char * str,const struct rte_dev_iterator * it)15499a2dd95SBruce Richardson eth_dev_iterate(const void *start,
15599a2dd95SBruce Richardson 		const char *str,
15699a2dd95SBruce Richardson 		const struct rte_dev_iterator *it)
15799a2dd95SBruce Richardson {
15899a2dd95SBruce Richardson 	struct rte_kvargs *kvargs = NULL;
15999a2dd95SBruce Richardson 	struct rte_eth_dev *edev = NULL;
16099a2dd95SBruce Richardson 	const char * const *valid_keys = NULL;
16199a2dd95SBruce Richardson 
16299a2dd95SBruce Richardson 	if (str != NULL) {
16399a2dd95SBruce Richardson 		if (str[0] == '+') /* no validation of keys */
16499a2dd95SBruce Richardson 			str++;
16599a2dd95SBruce Richardson 		else
16699a2dd95SBruce Richardson 			valid_keys = eth_params_keys;
16799a2dd95SBruce Richardson 		kvargs = rte_kvargs_parse(str, valid_keys);
16899a2dd95SBruce Richardson 		if (kvargs == NULL) {
16999a2dd95SBruce Richardson 			RTE_LOG(ERR, EAL, "cannot parse argument list\n");
17099a2dd95SBruce Richardson 			rte_errno = EINVAL;
17199a2dd95SBruce Richardson 			return NULL;
17299a2dd95SBruce Richardson 		}
17399a2dd95SBruce Richardson 	}
17499a2dd95SBruce Richardson 	edev = eth_find_device(start, eth_dev_match,
17599a2dd95SBruce Richardson 			       eth_dev_match_arg(it->device, kvargs));
17699a2dd95SBruce Richardson 	rte_kvargs_free(kvargs);
17799a2dd95SBruce Richardson 	return edev;
17899a2dd95SBruce Richardson }
17999a2dd95SBruce Richardson 
18099a2dd95SBruce Richardson static struct rte_class rte_class_eth = {
18199a2dd95SBruce Richardson 	.dev_iterate = eth_dev_iterate,
18299a2dd95SBruce Richardson };
18399a2dd95SBruce Richardson 
18499a2dd95SBruce Richardson RTE_REGISTER_CLASS(eth, rte_class_eth);
185