197f17497SC.J. Collier/*-
297f17497SC.J. Collier *   BSD LICENSE
397f17497SC.J. Collier *
497f17497SC.J. Collier *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
597f17497SC.J. Collier *   All rights reserved.
697f17497SC.J. Collier *
797f17497SC.J. Collier *   Redistribution and use in source and binary forms, with or without
897f17497SC.J. Collier *   modification, are permitted provided that the following conditions
997f17497SC.J. Collier *   are met:
1097f17497SC.J. Collier *
1197f17497SC.J. Collier *     * Redistributions of source code must retain the above copyright
1297f17497SC.J. Collier *       notice, this list of conditions and the following disclaimer.
1397f17497SC.J. Collier *     * Redistributions in binary form must reproduce the above copyright
1497f17497SC.J. Collier *       notice, this list of conditions and the following disclaimer in
1597f17497SC.J. Collier *       the documentation and/or other materials provided with the
1697f17497SC.J. Collier *       distribution.
1797f17497SC.J. Collier *     * Neither the name of Intel Corporation nor the names of its
1897f17497SC.J. Collier *       contributors may be used to endorse or promote products derived
1997f17497SC.J. Collier *       from this software without specific prior written permission.
2097f17497SC.J. Collier *
2197f17497SC.J. Collier *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2297f17497SC.J. Collier *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2397f17497SC.J. Collier *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2497f17497SC.J. Collier *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2597f17497SC.J. Collier *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2697f17497SC.J. Collier *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2797f17497SC.J. Collier *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2897f17497SC.J. Collier *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2997f17497SC.J. Collier *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3097f17497SC.J. Collier *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3197f17497SC.J. Collier *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3297f17497SC.J. Collier */
3397f17497SC.J. Collier#include "test.h"
3497f17497SC.J. Collier
3597f17497SC.J. Collier#include <stdio.h>
3697f17497SC.J. Collier
3797f17497SC.J. Collier#include <rte_eth_ring.h>
3897f17497SC.J. Collier#include <rte_ethdev.h>
3997f17497SC.J. Collier
4097f17497SC.J. Collierstatic struct rte_mempool *mp;
4197f17497SC.J. Collierstatic int tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte;
4297f17497SC.J. Collier
4397f17497SC.J. Collier#define SOCKET0 0
4497f17497SC.J. Collier#define RING_SIZE 256
4597f17497SC.J. Collier#define NUM_RINGS 2
4697f17497SC.J. Collier#define NB_MBUF 512
4797f17497SC.J. Collier
4897f17497SC.J. Collier
4997f17497SC.J. Collierstatic int
5097f17497SC.J. Colliertest_ethdev_configure_port(int port)
5197f17497SC.J. Collier{
5297f17497SC.J. Collier	struct rte_eth_conf null_conf;
5397f17497SC.J. Collier	struct rte_eth_link link;
5497f17497SC.J. Collier
5597f17497SC.J. Collier	memset(&null_conf, 0, sizeof(struct rte_eth_conf));
5697f17497SC.J. Collier
5797f17497SC.J. Collier	if (rte_eth_dev_configure(port, 1, 2, &null_conf) < 0) {
5897f17497SC.J. Collier		printf("Configure failed for port %d\n", port);
5997f17497SC.J. Collier		return -1;
6097f17497SC.J. Collier	}
6197f17497SC.J. Collier
6297f17497SC.J. Collier	/* Test queue release */
6397f17497SC.J. Collier	if (rte_eth_dev_configure(port, 1, 1, &null_conf) < 0) {
6497f17497SC.J. Collier		printf("Configure failed for port %d\n", port);
6597f17497SC.J. Collier		return -1;
6697f17497SC.J. Collier	}
6797f17497SC.J. Collier
6897f17497SC.J. Collier	if (rte_eth_tx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL) < 0) {
6997f17497SC.J. Collier		printf("TX queue setup failed port %d\n", port);
7097f17497SC.J. Collier		return -1;
7197f17497SC.J. Collier	}
7297f17497SC.J. Collier
7397f17497SC.J. Collier	if (rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET0,
7497f17497SC.J. Collier			NULL, mp) < 0) {
7597f17497SC.J. Collier		printf("RX queue setup failed port %d\n", port);
7697f17497SC.J. Collier		return -1;
7797f17497SC.J. Collier	}
7897f17497SC.J. Collier
7997f17497SC.J. Collier	if (rte_eth_dev_start(port) < 0) {
8097f17497SC.J. Collier		printf("Error starting port %d\n", port);
8197f17497SC.J. Collier		return -1;
8297f17497SC.J. Collier	}
8397f17497SC.J. Collier
8497f17497SC.J. Collier	rte_eth_link_get(port, &link);
8597f17497SC.J. Collier
8697f17497SC.J. Collier	return 0;
8797f17497SC.J. Collier}
8897f17497SC.J. Collier
8997f17497SC.J. Collierstatic int
9097f17497SC.J. Colliertest_send_basic_packets(void)
9197f17497SC.J. Collier{
9297f17497SC.J. Collier	struct rte_mbuf  bufs[RING_SIZE];
9397f17497SC.J. Collier	struct rte_mbuf *pbufs[RING_SIZE];
9497f17497SC.J. Collier	int i;
9597f17497SC.J. Collier
9697f17497SC.J. Collier	printf("Testing send and receive RING_SIZE/2 packets (tx_porta -> rx_portb)\n");
9797f17497SC.J. Collier
9897f17497SC.J. Collier	for (i = 0; i < RING_SIZE/2; i++)
9997f17497SC.J. Collier		pbufs[i] = &bufs[i];
10097f17497SC.J. Collier
10197f17497SC.J. Collier	if (rte_eth_tx_burst(tx_porta, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) {
10297f17497SC.J. Collier		printf("Failed to transmit packet burst port %d\n", tx_porta);
10397f17497SC.J. Collier		return -1;
10497f17497SC.J. Collier	}
10597f17497SC.J. Collier
10697f17497SC.J. Collier	if (rte_eth_rx_burst(rx_portb, 0, pbufs, RING_SIZE) != RING_SIZE/2) {
10797f17497SC.J. Collier		printf("Failed to receive packet burst on port %d\n", rx_portb);
10897f17497SC.J. Collier		return -1;
10997f17497SC.J. Collier	}
11097f17497SC.J. Collier
11197f17497SC.J. Collier	for (i = 0; i < RING_SIZE/2; i++)
11297f17497SC.J. Collier		if (pbufs[i] != &bufs[i]) {
11397f17497SC.J. Collier			printf("Error: received data does not match that transmitted\n");
11497f17497SC.J. Collier			return -1;
11597f17497SC.J. Collier		}
11697f17497SC.J. Collier
11797f17497SC.J. Collier	return 0;
11897f17497SC.J. Collier}
11997f17497SC.J. Collier
12097f17497SC.J. Collierstatic int
12197f17497SC.J. Colliertest_send_basic_packets_port(int port)
12297f17497SC.J. Collier{
12397f17497SC.J. Collier	struct rte_mbuf  bufs[RING_SIZE];
12497f17497SC.J. Collier	struct rte_mbuf *pbufs[RING_SIZE];
12597f17497SC.J. Collier	int i;
12697f17497SC.J. Collier
12797f17497SC.J. Collier	printf("Testing send and receive RING_SIZE/2 packets (cmdl_port0 -> cmdl_port0)\n");
12897f17497SC.J. Collier
12997f17497SC.J. Collier	for (i = 0; i < RING_SIZE/2; i++)
13097f17497SC.J. Collier		pbufs[i] = &bufs[i];
13197f17497SC.J. Collier
13297f17497SC.J. Collier	if (rte_eth_tx_burst(port, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) {
13397f17497SC.J. Collier		printf("Failed to transmit packet burst port %d\n", port);
13497f17497SC.J. Collier		return -1;
13597f17497SC.J. Collier	}
13697f17497SC.J. Collier
13797f17497SC.J. Collier	if (rte_eth_rx_burst(port, 0, pbufs, RING_SIZE) != RING_SIZE/2) {
13897f17497SC.J. Collier		printf("Failed to receive packet burst on port %d\n", port);
13997f17497SC.J. Collier		return -1;
14097f17497SC.J. Collier	}
14197f17497SC.J. Collier
14297f17497SC.J. Collier	for (i = 0; i < RING_SIZE/2; i++)
14397f17497SC.J. Collier		if (pbufs[i] != &bufs[i]) {
14497f17497SC.J. Collier			printf("Error: received data does not match that transmitted\n");
14597f17497SC.J. Collier			return -1;
14697f17497SC.J. Collier		}
14797f17497SC.J. Collier
14897f17497SC.J. Collier	return 0;
14997f17497SC.J. Collier}
15097f17497SC.J. Collier
15197f17497SC.J. Collier
15297f17497SC.J. Collierstatic int
15397f17497SC.J. Colliertest_get_stats(int port)
15497f17497SC.J. Collier{
15597f17497SC.J. Collier	struct rte_eth_stats stats;
15697f17497SC.J. Collier	struct rte_mbuf buf, *pbuf = &buf;
15797f17497SC.J. Collier
15897f17497SC.J. Collier	printf("Testing ring PMD stats_get port %d\n", port);
15997f17497SC.J. Collier
16097f17497SC.J. Collier	/* check stats of RXTX port, should all be zero */
16197f17497SC.J. Collier
16297f17497SC.J. Collier	rte_eth_stats_get(port, &stats);
16397f17497SC.J. Collier	if (stats.ipackets != 0 || stats.opackets != 0 ||
16497f17497SC.J. Collier			stats.ibytes != 0 || stats.obytes != 0 ||
16597f17497SC.J. Collier			stats.ierrors != 0 || stats.oerrors != 0) {
16697f17497SC.J. Collier		printf("Error: port %d stats are not zero\n", port);
16797f17497SC.J. Collier		return -1;
16897f17497SC.J. Collier	}
16997f17497SC.J. Collier
17097f17497SC.J. Collier	/* send and receive 1 packet and check for stats update */
17197f17497SC.J. Collier	if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) {
17297f17497SC.J. Collier		printf("Error sending packet to port %d\n", port);
17397f17497SC.J. Collier		return -1;
17497f17497SC.J. Collier	}
17597f17497SC.J. Collier
17697f17497SC.J. Collier	if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) {
17797f17497SC.J. Collier		printf("Error receiving packet from port %d\n", port);
17897f17497SC.J. Collier		return -1;
17997f17497SC.J. Collier	}
18097f17497SC.J. Collier
18197f17497SC.J. Collier	rte_eth_stats_get(port, &stats);
18297f17497SC.J. Collier	if (stats.ipackets != 1 || stats.opackets != 1 ||
18397f17497SC.J. Collier			stats.ibytes != 0 || stats.obytes != 0 ||
18497f17497SC.J. Collier			stats.ierrors != 0 || stats.oerrors != 0) {
18597f17497SC.J. Collier		printf("Error: port %d stats are not as expected\n", port);
18697f17497SC.J. Collier		return -1;
18797f17497SC.J. Collier	}
18897f17497SC.J. Collier	return 0;
18997f17497SC.J. Collier}
19097f17497SC.J. Collier
19197f17497SC.J. Collierstatic int
19297f17497SC.J. Colliertest_stats_reset(int port)
19397f17497SC.J. Collier{
19497f17497SC.J. Collier	struct rte_eth_stats stats;
19597f17497SC.J. Collier	struct rte_mbuf buf, *pbuf = &buf;
19697f17497SC.J. Collier
19797f17497SC.J. Collier	printf("Testing ring PMD stats_reset port %d\n", port);
19897f17497SC.J. Collier
19997f17497SC.J. Collier	rte_eth_stats_reset(port);
20097f17497SC.J. Collier
20197f17497SC.J. Collier	/* check stats of RXTX port, should all be zero */
20297f17497SC.J. Collier	rte_eth_stats_get(port, &stats);
20397f17497SC.J. Collier	if (stats.ipackets != 0 || stats.opackets != 0 ||
20497f17497SC.J. Collier			stats.ibytes != 0 || stats.obytes != 0 ||
20597f17497SC.J. Collier			stats.ierrors != 0 || stats.oerrors != 0) {
20697f17497SC.J. Collier		printf("Error: port %d stats are not zero\n", port);
20797f17497SC.J. Collier		return -1;
20897f17497SC.J. Collier	}
20997f17497SC.J. Collier
21097f17497SC.J. Collier	/* send and receive 1 packet and check for stats update */
21197f17497SC.J. Collier	if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) {
21297f17497SC.J. Collier		printf("Error sending packet to port %d\n", port);
21397f17497SC.J. Collier		return -1;
21497f17497SC.J. Collier	}
21597f17497SC.J. Collier
21697f17497SC.J. Collier	if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) {
21797f17497SC.J. Collier		printf("Error receiving packet from port %d\n", port);
21897f17497SC.J. Collier		return -1;
21997f17497SC.J. Collier	}
22097f17497SC.J. Collier
22197f17497SC.J. Collier	rte_eth_stats_get(port, &stats);
22297f17497SC.J. Collier	if (stats.ipackets != 1 || stats.opackets != 1 ||
22397f17497SC.J. Collier			stats.ibytes != 0 || stats.obytes != 0 ||
22497f17497SC.J. Collier			stats.ierrors != 0 || stats.oerrors != 0) {
22597f17497SC.J. Collier		printf("Error: port %d stats are not as expected\n", port);
22697f17497SC.J. Collier		return -1;
22797f17497SC.J. Collier	}
22897f17497SC.J. Collier
22997f17497SC.J. Collier	rte_eth_stats_reset(port);
23097f17497SC.J. Collier
23197f17497SC.J. Collier	/* check stats of RXTX port, should all be zero */
23297f17497SC.J. Collier	rte_eth_stats_get(port, &stats);
23397f17497SC.J. Collier	if (stats.ipackets != 0 || stats.opackets != 0 ||
23497f17497SC.J. Collier			stats.ibytes != 0 || stats.obytes != 0 ||
23597f17497SC.J. Collier			stats.ierrors != 0 || stats.oerrors != 0) {
23697f17497SC.J. Collier		printf("Error: port %d stats are not zero\n", port);
23797f17497SC.J. Collier		return -1;
23897f17497SC.J. Collier	}
23997f17497SC.J. Collier
24097f17497SC.J. Collier	return 0;
24197f17497SC.J. Collier}
24297f17497SC.J. Collier
24397f17497SC.J. Collierstatic int
24497f17497SC.J. Colliertest_pmd_ring_pair_create_attach(int portd, int porte)
24597f17497SC.J. Collier{
24697f17497SC.J. Collier	struct rte_eth_stats stats, stats2;
24797f17497SC.J. Collier	struct rte_mbuf buf, *pbuf = &buf;
24897f17497SC.J. Collier	struct rte_eth_conf null_conf;
24997f17497SC.J. Collier
2508e6d9d11SLuca Boccassi	memset(&null_conf, 0, sizeof(struct rte_eth_conf));
2518e6d9d11SLuca Boccassi
25297f17497SC.J. Collier	if ((rte_eth_dev_configure(portd, 1, 1, &null_conf) < 0)
25397f17497SC.J. Collier		|| (rte_eth_dev_configure(porte, 1, 1, &null_conf) < 0)) {
25497f17497SC.J. Collier		printf("Configure failed for port\n");
25597f17497SC.J. Collier		return -1;
25697f17497SC.J. Collier	}
25797f17497SC.J. Collier
25897f17497SC.J. Collier	if ((rte_eth_tx_queue_setup(portd, 0, RING_SIZE, SOCKET0, NULL) < 0)
25997f17497SC.J. Collier		|| (rte_eth_tx_queue_setup(porte, 0, RING_SIZE, SOCKET0, NULL) < 0)) {
26097f17497SC.J. Collier		printf("TX queue setup failed\n");
26197f17497SC.J. Collier		return -1;
26297f17497SC.J. Collier	}
26397f17497SC.J. Collier
26497f17497SC.J. Collier	if ((rte_eth_rx_queue_setup(portd, 0, RING_SIZE, SOCKET0, NULL, mp) < 0)
26597f17497SC.J. Collier		|| (rte_eth_rx_queue_setup(porte, 0, RING_SIZE, SOCKET0, NULL, mp) < 0)) {
26697f17497SC.J. Collier		printf("RX queue setup failed\n");
26797f17497SC.J. Collier		return -1;
26897f17497SC.J. Collier	}
26997f17497SC.J. Collier
27097f17497SC.J. Collier	if ((rte_eth_dev_start(portd) < 0)
27197f17497SC.J. Collier		|| (rte_eth_dev_start(porte) < 0)) {
27297f17497SC.J. Collier		printf("Error starting port\n");
27397f17497SC.J. Collier		return -1;
27497f17497SC.J. Collier	}
27597f17497SC.J. Collier
27697f17497SC.J. Collier	rte_eth_stats_reset(portd);
27797f17497SC.J. Collier	/* check stats of port, should all be zero */
27897f17497SC.J. Collier	rte_eth_stats_get(portd, &stats);
27997f17497SC.J. Collier	if (stats.ipackets != 0 || stats.opackets != 0 ||
28097f17497SC.J. Collier			stats.ibytes != 0 || stats.obytes != 0 ||
28197f17497SC.J. Collier			stats.ierrors != 0 || stats.oerrors != 0) {
28297f17497SC.J. Collier		printf("Error: port %d stats are not zero\n", portd);
28397f17497SC.J. Collier		return -1;
28497f17497SC.J. Collier	}
28597f17497SC.J. Collier
28697f17497SC.J. Collier	rte_eth_stats_reset(porte);
28797f17497SC.J. Collier	/* check stats of port, should all be zero */
28897f17497SC.J. Collier	rte_eth_stats_get(porte, &stats2);
28997f17497SC.J. Collier	if (stats2.ipackets != 0 || stats2.opackets != 0 ||
29097f17497SC.J. Collier			stats2.ibytes != 0 || stats2.obytes != 0 ||
29197f17497SC.J. Collier			stats2.ierrors != 0 || stats2.oerrors != 0) {
29297f17497SC.J. Collier		printf("Error: port %d stats are not zero\n", porte);
29397f17497SC.J. Collier		return -1;
29497f17497SC.J. Collier	}
29597f17497SC.J. Collier
29697f17497SC.J. Collier	/*
29797f17497SC.J. Collier	 * send and receive 1 packet (portd -> porte)
29897f17497SC.J. Collier	 * and check for stats update
29997f17497SC.J. Collier	 */
30097f17497SC.J. Collier	printf("Testing send and receive 1 packet (portd -> porte)\n");
30197f17497SC.J. Collier	if (rte_eth_tx_burst(portd, 0, &pbuf, 1) != 1) {
30297f17497SC.J. Collier		printf("Error sending packet to port %d\n", portd);
30397f17497SC.J. Collier		return -1;
30497f17497SC.J. Collier	}
30597f17497SC.J. Collier
30697f17497SC.J. Collier	if (rte_eth_rx_burst(porte, 0, &pbuf, 1) != 1) {
30797f17497SC.J. Collier		printf("Error receiving packet from port %d\n", porte);
30897f17497SC.J. Collier		return -1;
30997f17497SC.J. Collier	}
31097f17497SC.J. Collier
31197f17497SC.J. Collier	rte_eth_stats_get(portd, &stats);
31297f17497SC.J. Collier	rte_eth_stats_get(porte, &stats2);
31397f17497SC.J. Collier	if (stats.ipackets != 0 || stats.opackets != 1 ||
31497f17497SC.J. Collier			stats.ibytes != 0 || stats.obytes != 0 ||
31597f17497SC.J. Collier			stats.ierrors != 0 || stats.oerrors != 0) {
31697f17497SC.J. Collier		printf("Error: port %d stats are not as expected\n", portd);
31797f17497SC.J. Collier		return -1;
31897f17497SC.J. Collier	}
31997f17497SC.J. Collier
32097f17497SC.J. Collier	if (stats2.ipackets != 1 || stats2.opackets != 0 ||
32197f17497SC.J. Collier			stats2.ibytes != 0 || stats2.obytes != 0 ||
32297f17497SC.J. Collier			stats2.ierrors != 0 || stats2.oerrors != 0) {
32397f17497SC.J. Collier		printf("Error: port %d stats are not as expected\n", porte);
32497f17497SC.J. Collier		return -1;
32597f17497SC.J. Collier	}
32697f17497SC.J. Collier
32797f17497SC.J. Collier	/*
32897f17497SC.J. Collier	 * send and receive 1 packet (porte -> portd)
32997f17497SC.J. Collier	 * and check for stats update
33097f17497SC.J. Collier	 */
33197f17497SC.J. Collier	printf("Testing send and receive 1 packet (porte -> portd)\n");
33297f17497SC.J. Collier	if (rte_eth_tx_burst(porte, 0, &pbuf, 1) != 1) {
33397f17497SC.J. Collier		printf("Error sending packet to port %d\n", porte);
33497f17497SC.J. Collier		return -1;
33597f17497SC.J. Collier	}
33697f17497SC.J. Collier
33797f17497SC.J. Collier	if (rte_eth_rx_burst(portd, 0, &pbuf, 1) != 1) {
33897f17497SC.J. Collier		printf("Error receiving packet from port %d\n", portd);
33997f17497SC.J. Collier		return -1;
34097f17497SC.J. Collier	}
34197f17497SC.J. Collier
34297f17497SC.J. Collier	rte_eth_stats_get(portd, &stats);
34397f17497SC.J. Collier	rte_eth_stats_get(porte, &stats2);
34497f17497SC.J. Collier	if (stats.ipackets != 1 || stats.opackets != 1 ||
34597f17497SC.J. Collier			stats.ibytes != 0 || stats.obytes != 0 ||
34697f17497SC.J. Collier			stats.ierrors != 0 || stats.oerrors != 0) {
34797f17497SC.J. Collier		printf("Error: port %d stats are not as expected\n", portd);
34897f17497SC.J. Collier		return -1;
34997f17497SC.J. Collier	}
35097f17497SC.J. Collier
35197f17497SC.J. Collier	if (stats2.ipackets != 1 || stats2.opackets != 1 ||
35297f17497SC.J. Collier			stats2.ibytes != 0 || stats2.obytes != 0 ||
35397f17497SC.J. Collier			stats2.ierrors != 0 || stats2.oerrors != 0) {
35497f17497SC.J. Collier		printf("Error: port %d stats are not as expected\n", porte);
35597f17497SC.J. Collier		return -1;
35697f17497SC.J. Collier	}
35797f17497SC.J. Collier
35897f17497SC.J. Collier	/*
35997f17497SC.J. Collier	 * send and receive 1 packet (portd -> portd)
36097f17497SC.J. Collier	 * and check for stats update
36197f17497SC.J. Collier	 */
36297f17497SC.J. Collier	printf("Testing send and receive 1 packet (portd -> portd)\n");
36397f17497SC.J. Collier	if (rte_eth_tx_burst(portd, 0, &pbuf, 1) != 1) {
36497f17497SC.J. Collier		printf("Error sending packet to port %d\n", portd);
36597f17497SC.J. Collier		return -1;
36697f17497SC.J. Collier	}
36797f17497SC.J. Collier
36897f17497SC.J. Collier	if (rte_eth_rx_burst(portd, 0, &pbuf, 1) != 1) {
36997f17497SC.J. Collier		printf("Error receiving packet from port %d\n", porte);
37097f17497SC.J. Collier		return -1;
37197f17497SC.J. Collier	}
37297f17497SC.J. Collier
37397f17497SC.J. Collier	rte_eth_stats_get(portd, &stats);
37497f17497SC.J. Collier	rte_eth_stats_get(porte, &stats2);
37597f17497SC.J. Collier	if (stats.ipackets != 2 || stats.opackets != 2 ||
37697f17497SC.J. Collier			stats.ibytes != 0 || stats.obytes != 0 ||
37797f17497SC.J. Collier			stats.ierrors != 0 || stats.oerrors != 0) {
37897f17497SC.J. Collier		printf("Error: port %d stats are not as expected\n", portd);
37997f17497SC.J. Collier		return -1;
38097f17497SC.J. Collier	}
38197f17497SC.J. Collier
38297f17497SC.J. Collier	if (stats2.ipackets != 1 || stats2.opackets != 1 ||
38397f17497SC.J. Collier			stats2.ibytes != 0 || stats2.obytes != 0 ||
38497f17497SC.J. Collier			stats2.ierrors != 0 || stats2.oerrors != 0) {
38597f17497SC.J. Collier		printf("Error: port %d stats are not as expected\n", porte);
38697f17497SC.J. Collier		return -1;
38797f17497SC.J. Collier	}
38897f17497SC.J. Collier
38997f17497SC.J. Collier	/*
39097f17497SC.J. Collier	 * send and receive 1 packet (porte -> porte)
39197f17497SC.J. Collier	 * and check for stats update
39297f17497SC.J. Collier	 */
39397f17497SC.J. Collier	printf("Testing send and receive 1 packet (porte -> porte)\n");
39497f17497SC.J. Collier	if (rte_eth_tx_burst(porte, 0, &pbuf, 1) != 1) {
39597f17497SC.J. Collier		printf("Error sending packet to port %d\n", porte);
39697f17497SC.J. Collier		return -1;
39797f17497SC.J. Collier	}
39897f17497SC.J. Collier
39997f17497SC.J. Collier	if (rte_eth_rx_burst(porte, 0, &pbuf, 1) != 1) {
40097f17497SC.J. Collier		printf("Error receiving packet from port %d\n", porte);
40197f17497SC.J. Collier		return -1;
40297f17497SC.J. Collier	}
40397f17497SC.J. Collier
40497f17497SC.J. Collier	rte_eth_stats_get(portd, &stats);
40597f17497SC.J. Collier	rte_eth_stats_get(porte, &stats2);
40697f17497SC.J. Collier	if (stats.ipackets != 2 || stats.opackets != 2 ||
40797f17497SC.J. Collier			stats.ibytes != 0 || stats.obytes != 0 ||
40897f17497SC.J. Collier			stats.ierrors != 0 || stats.oerrors != 0) {
40997f17497SC.J. Collier		printf("Error: port %d stats are not as expected\n", portd);
41097f17497SC.J. Collier		return -1;
41197f17497SC.J. Collier	}
41297f17497SC.J. Collier
41397f17497SC.J. Collier	if (stats2.ipackets != 2 || stats2.opackets != 2 ||
41497f17497SC.J. Collier			stats2.ibytes != 0 || stats2.obytes != 0 ||
41597f17497SC.J. Collier			stats2.ierrors != 0 || stats2.oerrors != 0) {
41697f17497SC.J. Collier		printf("Error: port %d stats are not as expected\n", porte);
41797f17497SC.J. Collier		return -1;
41897f17497SC.J. Collier	}
41997f17497SC.J. Collier
42097f17497SC.J. Collier	rte_eth_dev_stop(portd);
42197f17497SC.J. Collier	rte_eth_dev_stop(porte);
42297f17497SC.J. Collier
42397f17497SC.J. Collier	return 0;
42497f17497SC.J. Collier}
42597f17497SC.J. Collier
42697f17497SC.J. Collierstatic int
42797f17497SC.J. Colliertest_pmd_ring(void)
42897f17497SC.J. Collier{
42997f17497SC.J. Collier	struct rte_ring *rxtx[NUM_RINGS];
43097f17497SC.J. Collier	int port, cmdl_port0 = -1;
43197f17497SC.J. Collier	uint8_t nb_ports;
43297f17497SC.J. Collier
43397f17497SC.J. Collier	nb_ports = rte_eth_dev_count();
43497f17497SC.J. Collier	printf("nb_ports=%d\n", (int)nb_ports);
43597f17497SC.J. Collier
43697f17497SC.J. Collier	/*  create the rings and eth_rings in the test code.
43797f17497SC.J. Collier	 *  This does not test the rte_pmd_ring_devinit function.
43897f17497SC.J. Collier	 *
4396b3e017eSChristian Ehrhardt	 *  Test with the command line option --vdev=net_ring0 to test rte_pmd_ring_devinit.
44097f17497SC.J. Collier	 */
44197f17497SC.J. Collier	rxtx[0] = rte_ring_create("R0", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ);
44297f17497SC.J. Collier	if (rxtx[0] == NULL) {
44397f17497SC.J. Collier		printf("rte_ring_create R0 failed");
44497f17497SC.J. Collier		return -1;
44597f17497SC.J. Collier	}
44697f17497SC.J. Collier
44797f17497SC.J. Collier	rxtx[1] = rte_ring_create("R1", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ);
44897f17497SC.J. Collier	if (rxtx[1] == NULL) {
44997f17497SC.J. Collier		printf("rte_ring_create R1 failed");
45097f17497SC.J. Collier		return -1;
45197f17497SC.J. Collier	}
45297f17497SC.J. Collier
4536b3e017eSChristian Ehrhardt	tx_porta = rte_eth_from_rings("net_ringa", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0);
4546b3e017eSChristian Ehrhardt	rx_portb = rte_eth_from_rings("net_ringb", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0);
4556b3e017eSChristian Ehrhardt	rxtx_portc = rte_eth_from_rings("net_ringc", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0);
4566b3e017eSChristian Ehrhardt	rxtx_portd = rte_eth_from_rings("net_ringd", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0);
4576b3e017eSChristian Ehrhardt	rxtx_porte = rte_eth_from_rings("net_ringe", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0);
45897f17497SC.J. Collier
45997f17497SC.J. Collier	printf("tx_porta=%d rx_portb=%d rxtx_portc=%d rxtx_portd=%d rxtx_porte=%d\n",
46097f17497SC.J. Collier			tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte);
46197f17497SC.J. Collier
46297f17497SC.J. Collier	if ((tx_porta == -1) || (rx_portb == -1) || (rxtx_portc == -1)
46397f17497SC.J. Collier		|| (rxtx_portd == -1) || (rxtx_porte == -1)) {
46497f17497SC.J. Collier		printf("rte_eth_from rings failed\n");
46597f17497SC.J. Collier		return -1;
46697f17497SC.J. Collier	}
46797f17497SC.J. Collier
46897f17497SC.J. Collier	mp = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32,
46997f17497SC.J. Collier		0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
47097f17497SC.J. Collier	if (mp == NULL)
47197f17497SC.J. Collier		return -1;
47297f17497SC.J. Collier
47397f17497SC.J. Collier	if ((tx_porta >= RTE_MAX_ETHPORTS) || (rx_portb >= RTE_MAX_ETHPORTS)
47497f17497SC.J. Collier		|| (rxtx_portc >= RTE_MAX_ETHPORTS)
47597f17497SC.J. Collier		|| (rxtx_portd >= RTE_MAX_ETHPORTS)
47697f17497SC.J. Collier		|| (rxtx_porte >= RTE_MAX_ETHPORTS)) {
47797f17497SC.J. Collier		printf(" port exceed max eth ports\n");
47897f17497SC.J. Collier		return -1;
47997f17497SC.J. Collier	}
48097f17497SC.J. Collier
48197f17497SC.J. Collier	if (test_ethdev_configure_port(tx_porta) < 0)
48297f17497SC.J. Collier		return -1;
48397f17497SC.J. Collier
48497f17497SC.J. Collier	if (test_ethdev_configure_port(rx_portb) < 0)
48597f17497SC.J. Collier		return -1;
48697f17497SC.J. Collier
48797f17497SC.J. Collier	if (test_ethdev_configure_port(rxtx_portc) < 0)
48897f17497SC.J. Collier		return -1;
48997f17497SC.J. Collier
49097f17497SC.J. Collier	if (test_send_basic_packets() < 0)
49197f17497SC.J. Collier		return -1;
49297f17497SC.J. Collier
49397f17497SC.J. Collier	if (test_get_stats(rxtx_portc) < 0)
49497f17497SC.J. Collier		return -1;
49597f17497SC.J. Collier
49697f17497SC.J. Collier	if (test_stats_reset(rxtx_portc) < 0)
49797f17497SC.J. Collier		return -1;
49897f17497SC.J. Collier
49997f17497SC.J. Collier	rte_eth_dev_stop(tx_porta);
50097f17497SC.J. Collier	rte_eth_dev_stop(rx_portb);
50197f17497SC.J. Collier	rte_eth_dev_stop(rxtx_portc);
50297f17497SC.J. Collier
50397f17497SC.J. Collier	if (test_pmd_ring_pair_create_attach(rxtx_portd, rxtx_porte) < 0)
50497f17497SC.J. Collier		return -1;
50597f17497SC.J. Collier
5066b3e017eSChristian Ehrhardt	/* find a port created with the --vdev=net_ring0 command line option */
50797f17497SC.J. Collier	for (port = 0; port < nb_ports; port++) {
50897f17497SC.J. Collier		struct rte_eth_dev_info dev_info;
50997f17497SC.J. Collier
51097f17497SC.J. Collier		rte_eth_dev_info_get(port, &dev_info);
51197f17497SC.J. Collier		if (!strcmp(dev_info.driver_name, "Rings PMD")) {
51297f17497SC.J. Collier			printf("found a command line ring port=%d\n", port);
51397f17497SC.J. Collier			cmdl_port0 = port;
51497f17497SC.J. Collier			break;
51597f17497SC.J. Collier		}
51697f17497SC.J. Collier	}
51797f17497SC.J. Collier	if (cmdl_port0 != -1) {
51897f17497SC.J. Collier		if (test_ethdev_configure_port(cmdl_port0) < 0)
51997f17497SC.J. Collier			return -1;
52097f17497SC.J. Collier		if (test_send_basic_packets_port(cmdl_port0) < 0)
52197f17497SC.J. Collier			return -1;
52297f17497SC.J. Collier		if (test_stats_reset(cmdl_port0) < 0)
52397f17497SC.J. Collier			return -1;
52497f17497SC.J. Collier		if (test_get_stats(cmdl_port0) < 0)
52597f17497SC.J. Collier			return -1;
52697f17497SC.J. Collier		rte_eth_dev_stop(cmdl_port0);
52797f17497SC.J. Collier	}
52897f17497SC.J. Collier	return 0;
52997f17497SC.J. Collier}
53097f17497SC.J. Collier
5315d4e5dcdSRicardo SalvetiREGISTER_TEST_COMMAND(ring_pmd_autotest, test_pmd_ring);
532