xref: /dpdk/lib/ethdev/ethdev_private.c (revision 68eb9a19)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2018 Gaëtan Rivet
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
541f2f055SDavid Marchand #include <rte_debug.h>
6*4b4f810eSFerruh Yigit 
799a2dd95SBruce Richardson #include "rte_ethdev.h"
899a2dd95SBruce Richardson #include "ethdev_driver.h"
999a2dd95SBruce Richardson #include "ethdev_private.h"
1099a2dd95SBruce Richardson 
11*4b4f810eSFerruh Yigit static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
12*4b4f810eSFerruh Yigit 
13*4b4f810eSFerruh Yigit /* Shared memory between primary and secondary processes. */
14*4b4f810eSFerruh Yigit struct eth_dev_shared *eth_dev_shared_data;
15*4b4f810eSFerruh Yigit 
16*4b4f810eSFerruh Yigit /* spinlock for shared data allocation */
17*4b4f810eSFerruh Yigit static rte_spinlock_t eth_dev_shared_data_lock = RTE_SPINLOCK_INITIALIZER;
18*4b4f810eSFerruh Yigit 
19*4b4f810eSFerruh Yigit /* spinlock for eth device callbacks */
20*4b4f810eSFerruh Yigit rte_spinlock_t eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
21*4b4f810eSFerruh Yigit 
2299a2dd95SBruce Richardson uint16_t
eth_dev_to_id(const struct rte_eth_dev * dev)2399a2dd95SBruce Richardson eth_dev_to_id(const struct rte_eth_dev *dev)
2499a2dd95SBruce Richardson {
2599a2dd95SBruce Richardson 	if (dev == NULL)
2699a2dd95SBruce Richardson 		return RTE_MAX_ETHPORTS;
2799a2dd95SBruce Richardson 	return dev - rte_eth_devices;
2899a2dd95SBruce Richardson }
2999a2dd95SBruce Richardson 
3099a2dd95SBruce Richardson struct rte_eth_dev *
eth_find_device(const struct rte_eth_dev * start,rte_eth_cmp_t cmp,const void * data)3199a2dd95SBruce Richardson eth_find_device(const struct rte_eth_dev *start, rte_eth_cmp_t cmp,
3299a2dd95SBruce Richardson 		const void *data)
3399a2dd95SBruce Richardson {
3499a2dd95SBruce Richardson 	struct rte_eth_dev *edev;
3599a2dd95SBruce Richardson 	ptrdiff_t idx;
3699a2dd95SBruce Richardson 
3799a2dd95SBruce Richardson 	/* Avoid Undefined Behaviour */
3899a2dd95SBruce Richardson 	if (start != NULL &&
3999a2dd95SBruce Richardson 	    (start < &rte_eth_devices[0] ||
4099a2dd95SBruce Richardson 	     start > &rte_eth_devices[RTE_MAX_ETHPORTS]))
4199a2dd95SBruce Richardson 		return NULL;
4299a2dd95SBruce Richardson 	if (start != NULL)
4399a2dd95SBruce Richardson 		idx = eth_dev_to_id(start) + 1;
4499a2dd95SBruce Richardson 	else
4599a2dd95SBruce Richardson 		idx = 0;
4699a2dd95SBruce Richardson 	for (; idx < RTE_MAX_ETHPORTS; idx++) {
4799a2dd95SBruce Richardson 		edev = &rte_eth_devices[idx];
4899a2dd95SBruce Richardson 		if (cmp(edev, data) == 0)
4999a2dd95SBruce Richardson 			return edev;
5099a2dd95SBruce Richardson 	}
5199a2dd95SBruce Richardson 	return NULL;
5299a2dd95SBruce Richardson }
5399a2dd95SBruce Richardson 
5499a2dd95SBruce Richardson /* Put new value into list. */
5599a2dd95SBruce Richardson static int
rte_eth_devargs_enlist(uint16_t * list,uint16_t * len_list,const uint16_t max_list,uint16_t val)5699a2dd95SBruce Richardson rte_eth_devargs_enlist(uint16_t *list, uint16_t *len_list,
5799a2dd95SBruce Richardson 		       const uint16_t max_list, uint16_t val)
5899a2dd95SBruce Richardson {
5999a2dd95SBruce Richardson 	uint16_t i;
6099a2dd95SBruce Richardson 
6199a2dd95SBruce Richardson 	for (i = 0; i < *len_list; i++) {
6299a2dd95SBruce Richardson 		if (list[i] == val)
6399a2dd95SBruce Richardson 			return 0;
6499a2dd95SBruce Richardson 	}
6599a2dd95SBruce Richardson 	if (*len_list >= max_list)
6699a2dd95SBruce Richardson 		return -1;
6799a2dd95SBruce Richardson 	list[(*len_list)++] = val;
6899a2dd95SBruce Richardson 	return 0;
6999a2dd95SBruce Richardson }
7099a2dd95SBruce Richardson 
7199a2dd95SBruce Richardson /* Parse and enlist a range expression of "min-max" or a single value. */
7299a2dd95SBruce Richardson static char *
rte_eth_devargs_process_range(char * str,uint16_t * list,uint16_t * len_list,const uint16_t max_list)7399a2dd95SBruce Richardson rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list,
7499a2dd95SBruce Richardson 	const uint16_t max_list)
7599a2dd95SBruce Richardson {
7699a2dd95SBruce Richardson 	uint16_t lo, hi, val;
7799a2dd95SBruce Richardson 	int result, n = 0;
7899a2dd95SBruce Richardson 	char *pos = str;
7999a2dd95SBruce Richardson 
8099a2dd95SBruce Richardson 	result = sscanf(str, "%hu%n-%hu%n", &lo, &n, &hi, &n);
8199a2dd95SBruce Richardson 	if (result == 1) {
8299a2dd95SBruce Richardson 		if (rte_eth_devargs_enlist(list, len_list, max_list, lo) != 0)
8399a2dd95SBruce Richardson 			return NULL;
8499a2dd95SBruce Richardson 	} else if (result == 2) {
8599a2dd95SBruce Richardson 		if (lo > hi)
8699a2dd95SBruce Richardson 			return NULL;
8799a2dd95SBruce Richardson 		for (val = lo; val <= hi; val++) {
8899a2dd95SBruce Richardson 			if (rte_eth_devargs_enlist(list, len_list, max_list,
8999a2dd95SBruce Richardson 						   val) != 0)
9099a2dd95SBruce Richardson 				return NULL;
9199a2dd95SBruce Richardson 		}
9299a2dd95SBruce Richardson 	} else
9399a2dd95SBruce Richardson 		return NULL;
9499a2dd95SBruce Richardson 	return pos + n;
9599a2dd95SBruce Richardson }
9699a2dd95SBruce Richardson 
9799a2dd95SBruce Richardson /*
9899a2dd95SBruce Richardson  * Parse list of values separated by ",".
9999a2dd95SBruce Richardson  * Each value could be a range [min-max] or single number.
10099a2dd95SBruce Richardson  * Examples:
10199a2dd95SBruce Richardson  *  2               - single
10299a2dd95SBruce Richardson  *  [1,2,3]         - single list
10399a2dd95SBruce Richardson  *  [1,3-5,7,9-11]  - list with singles and ranges
10499a2dd95SBruce Richardson  */
10599a2dd95SBruce Richardson static char *
rte_eth_devargs_process_list(char * str,uint16_t * list,uint16_t * len_list,const uint16_t max_list)10699a2dd95SBruce Richardson rte_eth_devargs_process_list(char *str, uint16_t *list, uint16_t *len_list,
10799a2dd95SBruce Richardson 	const uint16_t max_list)
10899a2dd95SBruce Richardson {
10999a2dd95SBruce Richardson 	char *pos = str;
11099a2dd95SBruce Richardson 
11199a2dd95SBruce Richardson 	if (*pos == '[')
11299a2dd95SBruce Richardson 		pos++;
11399a2dd95SBruce Richardson 	while (1) {
11499a2dd95SBruce Richardson 		pos = rte_eth_devargs_process_range(pos, list, len_list,
11599a2dd95SBruce Richardson 						    max_list);
11699a2dd95SBruce Richardson 		if (pos == NULL)
11799a2dd95SBruce Richardson 			return NULL;
11899a2dd95SBruce Richardson 		if (*pos != ',') /* end of list */
11999a2dd95SBruce Richardson 			break;
12099a2dd95SBruce Richardson 		pos++;
12199a2dd95SBruce Richardson 	}
12299a2dd95SBruce Richardson 	if (*str == '[' && *pos != ']')
12399a2dd95SBruce Richardson 		return NULL;
12499a2dd95SBruce Richardson 	if (*pos == ']')
12599a2dd95SBruce Richardson 		pos++;
12699a2dd95SBruce Richardson 	return pos;
12799a2dd95SBruce Richardson }
12899a2dd95SBruce Richardson 
12999a2dd95SBruce Richardson /*
13099a2dd95SBruce Richardson  * Parse representor ports from a single value or lists.
13199a2dd95SBruce Richardson  *
13299a2dd95SBruce Richardson  * Representor format:
13399a2dd95SBruce Richardson  *   #: range or single number of VF representor - legacy
13499a2dd95SBruce Richardson  *   [[c#]pf#]vf#: VF port representor/s
13599a2dd95SBruce Richardson  *   [[c#]pf#]sf#: SF port representor/s
13699a2dd95SBruce Richardson  *   [c#]pf#:      PF port representor/s
13799a2dd95SBruce Richardson  *
13899a2dd95SBruce Richardson  * Examples of #:
13999a2dd95SBruce Richardson  *  2               - single
14099a2dd95SBruce Richardson  *  [1,2,3]         - single list
14199a2dd95SBruce Richardson  *  [1,3-5,7,9-11]  - list with singles and ranges
14299a2dd95SBruce Richardson  */
14399a2dd95SBruce Richardson int
rte_eth_devargs_parse_representor_ports(char * str,void * data)14499a2dd95SBruce Richardson rte_eth_devargs_parse_representor_ports(char *str, void *data)
14599a2dd95SBruce Richardson {
14699a2dd95SBruce Richardson 	struct rte_eth_devargs *eth_da = data;
14799a2dd95SBruce Richardson 
14899a2dd95SBruce Richardson 	if (str[0] == 'c') {
14999a2dd95SBruce Richardson 		str += 1;
15099a2dd95SBruce Richardson 		str = rte_eth_devargs_process_list(str, eth_da->mh_controllers,
15199a2dd95SBruce Richardson 				&eth_da->nb_mh_controllers,
15299a2dd95SBruce Richardson 				RTE_DIM(eth_da->mh_controllers));
15399a2dd95SBruce Richardson 		if (str == NULL)
15499a2dd95SBruce Richardson 			goto done;
15599a2dd95SBruce Richardson 	}
15699a2dd95SBruce Richardson 	if (str[0] == 'p' && str[1] == 'f') {
15799a2dd95SBruce Richardson 		eth_da->type = RTE_ETH_REPRESENTOR_PF;
15899a2dd95SBruce Richardson 		str += 2;
15999a2dd95SBruce Richardson 		str = rte_eth_devargs_process_list(str, eth_da->ports,
16099a2dd95SBruce Richardson 				&eth_da->nb_ports, RTE_DIM(eth_da->ports));
16199a2dd95SBruce Richardson 		if (str == NULL || str[0] == '\0')
16299a2dd95SBruce Richardson 			goto done;
16399a2dd95SBruce Richardson 	} else if (eth_da->nb_mh_controllers > 0) {
16499a2dd95SBruce Richardson 		/* 'c' must followed by 'pf'. */
16599a2dd95SBruce Richardson 		str = NULL;
16699a2dd95SBruce Richardson 		goto done;
16799a2dd95SBruce Richardson 	}
16899a2dd95SBruce Richardson 	if (str[0] == 'v' && str[1] == 'f') {
16999a2dd95SBruce Richardson 		eth_da->type = RTE_ETH_REPRESENTOR_VF;
17099a2dd95SBruce Richardson 		str += 2;
17199a2dd95SBruce Richardson 	} else if (str[0] == 's' && str[1] == 'f') {
17299a2dd95SBruce Richardson 		eth_da->type = RTE_ETH_REPRESENTOR_SF;
17399a2dd95SBruce Richardson 		str += 2;
17499a2dd95SBruce Richardson 	} else {
17599a2dd95SBruce Richardson 		/* 'pf' must followed by 'vf' or 'sf'. */
17699a2dd95SBruce Richardson 		if (eth_da->type == RTE_ETH_REPRESENTOR_PF) {
17799a2dd95SBruce Richardson 			str = NULL;
17899a2dd95SBruce Richardson 			goto done;
17999a2dd95SBruce Richardson 		}
18099a2dd95SBruce Richardson 		eth_da->type = RTE_ETH_REPRESENTOR_VF;
18199a2dd95SBruce Richardson 	}
18299a2dd95SBruce Richardson 	str = rte_eth_devargs_process_list(str, eth_da->representor_ports,
18399a2dd95SBruce Richardson 		&eth_da->nb_representor_ports,
18499a2dd95SBruce Richardson 		RTE_DIM(eth_da->representor_ports));
18599a2dd95SBruce Richardson done:
18699a2dd95SBruce Richardson 	if (str == NULL)
18799a2dd95SBruce Richardson 		RTE_LOG(ERR, EAL, "wrong representor format: %s\n", str);
18899a2dd95SBruce Richardson 	return str == NULL ? -1 : 0;
18999a2dd95SBruce Richardson }
190c87d435aSKonstantin Ananyev 
19141f2f055SDavid Marchand struct dummy_queue {
19241f2f055SDavid Marchand 	bool rx_warn_once;
19341f2f055SDavid Marchand 	bool tx_warn_once;
19441f2f055SDavid Marchand };
19541f2f055SDavid Marchand static struct dummy_queue *dummy_queues_array[RTE_MAX_ETHPORTS][RTE_MAX_QUEUES_PER_PORT];
19641f2f055SDavid Marchand static struct dummy_queue per_port_queues[RTE_MAX_ETHPORTS];
RTE_INIT(dummy_queue_init)19741f2f055SDavid Marchand RTE_INIT(dummy_queue_init)
19841f2f055SDavid Marchand {
19941f2f055SDavid Marchand 	uint16_t port_id;
20041f2f055SDavid Marchand 
20141f2f055SDavid Marchand 	for (port_id = 0; port_id < RTE_DIM(per_port_queues); port_id++) {
20241f2f055SDavid Marchand 		unsigned int q;
20341f2f055SDavid Marchand 
20441f2f055SDavid Marchand 		for (q = 0; q < RTE_DIM(dummy_queues_array[port_id]); q++)
20541f2f055SDavid Marchand 			dummy_queues_array[port_id][q] = &per_port_queues[port_id];
20641f2f055SDavid Marchand 	}
20741f2f055SDavid Marchand }
20841f2f055SDavid Marchand 
209c87d435aSKonstantin Ananyev static uint16_t
dummy_eth_rx_burst(void * rxq,__rte_unused struct rte_mbuf ** rx_pkts,__rte_unused uint16_t nb_pkts)21041f2f055SDavid Marchand dummy_eth_rx_burst(void *rxq,
211c87d435aSKonstantin Ananyev 		__rte_unused struct rte_mbuf **rx_pkts,
212c87d435aSKonstantin Ananyev 		__rte_unused uint16_t nb_pkts)
213c87d435aSKonstantin Ananyev {
21441f2f055SDavid Marchand 	struct dummy_queue *queue = rxq;
21541f2f055SDavid Marchand 	uintptr_t port_id;
21641f2f055SDavid Marchand 
21741f2f055SDavid Marchand 	port_id = queue - per_port_queues;
21841f2f055SDavid Marchand 	if (port_id < RTE_DIM(per_port_queues) && !queue->rx_warn_once) {
21941f2f055SDavid Marchand 		RTE_ETHDEV_LOG(ERR, "lcore %u called rx_pkt_burst for not ready port %"PRIuPTR"\n",
22041f2f055SDavid Marchand 			rte_lcore_id(), port_id);
22141f2f055SDavid Marchand 		rte_dump_stack();
22241f2f055SDavid Marchand 		queue->rx_warn_once = true;
22341f2f055SDavid Marchand 	}
224c87d435aSKonstantin Ananyev 	rte_errno = ENOTSUP;
225c87d435aSKonstantin Ananyev 	return 0;
226c87d435aSKonstantin Ananyev }
227c87d435aSKonstantin Ananyev 
228c87d435aSKonstantin Ananyev static uint16_t
dummy_eth_tx_burst(void * txq,__rte_unused struct rte_mbuf ** tx_pkts,__rte_unused uint16_t nb_pkts)22941f2f055SDavid Marchand dummy_eth_tx_burst(void *txq,
230c87d435aSKonstantin Ananyev 		__rte_unused struct rte_mbuf **tx_pkts,
231c87d435aSKonstantin Ananyev 		__rte_unused uint16_t nb_pkts)
232c87d435aSKonstantin Ananyev {
23341f2f055SDavid Marchand 	struct dummy_queue *queue = txq;
23441f2f055SDavid Marchand 	uintptr_t port_id;
23541f2f055SDavid Marchand 
23641f2f055SDavid Marchand 	port_id = queue - per_port_queues;
23741f2f055SDavid Marchand 	if (port_id < RTE_DIM(per_port_queues) && !queue->tx_warn_once) {
23841f2f055SDavid Marchand 		RTE_ETHDEV_LOG(ERR, "lcore %u called tx_pkt_burst for not ready port %"PRIuPTR"\n",
23941f2f055SDavid Marchand 			rte_lcore_id(), port_id);
24041f2f055SDavid Marchand 		rte_dump_stack();
24141f2f055SDavid Marchand 		queue->tx_warn_once = true;
24241f2f055SDavid Marchand 	}
243c87d435aSKonstantin Ananyev 	rte_errno = ENOTSUP;
244c87d435aSKonstantin Ananyev 	return 0;
245c87d435aSKonstantin Ananyev }
246c87d435aSKonstantin Ananyev 
247c87d435aSKonstantin Ananyev void
eth_dev_fp_ops_reset(struct rte_eth_fp_ops * fpo)248c87d435aSKonstantin Ananyev eth_dev_fp_ops_reset(struct rte_eth_fp_ops *fpo)
249c87d435aSKonstantin Ananyev {
250c87d435aSKonstantin Ananyev 	static void *dummy_data[RTE_MAX_QUEUES_PER_PORT];
25141f2f055SDavid Marchand 	uintptr_t port_id = fpo - rte_eth_fp_ops;
25241f2f055SDavid Marchand 
25341f2f055SDavid Marchand 	per_port_queues[port_id].rx_warn_once = false;
25441f2f055SDavid Marchand 	per_port_queues[port_id].tx_warn_once = false;
25541f2f055SDavid Marchand 	*fpo = (struct rte_eth_fp_ops) {
256c87d435aSKonstantin Ananyev 		.rx_pkt_burst = dummy_eth_rx_burst,
257c87d435aSKonstantin Ananyev 		.tx_pkt_burst = dummy_eth_tx_burst,
25841f2f055SDavid Marchand 		.rxq = {
25941f2f055SDavid Marchand 			.data = (void **)&dummy_queues_array[port_id],
26041f2f055SDavid Marchand 			.clbk = dummy_data,
26141f2f055SDavid Marchand 		},
26241f2f055SDavid Marchand 		.txq = {
26341f2f055SDavid Marchand 			.data = (void **)&dummy_queues_array[port_id],
26441f2f055SDavid Marchand 			.clbk = dummy_data,
26541f2f055SDavid Marchand 		},
266c87d435aSKonstantin Ananyev 	};
267c87d435aSKonstantin Ananyev }
268c87d435aSKonstantin Ananyev 
269c87d435aSKonstantin Ananyev void
eth_dev_fp_ops_setup(struct rte_eth_fp_ops * fpo,const struct rte_eth_dev * dev)270c87d435aSKonstantin Ananyev eth_dev_fp_ops_setup(struct rte_eth_fp_ops *fpo,
271c87d435aSKonstantin Ananyev 		const struct rte_eth_dev *dev)
272c87d435aSKonstantin Ananyev {
273c87d435aSKonstantin Ananyev 	fpo->rx_pkt_burst = dev->rx_pkt_burst;
274c87d435aSKonstantin Ananyev 	fpo->tx_pkt_burst = dev->tx_pkt_burst;
275c87d435aSKonstantin Ananyev 	fpo->tx_pkt_prepare = dev->tx_pkt_prepare;
276c87d435aSKonstantin Ananyev 	fpo->rx_queue_count = dev->rx_queue_count;
277c87d435aSKonstantin Ananyev 	fpo->rx_descriptor_status = dev->rx_descriptor_status;
278c87d435aSKonstantin Ananyev 	fpo->tx_descriptor_status = dev->tx_descriptor_status;
279c87d435aSKonstantin Ananyev 
280c87d435aSKonstantin Ananyev 	fpo->rxq.data = dev->data->rx_queues;
281c87d435aSKonstantin Ananyev 	fpo->rxq.clbk = (void **)(uintptr_t)dev->post_rx_burst_cbs;
282c87d435aSKonstantin Ananyev 
283c87d435aSKonstantin Ananyev 	fpo->txq.data = dev->data->tx_queues;
284c87d435aSKonstantin Ananyev 	fpo->txq.clbk = (void **)(uintptr_t)dev->pre_tx_burst_cbs;
285c87d435aSKonstantin Ananyev }
2867a093523SKonstantin Ananyev 
2877a093523SKonstantin Ananyev uint16_t
rte_eth_call_rx_callbacks(uint16_t port_id,uint16_t queue_id,struct rte_mbuf ** rx_pkts,uint16_t nb_rx,uint16_t nb_pkts,void * opaque)2887a093523SKonstantin Ananyev rte_eth_call_rx_callbacks(uint16_t port_id, uint16_t queue_id,
2897a093523SKonstantin Ananyev 	struct rte_mbuf **rx_pkts, uint16_t nb_rx, uint16_t nb_pkts,
2907a093523SKonstantin Ananyev 	void *opaque)
2917a093523SKonstantin Ananyev {
2927a093523SKonstantin Ananyev 	const struct rte_eth_rxtx_callback *cb = opaque;
2937a093523SKonstantin Ananyev 
2947a093523SKonstantin Ananyev 	while (cb != NULL) {
2957a093523SKonstantin Ananyev 		nb_rx = cb->fn.rx(port_id, queue_id, rx_pkts, nb_rx,
2967a093523SKonstantin Ananyev 				nb_pkts, cb->param);
2977a093523SKonstantin Ananyev 		cb = cb->next;
2987a093523SKonstantin Ananyev 	}
2997a093523SKonstantin Ananyev 
3007a093523SKonstantin Ananyev 	return nb_rx;
3017a093523SKonstantin Ananyev }
3027a093523SKonstantin Ananyev 
3037a093523SKonstantin Ananyev uint16_t
rte_eth_call_tx_callbacks(uint16_t port_id,uint16_t queue_id,struct rte_mbuf ** tx_pkts,uint16_t nb_pkts,void * opaque)3047a093523SKonstantin Ananyev rte_eth_call_tx_callbacks(uint16_t port_id, uint16_t queue_id,
3057a093523SKonstantin Ananyev 	struct rte_mbuf **tx_pkts, uint16_t nb_pkts, void *opaque)
3067a093523SKonstantin Ananyev {
3077a093523SKonstantin Ananyev 	const struct rte_eth_rxtx_callback *cb = opaque;
3087a093523SKonstantin Ananyev 
3097a093523SKonstantin Ananyev 	while (cb != NULL) {
3107a093523SKonstantin Ananyev 		nb_pkts = cb->fn.tx(port_id, queue_id, tx_pkts, nb_pkts,
3117a093523SKonstantin Ananyev 				cb->param);
3127a093523SKonstantin Ananyev 		cb = cb->next;
3137a093523SKonstantin Ananyev 	}
3147a093523SKonstantin Ananyev 
3157a093523SKonstantin Ananyev 	return nb_pkts;
3167a093523SKonstantin Ananyev }
317*4b4f810eSFerruh Yigit 
318*4b4f810eSFerruh Yigit void
eth_dev_shared_data_prepare(void)319*4b4f810eSFerruh Yigit eth_dev_shared_data_prepare(void)
320*4b4f810eSFerruh Yigit {
321*4b4f810eSFerruh Yigit 	const unsigned int flags = 0;
322*4b4f810eSFerruh Yigit 	const struct rte_memzone *mz;
323*4b4f810eSFerruh Yigit 
324*4b4f810eSFerruh Yigit 	rte_spinlock_lock(&eth_dev_shared_data_lock);
325*4b4f810eSFerruh Yigit 
326*4b4f810eSFerruh Yigit 	if (eth_dev_shared_data == NULL) {
327*4b4f810eSFerruh Yigit 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
328*4b4f810eSFerruh Yigit 			/* Allocate port data and ownership shared memory. */
329*4b4f810eSFerruh Yigit 			mz = rte_memzone_reserve(MZ_RTE_ETH_DEV_DATA,
330*4b4f810eSFerruh Yigit 					sizeof(*eth_dev_shared_data),
331*4b4f810eSFerruh Yigit 					rte_socket_id(), flags);
332*4b4f810eSFerruh Yigit 		} else
333*4b4f810eSFerruh Yigit 			mz = rte_memzone_lookup(MZ_RTE_ETH_DEV_DATA);
334*4b4f810eSFerruh Yigit 		if (mz == NULL)
335*4b4f810eSFerruh Yigit 			rte_panic("Cannot allocate ethdev shared data\n");
336*4b4f810eSFerruh Yigit 
337*4b4f810eSFerruh Yigit 		eth_dev_shared_data = mz->addr;
338*4b4f810eSFerruh Yigit 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
339*4b4f810eSFerruh Yigit 			eth_dev_shared_data->next_owner_id =
340*4b4f810eSFerruh Yigit 					RTE_ETH_DEV_NO_OWNER + 1;
341*4b4f810eSFerruh Yigit 			rte_spinlock_init(&eth_dev_shared_data->ownership_lock);
342*4b4f810eSFerruh Yigit 			memset(eth_dev_shared_data->data, 0,
343*4b4f810eSFerruh Yigit 			       sizeof(eth_dev_shared_data->data));
344*4b4f810eSFerruh Yigit 		}
345*4b4f810eSFerruh Yigit 	}
346*4b4f810eSFerruh Yigit 
347*4b4f810eSFerruh Yigit 	rte_spinlock_unlock(&eth_dev_shared_data_lock);
348*4b4f810eSFerruh Yigit }
349*4b4f810eSFerruh Yigit 
350*4b4f810eSFerruh Yigit void
eth_dev_rxq_release(struct rte_eth_dev * dev,uint16_t qid)351*4b4f810eSFerruh Yigit eth_dev_rxq_release(struct rte_eth_dev *dev, uint16_t qid)
352*4b4f810eSFerruh Yigit {
353*4b4f810eSFerruh Yigit 	void **rxq = dev->data->rx_queues;
354*4b4f810eSFerruh Yigit 
355*4b4f810eSFerruh Yigit 	if (rxq[qid] == NULL)
356*4b4f810eSFerruh Yigit 		return;
357*4b4f810eSFerruh Yigit 
358*4b4f810eSFerruh Yigit 	if (dev->dev_ops->rx_queue_release != NULL)
359*4b4f810eSFerruh Yigit 		(*dev->dev_ops->rx_queue_release)(dev, qid);
360*4b4f810eSFerruh Yigit 	rxq[qid] = NULL;
361*4b4f810eSFerruh Yigit }
362*4b4f810eSFerruh Yigit 
363*4b4f810eSFerruh Yigit void
eth_dev_txq_release(struct rte_eth_dev * dev,uint16_t qid)364*4b4f810eSFerruh Yigit eth_dev_txq_release(struct rte_eth_dev *dev, uint16_t qid)
365*4b4f810eSFerruh Yigit {
366*4b4f810eSFerruh Yigit 	void **txq = dev->data->tx_queues;
367*4b4f810eSFerruh Yigit 
368*4b4f810eSFerruh Yigit 	if (txq[qid] == NULL)
369*4b4f810eSFerruh Yigit 		return;
370*4b4f810eSFerruh Yigit 
371*4b4f810eSFerruh Yigit 	if (dev->dev_ops->tx_queue_release != NULL)
372*4b4f810eSFerruh Yigit 		(*dev->dev_ops->tx_queue_release)(dev, qid);
373*4b4f810eSFerruh Yigit 	txq[qid] = NULL;
374*4b4f810eSFerruh Yigit }
375*4b4f810eSFerruh Yigit 
376*4b4f810eSFerruh Yigit int
eth_dev_rx_queue_config(struct rte_eth_dev * dev,uint16_t nb_queues)377*4b4f810eSFerruh Yigit eth_dev_rx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
378*4b4f810eSFerruh Yigit {
379*4b4f810eSFerruh Yigit 	uint16_t old_nb_queues = dev->data->nb_rx_queues;
380*4b4f810eSFerruh Yigit 	unsigned int i;
381*4b4f810eSFerruh Yigit 
382*4b4f810eSFerruh Yigit 	if (dev->data->rx_queues == NULL && nb_queues != 0) { /* first time configuration */
383*4b4f810eSFerruh Yigit 		dev->data->rx_queues = rte_zmalloc("ethdev->rx_queues",
384*4b4f810eSFerruh Yigit 				sizeof(dev->data->rx_queues[0]) *
385*4b4f810eSFerruh Yigit 				RTE_MAX_QUEUES_PER_PORT,
386*4b4f810eSFerruh Yigit 				RTE_CACHE_LINE_SIZE);
387*4b4f810eSFerruh Yigit 		if (dev->data->rx_queues == NULL) {
388*4b4f810eSFerruh Yigit 			dev->data->nb_rx_queues = 0;
389*4b4f810eSFerruh Yigit 			return -(ENOMEM);
390*4b4f810eSFerruh Yigit 		}
391*4b4f810eSFerruh Yigit 	} else if (dev->data->rx_queues != NULL && nb_queues != 0) { /* re-configure */
392*4b4f810eSFerruh Yigit 		for (i = nb_queues; i < old_nb_queues; i++)
393*4b4f810eSFerruh Yigit 			eth_dev_rxq_release(dev, i);
394*4b4f810eSFerruh Yigit 
395*4b4f810eSFerruh Yigit 	} else if (dev->data->rx_queues != NULL && nb_queues == 0) {
396*4b4f810eSFerruh Yigit 		for (i = nb_queues; i < old_nb_queues; i++)
397*4b4f810eSFerruh Yigit 			eth_dev_rxq_release(dev, i);
398*4b4f810eSFerruh Yigit 
399*4b4f810eSFerruh Yigit 		rte_free(dev->data->rx_queues);
400*4b4f810eSFerruh Yigit 		dev->data->rx_queues = NULL;
401*4b4f810eSFerruh Yigit 	}
402*4b4f810eSFerruh Yigit 	dev->data->nb_rx_queues = nb_queues;
403*4b4f810eSFerruh Yigit 	return 0;
404*4b4f810eSFerruh Yigit }
405*4b4f810eSFerruh Yigit 
406*4b4f810eSFerruh Yigit int
eth_dev_tx_queue_config(struct rte_eth_dev * dev,uint16_t nb_queues)407*4b4f810eSFerruh Yigit eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
408*4b4f810eSFerruh Yigit {
409*4b4f810eSFerruh Yigit 	uint16_t old_nb_queues = dev->data->nb_tx_queues;
410*4b4f810eSFerruh Yigit 	unsigned int i;
411*4b4f810eSFerruh Yigit 
412*4b4f810eSFerruh Yigit 	if (dev->data->tx_queues == NULL && nb_queues != 0) { /* first time configuration */
413*4b4f810eSFerruh Yigit 		dev->data->tx_queues = rte_zmalloc("ethdev->tx_queues",
414*4b4f810eSFerruh Yigit 				sizeof(dev->data->tx_queues[0]) *
415*4b4f810eSFerruh Yigit 				RTE_MAX_QUEUES_PER_PORT,
416*4b4f810eSFerruh Yigit 				RTE_CACHE_LINE_SIZE);
417*4b4f810eSFerruh Yigit 		if (dev->data->tx_queues == NULL) {
418*4b4f810eSFerruh Yigit 			dev->data->nb_tx_queues = 0;
419*4b4f810eSFerruh Yigit 			return -(ENOMEM);
420*4b4f810eSFerruh Yigit 		}
421*4b4f810eSFerruh Yigit 	} else if (dev->data->tx_queues != NULL && nb_queues != 0) { /* re-configure */
422*4b4f810eSFerruh Yigit 		for (i = nb_queues; i < old_nb_queues; i++)
423*4b4f810eSFerruh Yigit 			eth_dev_txq_release(dev, i);
424*4b4f810eSFerruh Yigit 
425*4b4f810eSFerruh Yigit 	} else if (dev->data->tx_queues != NULL && nb_queues == 0) {
426*4b4f810eSFerruh Yigit 		for (i = nb_queues; i < old_nb_queues; i++)
427*4b4f810eSFerruh Yigit 			eth_dev_txq_release(dev, i);
428*4b4f810eSFerruh Yigit 
429*4b4f810eSFerruh Yigit 		rte_free(dev->data->tx_queues);
430*4b4f810eSFerruh Yigit 		dev->data->tx_queues = NULL;
431*4b4f810eSFerruh Yigit 	}
432*4b4f810eSFerruh Yigit 	dev->data->nb_tx_queues = nb_queues;
433*4b4f810eSFerruh Yigit 	return 0;
434*4b4f810eSFerruh Yigit }
435