diff --git a/test/validation/pktio/pktio.c b/test/validation/pktio/pktio.c
index 14c1f5e..5fe8293 100644
--- a/test/validation/pktio/pktio.c
+++ b/test/validation/pktio/pktio.c
@@ -34,6 +34,7 @@ typedef struct {
 	odp_pktio_t id;
 	odp_queue_t outq;
 	odp_queue_t inq;
+	odp_pktio_input_mode_t in_mode;
 } pktio_info_t;
 
 /** magic number and sequence at start of UDP payload */
@@ -250,7 +251,7 @@ static int default_pool_create(void)
 	return 0;
 }
 
-static odp_pktio_t create_pktio(int iface_idx, odp_queue_type_t q_type)
+static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t mode)
 {
 	odp_pktio_t pktio;
 	odp_pktio_param_t pktio_param;
@@ -258,10 +259,7 @@ static odp_pktio_t create_pktio(int iface_idx, odp_queue_type_t q_type)
 
 	odp_pktio_param_init(&pktio_param);
 
-	if (q_type == ODP_QUEUE_TYPE_POLL)
-		pktio_param.in_mode = ODP_PKTIN_MODE_POLL;
-	else
-		pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
+	pktio_param.in_mode = mode;
 
 	pktio = odp_pktio_open(iface, pool[iface_idx], &pktio_param);
 	if (pktio == ODP_PKTIO_INVALID)
@@ -348,33 +346,41 @@ static odp_event_t queue_deq_wait_time(odp_queue_t queue, uint64_t ns)
 	return ODP_EVENT_INVALID;
 }
 
-static odp_packet_t wait_for_packet(odp_queue_t queue,
+static odp_packet_t wait_for_packet(pktio_info_t *pktio_rx,
 				    uint32_t seq, uint64_t ns)
 {
 	uint64_t start, now, diff;
 	odp_event_t ev;
-	odp_packet_t pkt = ODP_PACKET_INVALID;
+	odp_packet_t pkt;
 	uint64_t wait;
 
 	start = odp_time_cycles();
 	wait = odp_schedule_wait_time(ns);
 
 	do {
-		if (queue != ODP_QUEUE_INVALID &&
-		    odp_queue_type(queue) == ODP_QUEUE_TYPE_POLL)
-			ev = queue_deq_wait_time(queue, ns);
-		else
-			ev  = odp_schedule(NULL, wait);
-
-		if (ev != ODP_EVENT_INVALID) {
-			if (odp_event_type(ev) == ODP_EVENT_PACKET) {
-				pkt = odp_packet_from_event(ev);
-				if (pktio_pkt_seq(pkt) == seq)
-					return pkt;
+		pkt = ODP_PACKET_INVALID;
+
+		if (pktio_rx->in_mode == ODP_PKTIN_MODE_RECV) {
+			odp_pktio_recv(pktio_rx->id, &pkt, 1);
+		} else {
+			if (pktio_rx->in_mode == ODP_PKTIN_MODE_POLL)
+				ev = queue_deq_wait_time(pktio_rx->inq, ns);
+			else
+				ev = odp_schedule(NULL, wait);
+
+			if (ev != ODP_EVENT_INVALID) {
+				if (odp_event_type(ev) == ODP_EVENT_PACKET)
+					pkt = odp_packet_from_event(ev);
+				else
+					odp_event_free(ev);
 			}
+		}
 
-			/* not interested in this event */
-			odp_event_free(ev);
+		if (pkt != ODP_PACKET_INVALID) {
+			if (pktio_pkt_seq(pkt) == seq)
+				return pkt;
+
+			odp_packet_free(pkt);
 		}
 
 		now = odp_time_cycles();
@@ -438,7 +444,7 @@ static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b,
 
 	/* and wait for them to arrive back */
 	for (i = 0; i < num_pkts; ++i) {
-		rx_pkt = wait_for_packet(pktio_b->inq, tx_seq[i], ODP_TIME_SEC);
+		rx_pkt = wait_for_packet(pktio_b, tx_seq[i], ODP_TIME_SEC);
 
 		if (rx_pkt == ODP_PACKET_INVALID)
 			break;
@@ -450,7 +456,7 @@ static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b,
 	CU_ASSERT(i == num_pkts);
 }
 
-static void test_txrx(odp_queue_type_t q_type, int num_pkts)
+static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts)
 {
 	int ret, i, if_b;
 	pktio_info_t pktios[MAX_NUM_IFACES];
@@ -461,17 +467,21 @@ static void test_txrx(odp_queue_type_t q_type, int num_pkts)
 		io = &pktios[i];
 
 		io->name = iface_name[i];
-		io->id   = create_pktio(i, q_type);
+		io->id   = create_pktio(i, in_mode);
 		if (io->id == ODP_PKTIO_INVALID) {
 			CU_FAIL("failed to open iface");
 			return;
 		}
-		create_inq(io->id, q_type);
 		io->outq = odp_pktio_outq_getdef(io->id);
-		if (q_type == ODP_QUEUE_TYPE_POLL)
+		io->in_mode = in_mode;
+
+		if (in_mode == ODP_PKTIN_MODE_POLL) {
+			create_inq(io->id, ODP_QUEUE_TYPE_POLL);
 			io->inq = odp_pktio_inq_getdef(io->id);
-		else
+		} else if (in_mode == ODP_PKTIN_MODE_SCHED) {
+			create_inq(io->id, ODP_QUEUE_TYPE_SCHED);
 			io->inq = ODP_QUEUE_INVALID;
+		}
 
 		ret = odp_pktio_start(io->id);
 		CU_ASSERT(ret == 0);
@@ -483,7 +493,8 @@ static void test_txrx(odp_queue_type_t q_type, int num_pkts)
 	pktio_txrx_multi(&pktios[0], &pktios[if_b], num_pkts);
 
 	for (i = 0; i < num_ifaces; ++i) {
-		destroy_inq(pktios[i].id);
+		if (in_mode != ODP_PKTIN_MODE_RECV)
+			destroy_inq(pktios[i].id);
 		ret = odp_pktio_close(pktios[i].id);
 		CU_ASSERT(ret == 0);
 	}
@@ -491,22 +502,32 @@ static void test_txrx(odp_queue_type_t q_type, int num_pkts)
 
 void pktio_test_poll_queue(void)
 {
-	test_txrx(ODP_QUEUE_TYPE_POLL, 1);
+	test_txrx(ODP_PKTIN_MODE_POLL, 1);
 }
 
 void pktio_test_poll_multi(void)
 {
-	test_txrx(ODP_QUEUE_TYPE_POLL, 4);
+	test_txrx(ODP_PKTIN_MODE_POLL, 4);
 }
 
 void pktio_test_sched_queue(void)
 {
-	test_txrx(ODP_QUEUE_TYPE_SCHED, 1);
+	test_txrx(ODP_PKTIN_MODE_SCHED, 1);
 }
 
 void pktio_test_sched_multi(void)
 {
-	test_txrx(ODP_QUEUE_TYPE_SCHED, 4);
+	test_txrx(ODP_PKTIN_MODE_SCHED, 4);
+}
+
+void pktio_test_recv(void)
+{
+	test_txrx(ODP_PKTIN_MODE_RECV, 1);
+}
+
+void pktio_test_recv_multi(void)
+{
+	test_txrx(ODP_PKTIN_MODE_RECV, 4);
 }
 
 void pktio_test_jumbo(void)
@@ -521,7 +542,7 @@ void pktio_test_mtu(void)
 	int ret;
 	int mtu;
 
-	odp_pktio_t pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
+	odp_pktio_t pktio = create_pktio(0, ODP_PKTIN_MODE_SCHED);
 	CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
 
 	mtu = odp_pktio_mtu(pktio);
@@ -537,7 +558,7 @@ void pktio_test_promisc(void)
 {
 	int ret;
 
-	odp_pktio_t pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
+	odp_pktio_t pktio = create_pktio(0, ODP_PKTIN_MODE_SCHED);
 	CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
 
 	ret = odp_pktio_promisc_mode_set(pktio, 1);
@@ -565,7 +586,7 @@ void pktio_test_mac(void)
 	int ret;
 	odp_pktio_t pktio;
 
-	pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
+	pktio = create_pktio(0, ODP_PKTIN_MODE_SCHED);
 	CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
 
 	printf("testing mac for %s\n", iface_name[0]);
@@ -593,7 +614,7 @@ void pktio_test_inq_remdef(void)
 	uint64_t wait;
 	int i;
 
-	pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
+	pktio = create_pktio(0, ODP_PKTIN_MODE_SCHED);
 	CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
 	CU_ASSERT(create_inq(pktio, ODP_QUEUE_TYPE_POLL) == 0);
 	inq = odp_pktio_inq_getdef(pktio);
@@ -621,7 +642,7 @@ void pktio_test_open(void)
 
 	/* test the sequence open->close->open->close() */
 	for (i = 0; i < 2; ++i) {
-		pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
+		pktio = create_pktio(0, ODP_PKTIN_MODE_SCHED);
 		CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
 		CU_ASSERT(odp_pktio_close(pktio) == 0);
 	}
@@ -660,7 +681,7 @@ void pktio_test_inq(void)
 {
 	odp_pktio_t pktio;
 
-	pktio = create_pktio(0, ODP_QUEUE_TYPE_SCHED);
+	pktio = create_pktio(0, ODP_PKTIN_MODE_POLL);
 	CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
 
 	CU_ASSERT(create_inq(pktio, ODP_QUEUE_TYPE_POLL) == 0);
@@ -679,7 +700,7 @@ static void pktio_test_start_stop(void)
 	uint64_t wait = odp_schedule_wait_time(ODP_TIME_MSEC);
 
 	for (i = 0; i < num_ifaces; i++) {
-		pktio[i] = create_pktio(i, ODP_QUEUE_TYPE_SCHED);
+		pktio[i] = create_pktio(i, ODP_PKTIN_MODE_SCHED);
 		CU_ASSERT_FATAL(pktio[i] != ODP_PKTIO_INVALID);
 		create_inq(pktio[i],  ODP_QUEUE_TYPE_SCHED);
 	}
@@ -885,6 +906,8 @@ odp_testinfo_t pktio_suite_unsegmented[] = {
 	ODP_TEST_INFO(pktio_test_poll_multi),
 	ODP_TEST_INFO(pktio_test_sched_queue),
 	ODP_TEST_INFO(pktio_test_sched_multi),
+	ODP_TEST_INFO(pktio_test_recv),
+	ODP_TEST_INFO(pktio_test_recv_multi),
 	ODP_TEST_INFO(pktio_test_jumbo),
 	ODP_TEST_INFO(pktio_test_mtu),
 	ODP_TEST_INFO(pktio_test_promisc),
@@ -899,6 +922,8 @@ odp_testinfo_t pktio_suite_segmented[] = {
 	ODP_TEST_INFO(pktio_test_poll_multi),
 	ODP_TEST_INFO(pktio_test_sched_queue),
 	ODP_TEST_INFO(pktio_test_sched_multi),
+	ODP_TEST_INFO(pktio_test_recv),
+	ODP_TEST_INFO(pktio_test_recv_multi),
 	ODP_TEST_INFO(pktio_test_jumbo),
 	ODP_TEST_INFO_NULL
 };
diff --git a/test/validation/pktio/pktio.h b/test/validation/pktio/pktio.h
index 2928dbe..f22ff25 100644
--- a/test/validation/pktio/pktio.h
+++ b/test/validation/pktio/pktio.h
@@ -14,6 +14,8 @@ void pktio_test_poll_queue(void);
 void pktio_test_poll_multi(void);
 void pktio_test_sched_queue(void);
 void pktio_test_sched_multi(void);
+void pktio_test_recv(void);
+void pktio_test_recv_multi(void);
 void pktio_test_jumbo(void);
 void pktio_test_mtu(void);
 void pktio_test_promisc(void);
