diff --git a/drivers/net/softnic/Makefile b/drivers/net/softnic/Makefile
index 97ac884..5da7842 100644
--- a/drivers/net/softnic/Makefile
+++ b/drivers/net/softnic/Makefile
@@ -22,6 +22,7 @@ LIBABIVER := 1
 # all source are stored in SRCS-y
 #
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_swq.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_SOFTNIC) += rte_eth_softnic_tm.c
 
 #
diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c
index ccf3bd4..be4b086 100644
--- a/drivers/net/softnic/rte_eth_softnic.c
+++ b/drivers/net/softnic/rte_eth_softnic.c
@@ -218,14 +218,21 @@ pmd_init(struct pmd_params *params)
 	if (p == NULL)
 		return NULL;
 
+	/* Params */
 	memcpy(&p->params, params, sizeof(p->params));
 
+	/* Resources */
+	softnic_swq_init(p);
 	return p;
 }
 
 static void
 pmd_free(struct pmd_internals *p)
 {
+	if (p == NULL)
+		return;
+
+	softnic_swq_free(p);
 	rte_free(p);
 }
 
diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h
index 6ae5954..002b25f 100644
--- a/drivers/net/softnic/rte_eth_softnic_internals.h
+++ b/drivers/net/softnic/rte_eth_softnic_internals.h
@@ -7,8 +7,10 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#include <sys/queue.h>
 
 #include <rte_mbuf.h>
+#include <rte_ring.h>
 #include <rte_ethdev.h>
 #include <rte_sched.h>
 #include <rte_ethdev_driver.h>
@@ -16,6 +18,8 @@
 
 #include "rte_eth_softnic.h"
 
+#define NAME_SIZE                                            64
+
 /**
  * PMD Parameters
  */
@@ -33,6 +37,21 @@ struct pmd_params {
 };
 
 /**
+ * SWQ
+ */
+struct softnic_swq_params {
+	uint32_t size;
+};
+
+struct softnic_swq {
+	TAILQ_ENTRY(softnic_swq) node;
+	char name[NAME_SIZE];
+	struct rte_ring *r;
+};
+
+TAILQ_HEAD(softnic_swq_list, softnic_swq);
+
+/**
  * Traffic Management (TM) Internals
  */
 
@@ -155,9 +174,29 @@ struct pmd_internals {
 	struct {
 		struct tm_internals tm; /**< Traffic Management */
 	} soft;
+
+	struct softnic_swq_list swq_list;
 };
 
 /**
+ * SWQ
+ */
+int
+softnic_swq_init(struct pmd_internals *p);
+
+void
+softnic_swq_free(struct pmd_internals *p);
+
+struct softnic_swq *
+softnic_swq_find(struct pmd_internals *p,
+	const char *name);
+
+struct softnic_swq *
+softnic_swq_create(struct pmd_internals *p,
+	const char *name,
+	struct softnic_swq_params *params);
+
+/**
  * Traffic Management (TM) Operation
  */
 extern const struct rte_tm_ops pmd_tm_ops;
diff --git a/drivers/net/softnic/rte_eth_softnic_swq.c b/drivers/net/softnic/rte_eth_softnic_swq.c
new file mode 100644
index 0000000..c46cad9
--- /dev/null
+++ b/drivers/net/softnic/rte_eth_softnic_swq.c
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <rte_string_fns.h>
+
+#include "rte_eth_softnic_internals.h"
+
+int
+softnic_swq_init(struct pmd_internals *p)
+{
+	TAILQ_INIT(&p->swq_list);
+
+	return 0;
+}
+
+void
+softnic_swq_free(struct pmd_internals *p)
+{
+	for ( ; ; ) {
+		struct softnic_swq *swq;
+
+		swq = TAILQ_FIRST(&p->swq_list);
+		if (swq == NULL)
+			break;
+
+		TAILQ_REMOVE(&p->swq_list, swq, node);
+		rte_ring_free(swq->r);
+		free(swq);
+	}
+}
+
+struct softnic_swq *
+softnic_swq_find(struct pmd_internals *p,
+	const char *name)
+{
+	struct softnic_swq *swq;
+
+	if (name == NULL)
+		return NULL;
+
+	TAILQ_FOREACH(swq, &p->swq_list, node)
+		if (strcmp(swq->name, name) == 0)
+			return swq;
+
+	return NULL;
+}
+
+struct softnic_swq *
+softnic_swq_create(struct pmd_internals *p,
+	const char *name,
+	struct softnic_swq_params *params)
+{
+	char ring_name[NAME_SIZE];
+	struct softnic_swq *swq;
+	struct rte_ring *r;
+	unsigned int flags = RING_F_SP_ENQ | RING_F_SC_DEQ;
+
+	/* Check input params */
+	if (name == NULL ||
+		softnic_swq_find(p, name) ||
+		params == NULL ||
+		params->size == 0)
+		return NULL;
+
+	/* Resource create */
+	snprintf(ring_name, sizeof(ring_name), "%s_%s",
+		p->params.name,
+		name);
+
+	r = rte_ring_create(ring_name,
+		params->size,
+		p->params.cpu_id,
+		flags);
+
+	if (r == NULL)
+		return NULL;
+
+	/* Node allocation */
+	swq = calloc(1, sizeof(struct softnic_swq));
+	if (swq == NULL) {
+		rte_ring_free(r);
+		return NULL;
+	}
+
+	/* Node fill in */
+	strlcpy(swq->name, name, sizeof(swq->name));
+	swq->r = r;
+
+	/* Node add to list */
+	TAILQ_INSERT_TAIL(&p->swq_list, swq, node);
+
+	return swq;
+}
