15129044dSC.J. Collier/*-
25129044dSC.J. Collier *   BSD LICENSE
35129044dSC.J. Collier *
45129044dSC.J. Collier *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
55129044dSC.J. Collier *   All rights reserved.
65129044dSC.J. Collier *
75129044dSC.J. Collier *   Redistribution and use in source and binary forms, with or without
85129044dSC.J. Collier *   modification, are permitted provided that the following conditions
95129044dSC.J. Collier *   are met:
105129044dSC.J. Collier *
115129044dSC.J. Collier *     * Redistributions of source code must retain the above copyright
125129044dSC.J. Collier *       notice, this list of conditions and the following disclaimer.
135129044dSC.J. Collier *     * Redistributions in binary form must reproduce the above copyright
145129044dSC.J. Collier *       notice, this list of conditions and the following disclaimer in
155129044dSC.J. Collier *       the documentation and/or other materials provided with the
165129044dSC.J. Collier *       distribution.
175129044dSC.J. Collier *     * Neither the name of Intel Corporation nor the names of its
185129044dSC.J. Collier *       contributors may be used to endorse or promote products derived
195129044dSC.J. Collier *       from this software without specific prior written permission.
205129044dSC.J. Collier *
215129044dSC.J. Collier *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
225129044dSC.J. Collier *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
235129044dSC.J. Collier *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
245129044dSC.J. Collier *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
255129044dSC.J. Collier *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
265129044dSC.J. Collier *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
275129044dSC.J. Collier *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
285129044dSC.J. Collier *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
295129044dSC.J. Collier *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
305129044dSC.J. Collier *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
315129044dSC.J. Collier *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
325129044dSC.J. Collier */
335129044dSC.J. Collier
345129044dSC.J. Collier#include <stdlib.h>
355129044dSC.J. Collier#include <stdio.h>
365129044dSC.J. Collier#include <string.h>
375129044dSC.J. Collier#include <stdint.h>
385129044dSC.J. Collier#include <unistd.h>
395129044dSC.J. Collier
405129044dSC.J. Collier#include "test.h"
415129044dSC.J. Collier
425129044dSC.J. Collier#include <rte_cycles.h>
435129044dSC.J. Collier#include <rte_ether.h>
445129044dSC.J. Collier#include <rte_ip.h>
455129044dSC.J. Collier#include <rte_byteorder.h>
465129044dSC.J. Collier#include <rte_sched.h>
475129044dSC.J. Collier
485129044dSC.J. Collier
495129044dSC.J. Collier#define SUBPORT         0
505129044dSC.J. Collier#define PIPE            1
515129044dSC.J. Collier#define TC              2
525129044dSC.J. Collier#define QUEUE           3
535129044dSC.J. Collier
545129044dSC.J. Collierstatic struct rte_sched_subport_params subport_param[] = {
555129044dSC.J. Collier	{
565129044dSC.J. Collier		.tb_rate = 1250000000,
575129044dSC.J. Collier		.tb_size = 1000000,
585129044dSC.J. Collier
595129044dSC.J. Collier		.tc_rate = {1250000000, 1250000000, 1250000000, 1250000000},
605129044dSC.J. Collier		.tc_period = 10,
615129044dSC.J. Collier	},
625129044dSC.J. Collier};
635129044dSC.J. Collier
645129044dSC.J. Collierstatic struct rte_sched_pipe_params pipe_profile[] = {
655129044dSC.J. Collier	{ /* Profile #0 */
665129044dSC.J. Collier		.tb_rate = 305175,
675129044dSC.J. Collier		.tb_size = 1000000,
685129044dSC.J. Collier
695129044dSC.J. Collier		.tc_rate = {305175, 305175, 305175, 305175},
705129044dSC.J. Collier		.tc_period = 40,
715129044dSC.J. Collier
725129044dSC.J. Collier		.wrr_weights = {1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1},
735129044dSC.J. Collier	},
745129044dSC.J. Collier};
755129044dSC.J. Collier
765129044dSC.J. Collierstatic struct rte_sched_port_params port_param = {
775129044dSC.J. Collier	.socket = 0, /* computed */
785129044dSC.J. Collier	.rate = 0, /* computed */
795129044dSC.J. Collier	.mtu = 1522,
805129044dSC.J. Collier	.frame_overhead = RTE_SCHED_FRAME_OVERHEAD_DEFAULT,
815129044dSC.J. Collier	.n_subports_per_port = 1,
823d9b7210SChristian Ehrhardt	.n_pipes_per_subport = 1024,
833d9b7210SChristian Ehrhardt	.qsize = {32, 32, 32, 32},
845129044dSC.J. Collier	.pipe_profiles = pipe_profile,
855129044dSC.J. Collier	.n_pipe_profiles = 1,
865129044dSC.J. Collier};
875129044dSC.J. Collier
885129044dSC.J. Collier#define NB_MBUF          32
895129044dSC.J. Collier#define MBUF_DATA_SZ     (2048 + RTE_PKTMBUF_HEADROOM)
905129044dSC.J. Collier#define MEMPOOL_CACHE_SZ 0
915129044dSC.J. Collier#define SOCKET           0
925129044dSC.J. Collier
935129044dSC.J. Collier
945129044dSC.J. Collierstatic struct rte_mempool *
955129044dSC.J. Colliercreate_mempool(void)
965129044dSC.J. Collier{
975129044dSC.J. Collier	struct rte_mempool * mp;
985129044dSC.J. Collier
995129044dSC.J. Collier	mp = rte_mempool_lookup("test_sched");
1005129044dSC.J. Collier	if (!mp)
1015129044dSC.J. Collier		mp = rte_pktmbuf_pool_create("test_sched", NB_MBUF,
1025129044dSC.J. Collier			MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, SOCKET);
1035129044dSC.J. Collier
1045129044dSC.J. Collier	return mp;
1055129044dSC.J. Collier}
1065129044dSC.J. Collier
1075129044dSC.J. Collierstatic void
1085129044dSC.J. Collierprepare_pkt(struct rte_mbuf *mbuf)
1095129044dSC.J. Collier{
1105129044dSC.J. Collier	struct ether_hdr *eth_hdr;
1115129044dSC.J. Collier	struct vlan_hdr *vlan1, *vlan2;
1125129044dSC.J. Collier	struct ipv4_hdr *ip_hdr;
1135129044dSC.J. Collier
1145129044dSC.J. Collier	/* Simulate a classifier */
1155129044dSC.J. Collier	eth_hdr = rte_pktmbuf_mtod(mbuf, struct ether_hdr *);
1165129044dSC.J. Collier	vlan1 = (struct vlan_hdr *)(&eth_hdr->ether_type );
1175129044dSC.J. Collier	vlan2 = (struct vlan_hdr *)((uintptr_t)&eth_hdr->ether_type + sizeof(struct vlan_hdr));
1185129044dSC.J. Collier	eth_hdr = (struct ether_hdr *)((uintptr_t)&eth_hdr->ether_type + 2 *sizeof(struct vlan_hdr));
1195129044dSC.J. Collier	ip_hdr = (struct ipv4_hdr *)((uintptr_t)eth_hdr +  sizeof(eth_hdr->ether_type));
1205129044dSC.J. Collier
1215129044dSC.J. Collier	vlan1->vlan_tci = rte_cpu_to_be_16(SUBPORT);
1225129044dSC.J. Collier	vlan2->vlan_tci = rte_cpu_to_be_16(PIPE);
1235129044dSC.J. Collier	eth_hdr->ether_type =  rte_cpu_to_be_16(ETHER_TYPE_IPv4);
1245129044dSC.J. Collier	ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE);
1255129044dSC.J. Collier
1265129044dSC.J. Collier
1275129044dSC.J. Collier	rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE, e_RTE_METER_YELLOW);
1285129044dSC.J. Collier
1295129044dSC.J. Collier	/* 64 byte packet */
1305129044dSC.J. Collier	mbuf->pkt_len  = 60;
1315129044dSC.J. Collier	mbuf->data_len = 60;
1325129044dSC.J. Collier}
1335129044dSC.J. Collier
1345129044dSC.J. Collier
1355129044dSC.J. Collier/**
1365129044dSC.J. Collier * test main entrance for library sched
1375129044dSC.J. Collier */
1385129044dSC.J. Collierstatic int
1395129044dSC.J. Colliertest_sched(void)
1405129044dSC.J. Collier{
1415129044dSC.J. Collier	struct rte_mempool *mp = NULL;
1425129044dSC.J. Collier	struct rte_sched_port *port = NULL;
1435129044dSC.J. Collier	uint32_t pipe;
1445129044dSC.J. Collier	struct rte_mbuf *in_mbufs[10];
1455129044dSC.J. Collier	struct rte_mbuf *out_mbufs[10];
1465129044dSC.J. Collier	int i;
1475129044dSC.J. Collier
1485129044dSC.J. Collier	int err;
1495129044dSC.J. Collier
1505129044dSC.J. Collier	mp = create_mempool();
1515129044dSC.J. Collier	TEST_ASSERT_NOT_NULL(mp, "Error creating mempool\n");
1525129044dSC.J. Collier
1535129044dSC.J. Collier	port_param.socket = 0;
1545129044dSC.J. Collier	port_param.rate = (uint64_t) 10000 * 1000 * 1000 / 8;
1555129044dSC.J. Collier
1565129044dSC.J. Collier	port = rte_sched_port_config(&port_param);
1575129044dSC.J. Collier	TEST_ASSERT_NOT_NULL(port, "Error config sched port\n");
1585129044dSC.J. Collier
1595129044dSC.J. Collier	err = rte_sched_subport_config(port, SUBPORT, subport_param);
1605129044dSC.J. Collier	TEST_ASSERT_SUCCESS(err, "Error config sched, err=%d\n", err);
1615129044dSC.J. Collier
1625129044dSC.J. Collier	for (pipe = 0; pipe < port_param.n_pipes_per_subport; pipe ++) {
1635129044dSC.J. Collier		err = rte_sched_pipe_config(port, SUBPORT, pipe, 0);
1645129044dSC.J. Collier		TEST_ASSERT_SUCCESS(err, "Error config sched pipe %u, err=%d\n", pipe, err);
1655129044dSC.J. Collier	}
1665129044dSC.J. Collier
1675129044dSC.J. Collier	for (i = 0; i < 10; i++) {
1685129044dSC.J. Collier		in_mbufs[i] = rte_pktmbuf_alloc(mp);
1695129044dSC.J. Collier		TEST_ASSERT_NOT_NULL(in_mbufs[i], "Packet allocation failed\n");
1705129044dSC.J. Collier		prepare_pkt(in_mbufs[i]);
1715129044dSC.J. Collier	}
1725129044dSC.J. Collier
1735129044dSC.J. Collier
1745129044dSC.J. Collier	err = rte_sched_port_enqueue(port, in_mbufs, 10);
1755129044dSC.J. Collier	TEST_ASSERT_EQUAL(err, 10, "Wrong enqueue, err=%d\n", err);
1765129044dSC.J. Collier
1775129044dSC.J. Collier	err = rte_sched_port_dequeue(port, out_mbufs, 10);
1785129044dSC.J. Collier	TEST_ASSERT_EQUAL(err, 10, "Wrong dequeue, err=%d\n", err);
1795129044dSC.J. Collier
1805129044dSC.J. Collier	for (i = 0; i < 10; i++) {
1815129044dSC.J. Collier		enum rte_meter_color color;
1825129044dSC.J. Collier		uint32_t subport, traffic_class, queue;
1835129044dSC.J. Collier
1845129044dSC.J. Collier		color = rte_sched_port_pkt_read_color(out_mbufs[i]);
1855129044dSC.J. Collier		TEST_ASSERT_EQUAL(color, e_RTE_METER_YELLOW, "Wrong color\n");
1865129044dSC.J. Collier
1875129044dSC.J. Collier		rte_sched_port_pkt_read_tree_path(out_mbufs[i],
1885129044dSC.J. Collier				&subport, &pipe, &traffic_class, &queue);
1895129044dSC.J. Collier
1905129044dSC.J. Collier		TEST_ASSERT_EQUAL(subport, SUBPORT, "Wrong subport\n");
1915129044dSC.J. Collier		TEST_ASSERT_EQUAL(pipe, PIPE, "Wrong pipe\n");
1925129044dSC.J. Collier		TEST_ASSERT_EQUAL(traffic_class, TC, "Wrong traffic_class\n");
1935129044dSC.J. Collier		TEST_ASSERT_EQUAL(queue, QUEUE, "Wrong queue\n");
1945129044dSC.J. Collier
1955129044dSC.J. Collier	}
1965129044dSC.J. Collier
1975129044dSC.J. Collier
1985129044dSC.J. Collier	struct rte_sched_subport_stats subport_stats;
1995129044dSC.J. Collier	uint32_t tc_ov;
2005129044dSC.J. Collier	rte_sched_subport_read_stats(port, SUBPORT, &subport_stats, &tc_ov);
2015129044dSC.J. Collier#if 0
2025129044dSC.J. Collier	TEST_ASSERT_EQUAL(subport_stats.n_pkts_tc[TC-1], 10, "Wrong subport stats\n");
2035129044dSC.J. Collier#endif
2045129044dSC.J. Collier	struct rte_sched_queue_stats queue_stats;
2055129044dSC.J. Collier	uint16_t qlen;
2065129044dSC.J. Collier	rte_sched_queue_read_stats(port, QUEUE, &queue_stats, &qlen);
2075129044dSC.J. Collier#if 0
2085129044dSC.J. Collier	TEST_ASSERT_EQUAL(queue_stats.n_pkts, 10, "Wrong queue stats\n");
2095129044dSC.J. Collier#endif
2105129044dSC.J. Collier
2115129044dSC.J. Collier	rte_sched_port_free(port);
2125129044dSC.J. Collier
2135129044dSC.J. Collier	return 0;
2145129044dSC.J. Collier}
2155129044dSC.J. Collier
2169ecc306dSRicardo SalvetiREGISTER_TEST_COMMAND(sched_autotest, test_sched);
217