armada: introduce dev_armada plugin

Also retires old marvell plugin.

Change-Id: Icedec11f5661909058fdfe8d5fc455306adafacd
Type: feature
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index 4a65b35..c6dbd8b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -500,10 +500,10 @@
 M:	Damjan Marion <damarion@cisco.com>
 F:	src/plugins/memif/
 
-Plugin - Marvell MUSDK device driver
-I:	marvell
+Plugin - Marvell Armada device driver
+I:	armada
 M:	Damjan Marion <damarion@cisco.com>
-F:	src/plugins/marvell/
+F:	src/plugins/dev_armada/
 
 Plugin - performance counter
 I:	perfmon
diff --git a/docs/developer/plugins/dev_armada.rst b/docs/developer/plugins/dev_armada.rst
new file mode 120000
index 0000000..a545313
--- /dev/null
+++ b/docs/developer/plugins/dev_armada.rst
@@ -0,0 +1 @@
+../../../src/plugins/dev_armada/README.rst
\ No newline at end of file
diff --git a/docs/developer/plugins/index.rst b/docs/developer/plugins/index.rst
index c9081a8..393eefe 100644
--- a/docs/developer/plugins/index.rst
+++ b/docs/developer/plugins/index.rst
@@ -19,9 +19,9 @@
 
     quic
     cnat
+    dev_armada
     lcp
     srv6/index
-    marvell
     lldp
     nat64
     nat44_ei_ha
diff --git a/docs/developer/plugins/marvell.rst b/docs/developer/plugins/marvell.rst
deleted file mode 120000
index 28f0cd0..0000000
--- a/docs/developer/plugins/marvell.rst
+++ /dev/null
@@ -1 +0,0 @@
-../../../src/plugins/marvell/README.rst
\ No newline at end of file
diff --git a/src/plugins/dev_armada/CMakeLists.txt b/src/plugins/dev_armada/CMakeLists.txt
new file mode 100644
index 0000000..f955a9b
--- /dev/null
+++ b/src/plugins/dev_armada/CMakeLists.txt
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: Apache-2.0
+# Copyright(c) 2022 Cisco Systems, Inc.
+
+
+find_path(MUSDK_INCLUDE_DIR NAMES mv_std.h)
+find_library(MUSDK_LIB NAMES libmusdk.a)
+
+if(NOT MUSDK_INCLUDE_DIR OR NOT MUSDK_LIB)
+  message(WARNING "Marvell MUSDK not found - dev_armada plugin disabled")
+  return()
+endif()
+
+get_filename_component(MUSDK_LIB_DIR ${MUSDK_LIB} DIRECTORY)
+set(MUSDK_LINK_FLAGS "-Wl,--whole-archive,${MUSDK_LIB_DIR}/libmusdk.a,--no-whole-archive")
+
+add_vpp_plugin(dev_armada
+  SOURCES
+  plugin.c
+  pp2/init.c
+  pp2/format.c
+  pp2/port.c
+  pp2/queue.c
+  pp2/rx.c
+  pp2/tx.c
+
+  LINK_FLAGS
+  ${MUSDK_LINK_FLAGS}
+)
+include_directories(${MUSDK_INCLUDE_DIR})
+
diff --git a/src/plugins/dev_armada/README.rst b/src/plugins/dev_armada/README.rst
new file mode 100644
index 0000000..2c757d0
--- /dev/null
+++ b/src/plugins/dev_armada/README.rst
@@ -0,0 +1,61 @@
+Armada device plugin
+=====================
+
+Overview
+--------
+
+This plugins provides native device support for Marvell PP2 network
+device, found in Marvel Armada family of SOCs.
+It uses Marvell Usermode SDK
+(`MUSDK <https://github.com/MarvellEmbeddedProcessors/musdk-marvell>`__).
+
+Prerequisites
+-------------
+
+Plugins depends on installed MUSDK and Marvell provided linux in Marvell SDK.
+Following kernel modules from MUSDK must be loaded for plugin to work:
+``musdk_cma.ko``
+``mv_pp_uio.ko``
+
+Musdk 18.09.3 compilation steps
+-------------------------------
+
+::
+
+   ./bootstrap
+   ./configure --prefix=/opt/vpp/external/aarch64/ CFLAGS="-Wno-error=unused-result -g -fPIC" --enable-shared=no
+   sed -i -e  's/marvell,mv-pp-uio/generic-uio/' modules/pp2/mv_pp_uio.c
+   sed -i -e  's/O_CREAT/O_CREAT, S_IRUSR | S_IWUSR/' src/lib/file_utils.c
+   make
+   sudo make install
+
+Usage
+-----
+
+Interface Creation and Deletion
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Interfaces are using new vnet dev APIs, CLIs or startup.conf to create and
+delete interfaces.
+
+Sample startup.conf:
+
+::
+
+   devices {
+     dev platform/f2000000.ethernet {
+       port 1 { name ppio1 }
+   }
+
+Device identifier in this example is 'platform/f2000000.ethernet' where
+'platform' is bus name and 'f2000000.ethernet' is linux platform bus
+identifier for specific PP2.
+
+Platform identifier can be found in sysfs:
+
+::
+
+   $ ls /sys/bus/platform/devices | grep ethernet
+   f2000000.ethernet
+
+
diff --git a/src/plugins/dev_armada/musdk.h b/src/plugins/dev_armada/musdk.h
new file mode 100644
index 0000000..aad2f4a
--- /dev/null
+++ b/src/plugins/dev_armada/musdk.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2023 Cisco Systems, Inc.
+ */
+
+#ifndef _MUSDK_H_
+#define _MUSDK_H_
+
+#define MVCONF_DBG_LEVEL	       0
+#define MVCONF_PP2_BPOOL_COOKIE_SIZE   32
+#define MVCONF_PP2_BPOOL_DMA_ADDR_SIZE 64
+#define MVCONF_DMA_PHYS_ADDR_T_SIZE    64
+#define MVCONF_SYS_DMA_UIO
+#define MVCONF_TYPES_PUBLIC
+#define MVCONF_DMA_PHYS_ADDR_T_PUBLIC
+
+#include <mv_std.h>
+#include <env/mv_sys_dma.h>
+#include <drivers/mv_pp2.h>
+#include <drivers/mv_pp2_bpool.h>
+#include <drivers/mv_pp2_ppio.h>
+
+#endif /* _MUSDK_H_ */
diff --git a/src/plugins/dev_armada/plugin.c b/src/plugins/dev_armada/plugin.c
new file mode 100644
index 0000000..1dc465c
--- /dev/null
+++ b/src/plugins/dev_armada/plugin.c
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2023 Cisco Systems, Inc.
+ */
+
+#include <vlib/vlib.h>
+#include <vnet/plugin/plugin.h>
+#include <vpp/app/version.h>
+
+VLIB_PLUGIN_REGISTER () = {
+  .version = VPP_BUILD_VER,
+  .description = "Marvell Armada Drivers",
+};
diff --git a/src/plugins/dev_armada/pp2/format.c b/src/plugins/dev_armada/pp2/format.c
new file mode 100644
index 0000000..37d482b
--- /dev/null
+++ b/src/plugins/dev_armada/pp2/format.c
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2023 Cisco Systems, Inc.
+ */
+
+#include <vnet/vnet.h>
+#include <vnet/dev/dev.h>
+#include <vnet/dev/counters.h>
+#include <vnet/dev/bus/platform.h>
+#include <dev_armada/musdk.h>
+#include <dev_armada/pp2/pp2.h>
+
+static inline u32
+mrvl_get_u32_bits (void *start, int offset, int first, int last)
+{
+  u32 value = *(u32 *) (((u8 *) start) + offset);
+  if ((last == 0) && (first == 31))
+    return value;
+  value >>= last;
+  value &= (1 << (first - last + 1)) - 1;
+  return value;
+}
+
+u8 *
+format_pp2_ppio_link_info (u8 *s, va_list *args)
+{
+  struct pp2_ppio_link_info *li = va_arg (*args, struct pp2_ppio_link_info *);
+
+  char *port_duplex[] = {
+    [MV_NET_LINK_DUPLEX_HALF] = "half",
+    [MV_NET_LINK_DUPLEX_FULL] = "full",
+  };
+
+  u32 port_speeds[] = {
+    [MV_NET_LINK_SPEED_10] = 10,       [MV_NET_LINK_SPEED_100] = 100,
+    [MV_NET_LINK_SPEED_1000] = 1000,   [MV_NET_LINK_SPEED_2500] = 2500,
+    [MV_NET_LINK_SPEED_10000] = 10000,
+  };
+
+  char *port_phy_modes[] = {
+    [MV_NET_PHY_MODE_NONE] = "NONE",
+    [MV_NET_PHY_MODE_MII] = "MII",
+    [MV_NET_PHY_MODE_GMII] = "GMII",
+    [MV_NET_PHY_MODE_SGMII] = "SGMII",
+    [MV_NET_PHY_MODE_TBI] = "TBI",
+    [MV_NET_PHY_MODE_REVMII] = "REVMII",
+    [MV_NET_PHY_MODE_RMII] = "RMII",
+    [MV_NET_PHY_MODE_RGMII] = "RGMII",
+    [MV_NET_PHY_MODE_RGMII_ID] = "RGMII_ID",
+    [MV_NET_PHY_MODE_RGMII_RXID] = "RGMII_RXID",
+    [MV_NET_PHY_MODE_RGMII_TXID] = "RGMII_TXID",
+    [MV_NET_PHY_MODE_RTBI] = "RTBI",
+    [MV_NET_PHY_MODE_SMII] = "SMII",
+    [MV_NET_PHY_MODE_XGMII] = "XGMII",
+    [MV_NET_PHY_MODE_MOCA] = "MOCA",
+    [MV_NET_PHY_MODE_QSGMII] = "QSGMII",
+    [MV_NET_PHY_MODE_XAUI] = "XAUI",
+    [MV_NET_PHY_MODE_RXAUI] = "RXAUI",
+    [MV_NET_PHY_MODE_KR] = "KR",
+  };
+
+  s =
+    format (s, "duplex %s speed %d up %d phy_mode %s", port_duplex[li->duplex],
+	    port_speeds[li->speed], li->up, port_phy_modes[li->phy_mode]);
+
+  return s;
+}
+
+u8 *
+format_mvpp2_port_status (u8 *s, va_list *args)
+{
+  vnet_dev_format_args_t __clib_unused *a =
+    va_arg (*args, vnet_dev_format_args_t *);
+  vnet_dev_port_t *port = va_arg (*args, vnet_dev_port_t *);
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+  struct pp2_ppio_link_info li = {};
+
+  if (mp->ppio == 0 || pp2_ppio_get_link_info (mp->ppio, &li))
+    return format (s, "link info not available");
+
+  return format (s, "%U", format_pp2_ppio_link_info, &li);
+}
+
+u8 *
+format_mvpp2_dev_info (u8 *s, va_list *args)
+{
+  vnet_dev_format_args_t __clib_unused *a =
+    va_arg (*args, vnet_dev_format_args_t *);
+  vnet_dev_t *dev = va_arg (*args, vnet_dev_t *);
+  mvpp2_device_t *md = vnet_dev_get_data (dev);
+
+  format (s, "pp_id is %u", md->pp_id);
+  return s;
+}
+
+#define foreach_pp2_rx_desc_field                                             \
+  _ (0x00, 6, 0, l3_offset)                                                   \
+  _ (0x00, 12, 8, ip_hdlen)                                                   \
+  _ (0x00, 14, 13, ec)                                                        \
+  _ (0x00, 15, 15, es)                                                        \
+  _ (0x00, 19, 16, pool_id)                                                   \
+  _ (0x00, 21, 21, hwf_sync)                                                  \
+  _ (0x00, 22, 22, l4_chk_ok)                                                 \
+  _ (0x00, 23, 23, ip_frg)                                                    \
+  _ (0x00, 24, 24, ipv4_hdr_err)                                              \
+  _ (0x00, 27, 25, l4_info)                                                   \
+  _ (0x00, 30, 28, l3_info)                                                   \
+  _ (0x00, 31, 31, buf_header)                                                \
+  _ (0x04, 5, 0, lookup_id)                                                   \
+  _ (0x04, 8, 6, cpu_code)                                                    \
+  _ (0x04, 9, 9, pppoe)                                                       \
+  _ (0x04, 11, 10, l3_cast_info)                                              \
+  _ (0x04, 13, 12, l2_cast_info)                                              \
+  _ (0x04, 15, 14, vlan_info)                                                 \
+  _ (0x04, 31, 16, byte_count)                                                \
+  _ (0x08, 11, 0, gem_port_id)                                                \
+  _ (0x08, 13, 12, color)                                                     \
+  _ (0x08, 14, 14, gop_sop_u)                                                 \
+  _ (0x08, 15, 15, key_hash_enable)                                           \
+  _ (0x08, 31, 16, l4chk)                                                     \
+  _ (0x0c, 31, 0, timestamp)                                                  \
+  _ (0x10, 31, 0, buf_phys_ptr_lo)                                            \
+  _ (0x14, 7, 0, buf_phys_ptr_hi)                                             \
+  _ (0x14, 31, 8, key_hash)                                                   \
+  _ (0x18, 31, 0, buf_virt_ptr_lo)                                            \
+  _ (0x1c, 7, 0, buf_virt_ptr_hi)                                             \
+  _ (0x1c, 14, 8, buf_qset_no)                                                \
+  _ (0x1c, 15, 15, buf_type)                                                  \
+  _ (0x1c, 21, 16, mod_dscp)                                                  \
+  _ (0x1c, 24, 22, mod_pri)                                                   \
+  _ (0x1c, 25, 25, mdscp)                                                     \
+  _ (0x1c, 26, 26, mpri)                                                      \
+  _ (0x1c, 27, 27, mgpid)                                                     \
+  _ (0x1c, 31, 29, port_num)
+
+u8 *
+format_mvpp2_rx_desc (u8 *s, va_list *args)
+
+{
+  struct pp2_ppio_desc *d = va_arg (*args, struct pp2_ppio_desc *);
+  u32 indent = format_get_indent (s);
+  u32 r32;
+
+#define _(a, b, c, n)                                                         \
+  r32 = mrvl_get_u32_bits (d, a, b, c);                                       \
+  if (r32 > 9)                                                                \
+    s = format (s, "%s %u (0x%x)", #n, r32, r32);                             \
+  else                                                                        \
+    s = format (s, "%s %u", #n, r32);                                         \
+  if (format_get_indent (s) > 72)                                             \
+    s = format (s, "\n%U", format_white_space, indent + 2);                   \
+  else                                                                        \
+    s = format (s, " ");
+
+  foreach_pp2_rx_desc_field;
+  return s;
+}
+
+u8 *
+format_mvpp2_rx_trace (u8 *s, va_list *args)
+{
+  vlib_main_t *vm = va_arg (*args, vlib_main_t *);
+  vlib_node_t *node = va_arg (*args, vlib_node_t *);
+  mvpp2_rx_trace_t *t = va_arg (*args, mvpp2_rx_trace_t *);
+  vnet_main_t *vnm = vnet_get_main ();
+  u32 hw_if_index = t->rxq->port->intf.hw_if_index;
+  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
+  u32 indent = format_get_indent (s);
+  struct pp2_ppio_desc *d = &t->desc;
+
+  s = format (s, "pp2: %v (%d) next-node %U", hi->name, hw_if_index,
+	      format_vlib_next_node_name, vm, node->index, t->rxq->next_index);
+  s = format (s, "\n%U%U", format_white_space, indent + 2,
+	      format_mvpp2_rx_desc, d);
+
+  return s;
+}
diff --git a/src/plugins/dev_armada/pp2/init.c b/src/plugins/dev_armada/pp2/init.c
new file mode 100644
index 0000000..38ff32d
--- /dev/null
+++ b/src/plugins/dev_armada/pp2/init.c
@@ -0,0 +1,343 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2023 Cisco Systems, Inc.
+ */
+
+#include <vnet/vnet.h>
+#include <vnet/dev/dev.h>
+#include <vnet/dev/counters.h>
+#include <vnet/dev/bus/platform.h>
+#include <vppinfra/ring.h>
+#include <dev_armada/musdk.h>
+#include <dev_armada/pp2/pp2.h>
+#include <vnet/ethernet/ethernet.h>
+#include <vnet/plugin/plugin.h>
+#include <vpp/app/version.h>
+
+#include <linux/if.h>
+#include <sys/ioctl.h>
+
+#define MV_SYS_DMA_MEM_SZ (2 << 20)
+
+VLIB_REGISTER_LOG_CLASS (mvpp2_log, static) = {
+  .class_name = "armada",
+  .subclass_name = "init",
+};
+
+static int num_pp2_in_use = 0;
+static int dma_mem_initialized = 0;
+static int global_pp2_initialized = 0;
+
+#define _(f, n, s, d)                                                         \
+  { .name = #n, .desc = d, .severity = VL_COUNTER_SEVERITY_##s },
+
+vlib_error_desc_t mvpp2_rx_node_counters[] = { foreach_mvpp2_rx_node_counter };
+vlib_error_desc_t mvpp2_tx_node_counters[] = { foreach_mvpp2_tx_node_counter };
+#undef _
+
+vnet_dev_node_t mvpp2_rx_node = {
+  .error_counters = mvpp2_rx_node_counters,
+  .n_error_counters = ARRAY_LEN (mvpp2_rx_node_counters),
+  .format_trace = format_mvpp2_rx_trace,
+};
+
+vnet_dev_node_t mvpp2_tx_node = {
+  .error_counters = mvpp2_tx_node_counters,
+  .n_error_counters = ARRAY_LEN (mvpp2_tx_node_counters),
+};
+
+static u8 *
+mvpp2_probe (vlib_main_t *vm, vnet_dev_bus_index_t bus_index, void *dev_info)
+{
+  vnet_dev_bus_platform_device_info_t *di = dev_info;
+
+  if (clib_dt_node_is_compatible (di->node, "marvell,armada-7k-pp22"))
+    return format (0, "Marvell Armada Packet Processor v2.2");
+  return 0;
+}
+static void
+mvpp2_global_deinit (vlib_main_t *vm, vnet_dev_t *dev)
+{
+  mvpp2_device_t *md = vnet_dev_get_data (dev);
+  log_debug (dev, "");
+  if (--num_pp2_in_use == 0)
+    {
+      if (global_pp2_initialized)
+	{
+	  for (u32 i = 0; i < ARRAY_LEN (md->thread); i++)
+	    if (md->thread[i].bpool)
+	      {
+		pp2_bpool_deinit (md->thread[i].bpool);
+		md->thread[i].bpool = 0;
+	      }
+	  for (u32 i = 0; i < ARRAY_LEN (md->hif); i++)
+	    if (md->hif[i])
+	      {
+		pp2_hif_deinit (md->hif[i]);
+		md->hif[i] = 0;
+	      }
+
+	  pp2_deinit ();
+	  global_pp2_initialized = 0;
+	}
+      if (dma_mem_initialized)
+	{
+	  mv_sys_dma_mem_destroy ();
+	  log_debug (0, "mv_sys_dma_mem_destroy()");
+	  dma_mem_initialized = 0;
+	}
+    }
+}
+
+static void
+mvpp2_deinit (vlib_main_t *vm, vnet_dev_t *dev)
+{
+  log_debug (dev, "");
+  mvpp2_global_deinit (vm, dev);
+}
+
+static vnet_dev_rv_t
+mvpp2_global_init (vlib_main_t *vm, vnet_dev_t *dev)
+{
+  mvpp2_device_t *md = vnet_dev_get_data (dev);
+  vnet_dev_rv_t rv = VNET_DEV_OK;
+  int mrv;
+  u16 free_hifs, free_bpools;
+  u16 n_threads = vlib_get_n_threads ();
+
+  struct pp2_init_params init_params = {
+    .hif_reserved_map = 0xf,
+    .bm_pool_reserved_map = 0x7,
+  };
+
+  if (num_pp2_in_use++)
+    return rv;
+
+  mrv = mv_sys_dma_mem_init (MV_SYS_DMA_MEM_SZ);
+  if (mrv < 0)
+    {
+      log_err (0, "mv_sys_dma_mem_init failed, err %d", mrv);
+      rv = VNET_DEV_ERR_INIT_FAILED;
+      goto done;
+    }
+
+  dma_mem_initialized = 1;
+  log_debug (0, "mv_sys_dma_mem_init(%u) ok", MV_SYS_DMA_MEM_SZ);
+
+  if ((mrv = pp2_init (&init_params)))
+    {
+      log_err (dev, "pp2_init failed, err %d", mrv);
+      rv = VNET_DEV_ERR_INIT_FAILED;
+      goto done;
+    }
+
+  log_debug (dev, "pp2_init() ok");
+
+  free_hifs = pow2_mask (MVPP2_NUM_HIFS) ^ init_params.hif_reserved_map;
+  free_bpools =
+    pow2_mask (MVPP2_NUM_BPOOLS) ^ init_params.bm_pool_reserved_map;
+
+  if (n_threads > count_set_bits (free_hifs))
+    {
+      log_err (dev, "no enough HIFs (needed %u available %u)", n_threads,
+	       count_set_bits (free_hifs));
+      rv = VNET_DEV_ERR_INIT_FAILED;
+      goto done;
+    }
+
+  for (u32 i = 0; i < n_threads; i++)
+    {
+      char match[16];
+      u8 index;
+      struct pp2_hif_params hif_params = {
+	.match = match,
+	.out_size = 2048,
+      };
+      struct pp2_bpool_params bpool_params = {
+	.match = match,
+	.buff_len = vlib_buffer_get_default_data_size (vm),
+      };
+
+      index = get_lowest_set_bit_index (free_hifs);
+      free_hifs ^= 1 << index;
+      snprintf (match, sizeof (match), "hif-%u", index);
+
+      mrv = pp2_hif_init (&hif_params, md->hif + i);
+      if (mrv < 0)
+	{
+	  log_err (dev, "pp2_hif_init failed for hif %u thread %u, err %d",
+		   index, i, mrv);
+	  rv = VNET_DEV_ERR_INIT_FAILED;
+	  goto done;
+	}
+      log_debug (dev, "pp2_hif_init(hif %u, thread %u) ok", index, i);
+
+      index = get_lowest_set_bit_index (free_bpools);
+      free_bpools ^= 1 << index;
+      snprintf (match, sizeof (match), "pool-%u:%u", md->pp_id, index);
+
+      mrv = pp2_bpool_init (&bpool_params, &md->thread[i].bpool);
+      if (mrv < 0)
+	{
+	  log_err (dev, "pp2_bpool_init failed for bpool %u thread %u, err %d",
+		   index, i, mrv);
+	  rv = VNET_DEV_ERR_INIT_FAILED;
+	  goto done;
+	}
+      log_debug (dev, "pp2_bpool_init(bpool %u, thread %u) pool-%u:%u ok",
+		 index, i, md->thread[i].bpool->pp2_id,
+		 md->thread[i].bpool->id);
+      for (u32 j = 0; j < ARRAY_LEN (md->thread[0].bre); j++)
+	md->thread[i].bre[j].bpool = md->thread[i].bpool;
+    }
+
+done:
+  return rv;
+}
+
+static vnet_dev_rv_t
+mvpp2_init (vlib_main_t *vm, vnet_dev_t *dev)
+{
+  mvpp2_device_t *md = vnet_dev_get_data (dev);
+  vnet_dev_rv_t rv = VNET_DEV_OK;
+  vnet_dev_bus_platform_device_data_t *dd = vnet_dev_get_bus_data (dev);
+  clib_dt_node_t *sc;
+  int pp_id = -1;
+
+  if (!clib_dt_node_is_compatible (dd->node, "marvell,armada-7k-pp22"))
+    return VNET_DEV_ERR_NOT_SUPPORTED;
+
+  sc = clib_dt_dereference_node (dd->node, "marvell,system-controller");
+
+  if (sc && vec_len (sc->path) > strlen ("/cpX/"))
+    {
+      if (strncmp ((char *) sc->path, "/cp0/", 4) == 0)
+	pp_id = 0;
+      else if (strncmp ((char *) sc->path, "/cp1/", 4) == 0)
+	pp_id = 1;
+    }
+
+  if (pp_id < 0)
+    return VNET_DEV_ERR_UNKNOWN_DEVICE;
+
+  if ((mvpp2_global_init (vm, dev)) != VNET_DEV_OK)
+    return rv;
+
+  md->pp_id = pp_id;
+
+  vec_foreach_pointer (cn, dd->node->child_nodes)
+    {
+      clib_dt_property_t *p;
+      char netdev_name[IFNAMSIZ];
+      struct ifreq s = {};
+      u8 ppio_id;
+      int fd, srv;
+
+      p = clib_dt_get_node_property_by_name (cn, "port-id");
+
+      if (!clib_dt_proprerty_is_u32 (p))
+	continue;
+
+      ppio_id = clib_dt_proprerty_get_u32 (p);
+      log_debug (dev, "found port with ppio id %u", ppio_id);
+
+      if (pp2_ppio_available (md->pp_id, ppio_id) == 0)
+	continue;
+
+      if (pp2_netdev_get_ifname (md->pp_id, ppio_id, netdev_name) < 0)
+	{
+	  log_warn (dev, "failed to get ifname, skipping port %u ", ppio_id);
+	  continue;
+	}
+
+      srv = -1;
+      if ((fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_IP)) >= 0)
+	{
+	  strcpy (s.ifr_name, netdev_name);
+	  srv = ioctl (fd, SIOCGIFHWADDR, &s);
+	  close (fd);
+	}
+
+      if (srv < 0)
+	{
+	  log_warn (dev, "unable to get hw address, skipping port %u",
+		    ppio_id);
+	  continue;
+	}
+
+      log_debug (dev, "adding ppio %u (netdev name %s, hwaddr %U)", ppio_id,
+		 netdev_name, format_ethernet_address, s.ifr_addr.sa_data);
+
+      mvpp2_port_t mvpp2_port = {
+	.ppio_id = ppio_id,
+      };
+
+      vnet_dev_port_add_args_t port_add_args = {
+        .port = {
+          .attr = {
+            .type = VNET_DEV_PORT_TYPE_ETHERNET,
+            .max_rx_queues = PP2_PPIO_MAX_NUM_INQS,
+            .max_tx_queues = PP2_PPIO_MAX_NUM_OUTQS,
+            .max_supported_rx_frame_size = 9216,
+          },
+          .ops = {
+            .init = mvpp2_port_init,
+            .deinit = mvpp2_port_deinit,
+            .start = mvpp2_port_start,
+            .stop = mvpp2_port_stop,
+            .config_change = mvpp2_port_cfg_change,
+            .config_change_validate = mvpp2_port_cfg_change_validate,
+            .format_status = format_mvpp2_port_status,
+          },
+          .data_size = sizeof (mvpp2_port_t),
+          .initial_data = &mvpp2_port,
+        },
+    .rx_node = &mvpp2_rx_node,
+    .tx_node = &mvpp2_tx_node,
+    .rx_queue = {
+      .config = {
+        .data_size = sizeof (mvpp2_rxq_t),
+        .default_size = 512,
+        .multiplier = 32,
+        .min_size = 32,
+        .max_size = 4096,
+	.size_is_power_of_two = 1,
+      },
+    },
+    .tx_queue = {
+      .config = {
+        .data_size = sizeof (mvpp2_txq_t),
+        .default_size = 512,
+        .multiplier = 32,
+        .min_size = 32,
+        .max_size = 4096,
+	.size_is_power_of_two = 1,
+          },
+      .ops = {
+	  .alloc = mvpp2_txq_alloc,
+	  .free = mvpp2_txq_free,
+      },
+        },
+      };
+
+      vnet_dev_set_hw_addr_eth_mac (&port_add_args.port.attr.hw_addr,
+				    (u8 *) s.ifr_addr.sa_data);
+
+      vnet_dev_port_add (vm, dev, ppio_id, &port_add_args);
+    }
+
+  if (rv != VNET_DEV_OK)
+    mvpp2_deinit (vm, dev);
+  return rv;
+}
+
+VNET_DEV_REGISTER_DRIVER (pp2) = {
+  .name = "mvpp2",
+  .bus = PLATFORM_BUS_NAME,
+  .device_data_sz = sizeof (mvpp2_device_t),
+  .ops = {
+    .init = mvpp2_init,
+    .deinit = mvpp2_deinit,
+    .probe = mvpp2_probe,
+    .format_info = format_mvpp2_dev_info,
+  },
+};
diff --git a/src/plugins/dev_armada/pp2/port.c b/src/plugins/dev_armada/pp2/port.c
new file mode 100644
index 0000000..8e785e5
--- /dev/null
+++ b/src/plugins/dev_armada/pp2/port.c
@@ -0,0 +1,280 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2023 Cisco Systems, Inc.
+ */
+
+#include <vnet/vnet.h>
+#include <vnet/ethernet/ethernet.h>
+#include <vnet/dev/dev.h>
+#include <vnet/dev/counters.h>
+#include <vnet/dev/bus/platform.h>
+#include <vppinfra/ring.h>
+#include <dev_armada/musdk.h>
+#include <dev_armada/pp2/pp2.h>
+
+VLIB_REGISTER_LOG_CLASS (mvpp2_log, static) = {
+  .class_name = "armada",
+  .subclass_name = "pp2-port",
+};
+
+vnet_dev_rv_t
+mvpp2_port_init (vlib_main_t *vm, vnet_dev_port_t *port)
+{
+  vnet_dev_t *dev = port->dev;
+  mvpp2_device_t *md = vnet_dev_get_data (dev);
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+  vnet_dev_rv_t rv = VNET_DEV_OK;
+  struct pp2_ppio_link_info li;
+  char match[16];
+  int mrv;
+
+  log_debug (port->dev, "");
+
+  snprintf (match, sizeof (match), "ppio-%d:%d", md->pp_id, port->port_id);
+
+  struct pp2_ppio_params ppio_params = {
+    .match = match,
+    .type = PP2_PPIO_T_NIC,
+    .eth_start_hdr = mp->is_dsa ? PP2_PPIO_HDR_ETH_DSA : PP2_PPIO_HDR_ETH,
+    .inqs_params = {
+      .num_tcs = 1,
+      .tcs_params[0] = {
+        .pkt_offset = 0,
+	.num_in_qs = 1,
+	.inqs_params = &(struct pp2_ppio_inq_params) { .size = 512 },
+	.pools[0][0] = md->thread[0].bpool,
+      },
+    },
+  };
+
+  foreach_vnet_dev_port_rx_queue (q, port)
+    {
+      struct pp2_ppio_outqs_params *oqs = &ppio_params.outqs_params;
+      oqs->outqs_params[0].weight = 1;
+      oqs->outqs_params[0].size = q->size;
+      oqs->num_outqs++;
+    }
+
+  mrv = pp2_ppio_init (&ppio_params, &mp->ppio);
+  if (mrv)
+    {
+      rv = VNET_DEV_ERR_INIT_FAILED;
+      log_err (dev, "port %u ppio '%s' init failed, rv %d", port->port_id,
+	       match, mrv);
+      goto done;
+    }
+  log_debug (dev, "port %u ppio '%s' init ok", port->port_id, match);
+
+  mrv = pp2_ppio_get_link_info (mp->ppio, &li);
+  if (mrv)
+    {
+      rv = VNET_DEV_ERR_INIT_FAILED;
+      log_err (dev, "failed to get link info for port %u, rv %d",
+	       port->port_id, mrv);
+      goto done;
+    }
+
+  log_debug (dev, "port %u %U", port->port_id, format_pp2_ppio_link_info, &li);
+
+done:
+  if (rv != VNET_DEV_OK)
+    mvpp2_port_stop (vm, port);
+  return rv;
+}
+
+void
+mvpp2_port_deinit (vlib_main_t *vm, vnet_dev_port_t *port)
+{
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+
+  log_debug (port->dev, "");
+
+  if (mp->ppio)
+    {
+      pp2_ppio_deinit (mp->ppio);
+      mp->ppio = 0;
+    }
+}
+
+void
+mvpp2_port_poll (vlib_main_t *vm, vnet_dev_port_t *port)
+{
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+  vnet_dev_t *dev = port->dev;
+  vnet_dev_port_state_changes_t changes = {};
+  struct pp2_ppio_link_info li;
+  int mrv;
+
+  mrv = pp2_ppio_get_link_info (mp->ppio, &li);
+
+  if (mrv)
+    {
+      log_debug (dev, "pp2_ppio_get_link_info: failed, rv %d", mrv);
+      return;
+    }
+
+  if (mp->last_link_info.up != li.up)
+    {
+      changes.change.link_state = 1;
+      changes.link_state = li.up != 0;
+      log_debug (dev, "link state changed to %u", changes.link_state);
+    }
+
+  if (mp->last_link_info.duplex != li.duplex)
+    {
+      changes.change.link_duplex = 1;
+      changes.full_duplex = li.duplex != 0;
+      log_debug (dev, "link full duplex changed to %u", changes.full_duplex);
+    }
+
+  if (mp->last_link_info.speed != li.speed)
+    {
+      u32 speeds[] = {
+	[MV_NET_LINK_SPEED_AN] = 0,
+	[MV_NET_LINK_SPEED_10] = 10000,
+	[MV_NET_LINK_SPEED_100] = 100000,
+	[MV_NET_LINK_SPEED_1000] = 1000000,
+	[MV_NET_LINK_SPEED_2500] = 2500000,
+	[MV_NET_LINK_SPEED_10000] = 10000000,
+      };
+
+      if (li.speed < ARRAY_LEN (speeds))
+	{
+	  changes.change.link_speed = 1;
+	  changes.link_speed = speeds[li.speed];
+	  log_debug (dev, "link speed changed to %u", changes.link_speed);
+	}
+    }
+
+  if (changes.change.any == 0)
+    return;
+
+  mp->last_link_info = li;
+
+  vnet_dev_port_state_change (vm, port, changes);
+}
+
+vnet_dev_rv_t
+mvpp2_port_start (vlib_main_t *vm, vnet_dev_port_t *port)
+{
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+  int mrv;
+
+  log_debug (port->dev, "");
+
+  mrv = pp2_ppio_enable (mp->ppio);
+  if (mrv)
+    {
+      log_err (port->dev, "pp2_ppio_enable() failed, rv %d", mrv);
+      return VNET_DEV_ERR_NOT_READY;
+    }
+
+  mp->is_enabled = 1;
+
+  vnet_dev_poll_port_add (vm, port, 0.5, mvpp2_port_poll);
+
+  return VNET_DEV_OK;
+}
+
+void
+mvpp2_port_stop (vlib_main_t *vm, vnet_dev_port_t *port)
+{
+  int rv;
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+
+  log_debug (port->dev, "");
+
+  if (mp->is_enabled)
+    {
+      vnet_dev_poll_port_remove (vm, port, mvpp2_port_poll);
+
+      rv = pp2_ppio_disable (mp->ppio);
+      if (rv)
+	log_err (port->dev, "pp2_ppio_disable() failed, rv %d", rv);
+
+      vnet_dev_port_state_change (vm, port,
+				  (vnet_dev_port_state_changes_t){
+				    .change.link_state = 1,
+				    .change.link_speed = 1,
+				    .link_speed = 0,
+				    .link_state = 0,
+				  });
+      mp->is_enabled = 0;
+    }
+}
+
+vnet_dev_rv_t
+mvpp2_port_cfg_change_validate (vlib_main_t *vm, vnet_dev_port_t *port,
+				vnet_dev_port_cfg_change_req_t *req)
+{
+  vnet_dev_rv_t rv = VNET_DEV_OK;
+
+  switch (req->type)
+    {
+    case VNET_DEV_PORT_CFG_PROMISC_MODE:
+    case VNET_DEV_PORT_CFG_ADD_SECONDARY_HW_ADDR:
+    case VNET_DEV_PORT_CFG_REMOVE_SECONDARY_HW_ADDR:
+      break;
+
+    default:
+      rv = VNET_DEV_ERR_NOT_SUPPORTED;
+    };
+
+  return rv;
+}
+
+vnet_dev_rv_t
+mvpp2_port_cfg_change (vlib_main_t *vm, vnet_dev_port_t *port,
+		       vnet_dev_port_cfg_change_req_t *req)
+{
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+  vnet_dev_rv_t rv = VNET_DEV_OK;
+  eth_addr_t addr;
+  int mrv;
+
+  switch (req->type)
+    {
+
+    case VNET_DEV_PORT_CFG_PROMISC_MODE:
+      mrv = pp2_ppio_set_promisc (mp->ppio, req->promisc);
+      if (mrv)
+	{
+	  log_err (port->dev, "pp2_ppio_set_promisc: failed, rv %d", mrv);
+	  rv = VNET_DEV_ERR_INTERNAL;
+	}
+      else
+	log_debug (port->dev, "pp2_ppio_set_promisc: promisc %u",
+		   req->promisc);
+      break;
+
+    case VNET_DEV_PORT_CFG_ADD_SECONDARY_HW_ADDR:
+      clib_memcpy (&addr, req->addr.eth_mac, sizeof (addr));
+      mrv = pp2_ppio_add_mac_addr (mp->ppio, addr);
+      if (mrv)
+	{
+	  log_err (port->dev, "pp2_ppio_add_mac_addr: failed, rv %d", mrv);
+	  rv = VNET_DEV_ERR_INTERNAL;
+	}
+      else
+	log_debug (port->dev, "pp2_ppio_add_mac_addr: %U added",
+		   format_ethernet_address, &addr);
+      break;
+
+    case VNET_DEV_PORT_CFG_REMOVE_SECONDARY_HW_ADDR:
+      clib_memcpy (&addr, req->addr.eth_mac, sizeof (addr));
+      mrv = pp2_ppio_remove_mac_addr (mp->ppio, addr);
+      if (mrv)
+	{
+	  log_err (port->dev, "pp2_ppio_remove_mac_addr: failed, rv %d", mrv);
+	  rv = VNET_DEV_ERR_INTERNAL;
+	}
+      else
+	log_debug (port->dev, "pp2_ppio_remove_mac_addr: %U added",
+		   format_ethernet_address, &addr);
+      break;
+
+    default:
+      return VNET_DEV_ERR_NOT_SUPPORTED;
+    };
+
+  return rv;
+}
diff --git a/src/plugins/dev_armada/pp2/pp2.h b/src/plugins/dev_armada/pp2/pp2.h
new file mode 100644
index 0000000..6b12dc7
--- /dev/null
+++ b/src/plugins/dev_armada/pp2/pp2.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2023 Cisco Systems, Inc.
+ */
+
+#ifndef _PP2_H_
+#define _PP2_H_
+
+#include <vppinfra/clib.h>
+#include <vppinfra/error_bootstrap.h>
+#include <vppinfra/format.h>
+#include <vnet/vnet.h>
+#include <vnet/dev/dev.h>
+
+#define MVCONF_DBG_LEVEL	       0
+#define MVCONF_PP2_BPOOL_COOKIE_SIZE   32
+#define MVCONF_PP2_BPOOL_DMA_ADDR_SIZE 64
+#define MVCONF_DMA_PHYS_ADDR_T_SIZE    64
+#define MVCONF_SYS_DMA_UIO
+#define MVCONF_TYPES_PUBLIC
+#define MVCONF_DMA_PHYS_ADDR_T_PUBLIC
+
+#include "mv_std.h"
+#include "env/mv_sys_dma.h"
+#include "drivers/mv_pp2.h"
+#include <drivers/mv_pp2_bpool.h>
+#include <drivers/mv_pp2_ppio.h>
+
+#define MVPP2_NUM_HIFS	       9
+#define MVPP2_NUM_BPOOLS       16
+#define MVPP2_MAX_THREADS      4
+#define MRVL_PP2_BUFF_BATCH_SZ 32
+
+typedef struct
+{
+  u8 pp_id;
+  struct pp2_hif *hif[MVPP2_NUM_HIFS];
+  struct
+  {
+    struct pp2_bpool *bpool;
+    struct buff_release_entry bre[MRVL_PP2_BUFF_BATCH_SZ];
+  } thread[MVPP2_NUM_BPOOLS];
+
+} mvpp2_device_t;
+
+typedef struct
+{
+  u8 is_enabled : 1;
+  u8 is_dsa : 1;
+  struct pp2_ppio *ppio;
+  u8 ppio_id;
+  struct pp2_ppio_link_info last_link_info;
+} mvpp2_port_t;
+
+typedef struct
+{
+  u16 next;
+  u16 n_enq;
+  u32 *buffers;
+} mvpp2_txq_t;
+
+typedef struct
+{
+} mvpp2_rxq_t;
+
+typedef struct
+{
+  struct pp2_ppio_desc desc;
+  vnet_dev_rx_queue_t *rxq;
+} mvpp2_rx_trace_t;
+
+/* format.c */
+format_function_t format_pp2_ppio_link_info;
+format_function_t format_mvpp2_port_status;
+format_function_t format_mvpp2_dev_info;
+format_function_t format_mvpp2_rx_trace;
+format_function_t format_mvpp2_rx_desc;
+
+/* port.c */
+vnet_dev_port_op_t mvpp2_port_init;
+vnet_dev_port_op_no_rv_t mvpp2_port_deinit;
+vnet_dev_port_op_t mvpp2_port_start;
+vnet_dev_port_op_no_rv_t mvpp2_port_stop;
+vnet_dev_rv_t mvpp2_port_cfg_change (vlib_main_t *, vnet_dev_port_t *,
+				     vnet_dev_port_cfg_change_req_t *);
+vnet_dev_rv_t
+mvpp2_port_cfg_change_validate (vlib_main_t *, vnet_dev_port_t *,
+				vnet_dev_port_cfg_change_req_t *);
+
+/* queue.c */
+vnet_dev_tx_queue_op_t mvpp2_txq_alloc;
+vnet_dev_tx_queue_op_no_rv_t mvpp2_txq_free;
+
+/* inline funcs */
+
+#define log_debug(dev, f, ...)                                                \
+  vlib_log (VLIB_LOG_LEVEL_DEBUG, mvpp2_log.class, "%U" f,                    \
+	    format_vnet_dev_log, (dev),                                       \
+	    clib_string_skip_prefix (__func__, "mvpp2_"), ##__VA_ARGS__)
+#define log_info(dev, f, ...)                                                 \
+  vlib_log (VLIB_LOG_LEVEL_INFO, mvpp2_log.class, "%U" f,                     \
+	    format_vnet_dev_log, (dev), 0, ##__VA_ARGS__)
+#define log_notice(dev, f, ...)                                               \
+  vlib_log (VLIB_LOG_LEVEL_NOTICE, mvpp2_log.class, "%U" f,                   \
+	    format_vnet_dev_log, (dev), 0, ##__VA_ARGS__)
+#define log_warn(dev, f, ...)                                                 \
+  vlib_log (VLIB_LOG_LEVEL_WARNING, mvpp2_log.class, "%U" f,                  \
+	    format_vnet_dev_log, (dev), 0, ##__VA_ARGS__)
+#define log_err(dev, f, ...)                                                  \
+  vlib_log (VLIB_LOG_LEVEL_ERR, mvpp2_log.class, "%U" f, format_vnet_dev_log, \
+	    (dev), 0, ##__VA_ARGS__)
+
+#define foreach_mvpp2_tx_node_counter                                         \
+  _ (NO_FREE_SLOTS, no_free_slots, ERROR, "no free tx slots")                 \
+  _ (PPIO_SEND, ppio_semd, ERROR, "pp2_ppio_send errors")                     \
+  _ (PPIO_GET_NUM_OUTQ_DONE, ppio_get_num_outq_done, ERROR,                   \
+     "pp2_ppio_get_num_outq_done errors")
+
+typedef enum
+{
+#define _(f, n, s, d) MVPP2_TX_NODE_CTR_##f,
+  foreach_mvpp2_tx_node_counter
+#undef _
+} mvpp2_tx_node_counter_t;
+
+#define foreach_mvpp2_rx_node_counter                                         \
+  _ (PPIO_RECV, ppio_recv, ERROR, "pp2_ppio_recv error")                      \
+  _ (BPOOL_GET_NUM_BUFFS, bpool_get_num_bufs, ERROR,                          \
+     "pp2_bpool_get_num_buffs error")                                         \
+  _ (BPOOL_PUT_BUFFS, bpool_put_buffs, ERROR, "pp2_bpool_put_buffs error")    \
+  _ (BUFFER_ALLOC, buffer_alloc, ERROR, "buffer alloc error")                 \
+  _ (MAC_CE, mac_ce, ERROR, "MAC error (CRC error)")                          \
+  _ (MAC_OR, mac_or, ERROR, "overrun error")                                  \
+  _ (MAC_RSVD, mac_rsvd, ERROR, "unknown MAC error")                          \
+  _ (MAC_RE, mac_re, ERROR, "resource error")                                 \
+  _ (IP_HDR, ip_hdr, ERROR, "ip4 header error")
+
+typedef enum
+{
+#define _(f, n, s, d) MVPP2_RX_NODE_CTR_##f,
+  foreach_mvpp2_rx_node_counter
+#undef _
+} mvpp2_rx_node_counter_t;
+
+#endif /* _PP2_H_ */
diff --git a/src/plugins/dev_armada/pp2/queue.c b/src/plugins/dev_armada/pp2/queue.c
new file mode 100644
index 0000000..0501541
--- /dev/null
+++ b/src/plugins/dev_armada/pp2/queue.c
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2023 Cisco Systems, Inc.
+ */
+
+#include <vnet/vnet.h>
+#include <vnet/ethernet/ethernet.h>
+#include <vnet/dev/dev.h>
+#include <vnet/dev/counters.h>
+#include <vnet/dev/bus/platform.h>
+#include <vppinfra/ring.h>
+#include <dev_armada/musdk.h>
+#include <dev_armada/pp2/pp2.h>
+
+VLIB_REGISTER_LOG_CLASS (mvpp2_log, static) = {
+  .class_name = "armada",
+  .subclass_name = "pp2-queue",
+};
+
+vnet_dev_rv_t
+mvpp2_txq_alloc (vlib_main_t *vm, vnet_dev_tx_queue_t *txq)
+{
+  vnet_dev_rv_t rv = VNET_DEV_OK;
+  mvpp2_txq_t *mtq = vnet_dev_get_tx_queue_data (txq);
+  log_debug (txq->port->dev, "");
+
+  ASSERT (mtq->buffers == 0);
+  if (mtq->buffers == 0)
+    {
+      u32 sz = sizeof (u32) * txq->size;
+      mtq->buffers = clib_mem_alloc_aligned (sz, CLIB_CACHE_LINE_BYTES);
+      clib_memset (mtq->buffers, 0, sz);
+    }
+
+  return rv;
+}
+
+void
+mvpp2_txq_free (vlib_main_t *vm, vnet_dev_tx_queue_t *txq)
+{
+  mvpp2_txq_t *mtq = vnet_dev_get_tx_queue_data (txq);
+
+  log_debug (txq->port->dev, "");
+  if (mtq->buffers)
+    {
+      clib_mem_free (mtq->buffers);
+      mtq->buffers = 0;
+    }
+}
diff --git a/src/plugins/dev_armada/pp2/rx.c b/src/plugins/dev_armada/pp2/rx.c
new file mode 100644
index 0000000..81101ef
--- /dev/null
+++ b/src/plugins/dev_armada/pp2/rx.c
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2024 Cisco Systems, Inc.
+ */
+
+#include <vlib/vlib.h>
+#include <vnet/dev/dev.h>
+#include <vnet/ethernet/ethernet.h>
+
+#include <dev_armada/pp2/pp2.h>
+
+static_always_inline void
+mvpp2_rx_trace (vlib_main_t *vm, vlib_node_runtime_t *node,
+		vnet_dev_rx_queue_t *rxq, vlib_buffer_t *b0, uword *n_trace,
+		struct pp2_ppio_desc *d)
+{
+  if (PREDICT_TRUE (vlib_trace_buffer (vm, node, rxq->next_index, b0,
+				       /* follow_chain */ 0)))
+    {
+      mvpp2_rx_trace_t *tr;
+      vlib_set_trace_count (vm, node, --(*n_trace));
+      tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
+      tr->desc = *d;
+      tr->rxq = rxq;
+    }
+}
+
+static_always_inline uword
+mrvl_pp2_rx_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
+		    vlib_frame_t *frame, vnet_dev_rx_queue_t *rxq)
+{
+  vnet_main_t *vnm = vnet_get_main ();
+  vnet_dev_port_t *port = rxq->port;
+  vnet_dev_t *dev = port->dev;
+  mvpp2_device_t *md = vnet_dev_get_data (dev);
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+  vlib_buffer_template_t bt = rxq->buffer_template;
+  u32 thread_index = vm->thread_index;
+  uword n_trace = vlib_get_trace_count (vm, node);
+  u32 next_index = rxq->next_index;
+  u32 n_rx_packets = 0, n_rx_bytes = 0;
+  struct pp2_hif *hif = md->hif[thread_index];
+  struct pp2_ppio_desc descs[VLIB_FRAME_SIZE], *d;
+  struct pp2_bpool *bpool = md->thread[thread_index].bpool;
+  struct buff_release_entry *bre = md->thread[thread_index].bre;
+  u16 n_desc = VLIB_FRAME_SIZE;
+  u32 buffers[VLIB_FRAME_SIZE];
+  u32 n_bufs, *bi, i;
+  vlib_buffer_t *b0, *b1;
+
+  if (PREDICT_FALSE (
+	pp2_ppio_recv (mp->ppio, 0, rxq->queue_id, descs, &n_desc)))
+    {
+      vlib_error_count (vm, node->node_index, MVPP2_RX_NODE_CTR_PPIO_RECV, 1);
+      n_desc = 0;
+    }
+
+  n_rx_packets = n_desc;
+
+  for (i = 0; i < n_desc; i++)
+    buffers[i] = pp2_ppio_inq_desc_get_cookie (descs + i);
+
+  bt.current_data = 2;
+
+  for (d = descs, bi = buffers; n_desc >= 4; d += 2, bi += 2, n_desc -= 2)
+    {
+      /* prefetch */
+      b0 = vlib_get_buffer (vm, bi[0]);
+      b1 = vlib_get_buffer (vm, bi[1]);
+      b0->template = bt;
+      b1->template = bt;
+
+      n_rx_bytes += b0->current_length = pp2_ppio_inq_desc_get_pkt_len (d);
+      n_rx_bytes += b1->current_length = pp2_ppio_inq_desc_get_pkt_len (d + 1);
+
+      if (PREDICT_FALSE (n_trace > 0))
+	{
+	  mvpp2_rx_trace (vm, node, rxq, b0, &n_trace, d);
+	  if (n_trace > 0)
+	    mvpp2_rx_trace (vm, node, rxq, b1, &n_trace, d + 1);
+	}
+    }
+
+  for (; n_desc; d++, bi++, n_desc--)
+    {
+      b0 = vlib_get_buffer (vm, bi[0]);
+      b0->template = bt;
+
+      n_rx_bytes += b0->current_length = pp2_ppio_inq_desc_get_pkt_len (d);
+
+      if (PREDICT_FALSE (n_trace > 0))
+	mvpp2_rx_trace (vm, node, rxq, b0, &n_trace, d);
+    }
+
+  vlib_buffer_enqueue_to_single_next (vm, node, buffers, next_index,
+				      n_rx_packets);
+
+  vlib_increment_combined_counter (
+    vnm->interface_main.combined_sw_if_counters + VNET_INTERFACE_COUNTER_RX,
+    thread_index, port->intf.sw_if_index, n_rx_packets, n_rx_bytes);
+
+  if (PREDICT_FALSE (pp2_bpool_get_num_buffs (bpool, &n_bufs)))
+    {
+      vlib_error_count (vm, node->node_index,
+			MVPP2_RX_NODE_CTR_BPOOL_GET_NUM_BUFFS, 1);
+      goto done;
+    }
+
+  n_bufs = rxq->size - n_bufs;
+  while (n_bufs >= MRVL_PP2_BUFF_BATCH_SZ)
+    {
+      u16 n_alloc, i;
+      struct buff_release_entry *e = bre;
+
+      n_alloc = vlib_buffer_alloc (vm, buffers, MRVL_PP2_BUFF_BATCH_SZ);
+      i = n_alloc;
+
+      if (PREDICT_FALSE (n_alloc == 0))
+	{
+	  vlib_error_count (vm, node->node_index,
+			    MVPP2_RX_NODE_CTR_BUFFER_ALLOC, 1);
+	  goto done;
+	}
+
+      for (bi = buffers; i--; e++, bi++)
+	{
+
+	  vlib_buffer_t *b = vlib_get_buffer (vm, bi[0]);
+	  e->buff.addr = vlib_buffer_get_pa (vm, b) - 64;
+	  e->buff.cookie = bi[0];
+	}
+
+      i = n_alloc;
+      if (PREDICT_FALSE (pp2_bpool_put_buffs (hif, bre, &i)))
+	{
+	  vlib_error_count (vm, node->node_index,
+			    MVPP2_RX_NODE_CTR_BPOOL_PUT_BUFFS, 1);
+	  vlib_buffer_free (vm, buffers, n_alloc);
+	  goto done;
+	}
+
+      if (PREDICT_FALSE (i != n_alloc))
+	vlib_buffer_free (vm, buffers + i, n_alloc - i);
+
+      n_bufs -= i;
+    }
+
+done:
+  return n_rx_packets;
+}
+
+VNET_DEV_NODE_FN (mvpp2_rx_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+  u32 n_rx = 0;
+  foreach_vnet_dev_rx_queue_runtime (rxq, node)
+    n_rx += mrvl_pp2_rx_inline (vm, node, frame, rxq);
+  return n_rx;
+}
diff --git a/src/plugins/dev_armada/pp2/tx.c b/src/plugins/dev_armada/pp2/tx.c
new file mode 100644
index 0000000..1e6675c
--- /dev/null
+++ b/src/plugins/dev_armada/pp2/tx.c
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2024 Cisco Systems, Inc.
+ */
+
+#include <vlib/vlib.h>
+#include <vnet/dev/dev.h>
+#include <vnet/ethernet/ethernet.h>
+
+#include <dev_armada/pp2/pp2.h>
+
+VNET_DEV_NODE_FN (mvpp2_tx_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+  vnet_dev_tx_node_runtime_t *rt = vnet_dev_get_tx_node_runtime (node);
+  vnet_dev_tx_queue_t *txq = rt->tx_queue;
+  vnet_dev_port_t *port = txq->port;
+  vnet_dev_t *dev = port->dev;
+  mvpp2_txq_t *mtq = vnet_dev_get_tx_queue_data (txq);
+  mvpp2_port_t *mp = vnet_dev_get_port_data (port);
+  mvpp2_device_t *md = vnet_dev_get_data (dev);
+  u8 qid = txq->queue_id;
+  u32 *buffers = vlib_frame_vector_args (frame);
+  u32 n_vectors = frame->n_vectors, n_left;
+  u16 n_sent;
+  struct pp2_ppio *ppio = mp->ppio;
+  struct pp2_hif *hif = md->hif[vm->thread_index];
+  struct pp2_ppio_desc descs[VLIB_FRAME_SIZE], *d = descs;
+  u16 sz = txq->size;
+  u16 mask = sz - 1;
+
+  if (mtq->n_enq)
+    {
+      u16 n_done = 0;
+      if (PREDICT_FALSE (pp2_ppio_get_num_outq_done (ppio, hif, qid, &n_done)))
+	vlib_error_count (vm, node->node_index,
+			  MVPP2_TX_NODE_CTR_PPIO_GET_NUM_OUTQ_DONE, 1);
+
+      if (n_done)
+	{
+	  vlib_buffer_free_from_ring (
+	    vm, mtq->buffers, (mtq->next - mtq->n_enq) & mask, sz, n_done);
+	  mtq->n_enq -= n_done;
+	}
+    }
+
+  n_sent = clib_min (n_vectors, sz - mtq->n_enq);
+
+  for (d = descs, n_left = n_sent; n_left; d++, buffers++, n_left--)
+    {
+      vlib_buffer_t *b0 = vlib_get_buffer (vm, buffers[0]);
+      u64 paddr = vlib_buffer_get_pa (vm, b0);
+
+      pp2_ppio_outq_desc_reset (d);
+      pp2_ppio_outq_desc_set_phys_addr (d, paddr + b0->current_data);
+      pp2_ppio_outq_desc_set_pkt_offset (d, 0);
+      pp2_ppio_outq_desc_set_pkt_len (d, b0->current_length);
+    }
+
+  buffers = vlib_frame_vector_args (frame);
+
+  if (pp2_ppio_send (ppio, hif, qid, descs, &n_sent))
+    {
+      n_sent = 0;
+      vlib_error_count (vm, node->node_index, MVPP2_TX_NODE_CTR_PPIO_SEND, 1);
+    }
+  else if (n_sent)
+    {
+      vlib_buffer_copy_indices_to_ring (mtq->buffers, buffers,
+					mtq->next & mask, sz, n_sent);
+      mtq->next += n_sent;
+      mtq->n_enq += n_sent;
+    }
+
+  /* free unsent buffers */
+  if (PREDICT_FALSE (n_sent != n_vectors))
+    {
+      vlib_buffer_free (vm, buffers + n_sent, n_vectors - n_sent);
+      vlib_error_count (vm, node->node_index, MVPP2_TX_NODE_CTR_NO_FREE_SLOTS,
+			n_vectors - n_sent);
+    }
+
+  return n_sent;
+}
diff --git a/src/plugins/marvell/CMakeLists.txt b/src/plugins/marvell/CMakeLists.txt
deleted file mode 100644
index b48ac72..0000000
--- a/src/plugins/marvell/CMakeLists.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (c) 2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)")
-  return()
-endif()
-
-find_path(MUSDK_INCLUDE_DIR NAMES mv_std.h)
-find_library(MUSDK_LIB NAMES libmusdk.a)
-
-if(MUSDK_INCLUDE_DIR AND MUSDK_LIB)
-  get_filename_component(MUSDK_LIB_DIR ${MUSDK_LIB} DIRECTORY)
-  set(MUSDK_LINK_FLAGS "-Wl,--whole-archive,${MUSDK_LIB_DIR}/libmusdk.a,--no-whole-archive")
-  add_vpp_plugin(marvell
-    SOURCES
-    plugin.c
-    pp2/cli.c
-    pp2/format.c
-    pp2/input.c
-    pp2/output.c
-    pp2/pp2.c
-    pp2/pp2_api.c
-
-    API_FILES
-    pp2/pp2.api
-
-    API_TEST_SOURCES
-    pp2/pp2_test.c
-
-    LINK_FLAGS
-    ${MUSDK_LINK_FLAGS}
-  )
-  include_directories(${MUSDK_INCLUDE_DIR})
-  message(STATUS "Found Marvell MUSDK in ${MUSDK_INCLUDE_DIR}")
-else()
-  message(WARNING "Marvell MUSDK not found - marvell_plugin disabled")
-endif()
diff --git a/src/plugins/marvell/README.rst b/src/plugins/marvell/README.rst
deleted file mode 100644
index 19cf1c4..0000000
--- a/src/plugins/marvell/README.rst
+++ /dev/null
@@ -1,85 +0,0 @@
-Marvell device plugin
-=====================
-
-Overview
---------
-
-This plugins provides native device support for Marvell PP2 network
-device, by use of Marvell Usermode SDK
-(`MUSDK <https://github.com/MarvellEmbeddedProcessors/musdk-marvell>`__).
-Code is developed and tested on
-`MACCHIATObin <http://macchiatobin.net>`__ board.
-
-Prerequisites
--------------
-
-Plugins depends on installed MUSDK and Marvell provided linux
-`kernel <https://github.com/MarvellEmbeddedProcessors/linux-marvell>`__
-with MUSDK provided kernel patches (see ``patches/linux`` in musdk repo
-and relevant documentation. Kernel version used: **4.14.22
-armada-18.09.3** MUSDK version used: **armada-18.09.3** Following kernel
-modules from MUSDK must be loaded for plugin to work: \*
-``musdk_cma.ko`` \* ``mv_pp_uio.ko``
-
-Musdk 18.09.3 compilation steps
--------------------------------
-
-::
-
-   ./bootstrap
-   ./configure --prefix=/opt/vpp/external/aarch64/ CFLAGS="-Wno-error=unused-result -g -fPIC" --enable-shared=no
-   sed -i -e  's/marvell,mv-pp-uio/generic-uio/' modules/pp2/mv_pp_uio.c
-   sed -i -e  's/O_CREAT/O_CREAT, S_IRUSR | S_IWUSR/' src/lib/file_utils.c
-   make
-   sudo make install
-
-Usage
------
-
-Interface Creation
-~~~~~~~~~~~~~~~~~~
-
-Interfaces are dynamically created with following CLI:
-
-::
-
-   create interface marvell pp2 name eth0
-   set interface state mv-ppio-0/0 up
-
-Where ``eth0`` is linux interface name and ``mv-ppio-X/Y`` is VPP
-interface name where X is PP2 device ID and Y is PPIO ID Interface needs
-to be assigned to MUSDK in FDT configuration and linux interface state
-must be up.
-
-Interface Deletion
-~~~~~~~~~~~~~~~~~~
-
-Interface can be deleted with following CLI:
-
-::
-
-   delete interface marvell pp2 <interface name>
-
-Interface Statistics
-~~~~~~~~~~~~~~~~~~~~
-
-Interface statistics can be displayed with
-``sh hardware-interface mv-ppio0/0`` command.
-
-Interaction with DPDK plugin
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This plugin doesn’t have any dependency on DPDK or DPDK plugin but it
-can work with DPDK plugin enabled or disabled. It is observed that
-performance is better around 30% when DPDK plugin is disabled, as DPDK
-plugin registers own buffer manager, which needs to deal with additional
-metadata in each packet.
-
-DPKD plugin can be disabled by adding following config to the
-startup.conf.
-
-::
-
-   plugins {
-     dpdk_plugin.so { disable }
-   }
diff --git a/src/plugins/marvell/plugin.c b/src/plugins/marvell/plugin.c
deleted file mode 100644
index ed90776..0000000
--- a/src/plugins/marvell/plugin.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *------------------------------------------------------------------
- */
-
-#include <vlib/vlib.h>
-#include <vnet/plugin/plugin.h>
-#include <vpp/app/version.h>
-
-VLIB_PLUGIN_REGISTER () = {
-  .version = VPP_BUILD_VER,
-  .description = "Marvell PP2 Device Driver",
-};
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/marvell/pp2/cli.c b/src/plugins/marvell/pp2/cli.c
deleted file mode 100644
index 5072a3c..0000000
--- a/src/plugins/marvell/pp2/cli.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *------------------------------------------------------------------
- */
-#include <stdint.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <inttypes.h>
-
-#include <vlib/vlib.h>
-#include <vlib/unix/unix.h>
-#include <vnet/ethernet/ethernet.h>
-
-#include <marvell/pp2/pp2.h>
-
-static clib_error_t *
-mrvl_pp2_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
-			    vlib_cli_command_t * cmd)
-{
-  unformat_input_t _line_input, *line_input = &_line_input;
-  mrvl_pp2_create_if_args_t args = { 0 };
-  unsigned int val;
-
-  /* Get a line of input. */
-  if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
-
-  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (line_input, "name %s", &args.name))
-	;
-      else if (unformat (line_input, "rx-queue-size %u", &val))
-	args.rx_q_sz = val;
-      else if (unformat (line_input, "tx-queue-size %u", &val))
-	args.tx_q_sz = val;
-      else
-	return clib_error_return (0, "unknown input `%U'",
-				  format_unformat_error, input);
-    }
-  unformat_free (line_input);
-
-
-  mrvl_pp2_create_if (&args);
-
-  vec_free (args.name);
-
-  return args.error;
-}
-
-VLIB_CLI_COMMAND (mrvl_pp2_create_command, static) = {
-  .path = "create interface marvell pp2",
-  .short_help = "create interface marvell pp2 [name <ifname>] [rx-queue-size slots] [tx-queue-size slots]",
-  .function = mrvl_pp2_create_command_fn,
-};
-
-static clib_error_t *
-mrvl_pp2_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
-			    vlib_cli_command_t * cmd)
-{
-  unformat_input_t _line_input, *line_input = &_line_input;
-  u32 sw_if_index = ~0;
-  vnet_hw_interface_t *hw;
-  mrvl_pp2_main_t *mm = &mrvl_pp2_main;
-  mrvl_pp2_if_t *dif;
-  vnet_main_t *vnm = vnet_get_main ();
-
-  /* Get a line of input. */
-  if (!unformat_user (input, unformat_line_input, line_input))
-    return 0;
-
-  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (line_input, "sw_if_index %d", &sw_if_index))
-	;
-      else if (unformat (line_input, "%U", unformat_vnet_sw_interface,
-			 vnm, &sw_if_index))
-	;
-      else
-	return clib_error_return (0, "unknown input `%U'",
-				  format_unformat_error, input);
-    }
-  unformat_free (line_input);
-
-  if (sw_if_index == ~0)
-    return clib_error_return (0,
-			      "please specify interface name or sw_if_index");
-
-  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
-  if (hw == NULL || mrvl_pp2_device_class.index != hw->dev_class_index)
-    return clib_error_return (0, "not a Marvell PP2 interface");
-
-  dif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
-
-  mrvl_pp2_delete_if (dif);
-
-  return 0;
-}
-
-VLIB_CLI_COMMAND (mrvl_pp2_delete_command, static) = {
-  .path = "delete interface marvell pp2",
-  .short_help = "delete interface marvell pp2 "
-    "{<interface> | sw_if_index <sw_idx>}",
-  .function = mrvl_pp2_delete_command_fn,
-};
-
-clib_error_t *
-mrvl_pp2_cli_init (vlib_main_t * vm)
-{
-  /* initialize binary API */
-  mrvl_pp2_plugin_api_hookup (vm);
-
-  return 0;
-}
-
-VLIB_INIT_FUNCTION (mrvl_pp2_cli_init);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/marvell/pp2/format.c b/src/plugins/marvell/pp2/format.c
deleted file mode 100644
index 877010e..0000000
--- a/src/plugins/marvell/pp2/format.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *------------------------------------------------------------------
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#include <vlib/vlib.h>
-#include <vlib/unix/unix.h>
-#include <vnet/plugin/plugin.h>
-#include <marvell/pp2/pp2.h>
-
-static inline u32
-mrvl_get_u32_bits (void *start, int offset, int first, int last)
-{
-  u32 value = *(u32 *) (((u8 *) start) + offset);
-  if ((last == 0) && (first == 31))
-    return value;
-  value >>= last;
-  value &= (1 << (first - last + 1)) - 1;
-  return value;
-}
-
-u8 *
-format_mrvl_pp2_interface_name (u8 * s, va_list * args)
-{
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  u32 dev_instance = va_arg (*args, u32);
-  mrvl_pp2_if_t *ppif = pool_elt_at_index (ppm->interfaces, dev_instance);
-  return format (s, "mv-ppio-%d/%d", ppif->ppio->pp2_id, ppif->ppio->port_id);
-}
-
-#define foreach_ppio_statistics_entry \
-  _(rx_packets) \
-  _(rx_fullq_dropped) \
-  _(rx_bm_dropped) \
-  _(rx_early_dropped) \
-  _(rx_fifo_dropped) \
-  _(rx_cls_dropped) \
-  _(tx_packets)
-
-#define foreach_ppio_inq_statistics_entry \
-  _(enq_desc) \
-  _(drop_early) \
-  _(drop_fullq) \
-  _(drop_bm)
-
-#define foreach_ppio_outq_statistics_entry \
-  _(enq_desc) \
-  _(enq_dec_to_ddr) \
-  _(enq_buf_to_ddr) \
-  _(deq_desc)
-
-u8 *
-format_mrvl_pp2_interface (u8 * s, va_list * args)
-{
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  u32 dev_instance = va_arg (*args, u32);
-  u32 indent = format_get_indent (s);
-  mrvl_pp2_if_t *ppif = pool_elt_at_index (ppm->interfaces, dev_instance);
-  struct pp2_ppio_statistics stat;
-  int i;
-  u8 *s2 = 0;
-
-  pp2_ppio_get_statistics (ppif->ppio, &stat, 0);
-
-#define _(c) if (stat.c) \
-  s2 = format (s2, "\n%U%-25U%16Ld", \
-	      format_white_space, indent + 2, \
-	      format_c_identifier, #c, stat.c);
-  foreach_ppio_statistics_entry;
-
-  if (vec_len (s2))
-    s = format (s, "Interface statistics:%v", s2);
-  vec_reset_length (s2);
-
-  vec_foreach_index (i, ppif->inqs)
-  {
-    struct pp2_ppio_inq_statistics stat = { 0 };
-    pp2_ppio_inq_get_statistics (ppif->ppio, 0, i, &stat, 0);
-
-    foreach_ppio_inq_statistics_entry;
-
-    if (vec_len (s2))
-      s = format (s, "\n%UInput queue %u statistics:%v",
-		  format_white_space, indent, i, s2);
-    vec_reset_length (s2);
-  }
-  vec_foreach_index (i, ppif->outqs)
-  {
-    struct pp2_ppio_outq_statistics stat = { 0 };
-
-    pp2_ppio_outq_get_statistics (ppif->ppio, i, &stat, 0);
-
-    foreach_ppio_outq_statistics_entry;
-
-    if (vec_len (s2))
-      s = format (s, "\n%UOutput queue %u statistics:%v",
-		  format_white_space, indent, i, s2);
-    vec_reset_length (s2);
-  }
-#undef _
-  vec_free (s2);
-  return s;
-}
-
-#define foreach_pp2_rx_desc_field \
-  _(0x00,  6,  0, l3_offset) \
-  _(0x00, 12,  8, ip_hdlen) \
-  _(0x00, 14, 13, ec) \
-  _(0x00, 15, 15, es) \
-  _(0x00, 19, 16, pool_id) \
-  _(0x00, 21, 21, hwf_sync) \
-  _(0x00, 22, 22, l4_chk_ok) \
-  _(0x00, 23, 23, ip_frg) \
-  _(0x00, 24, 24, ipv4_hdr_err) \
-  _(0x00, 27, 25, l4_info) \
-  _(0x00, 30, 28, l3_info) \
-  _(0x00, 31, 31, buf_header) \
-  _(0x04,  5,  0, lookup_id) \
-  _(0x04,  8,  6, cpu_code) \
-  _(0x04,  9,  9, pppoe) \
-  _(0x04, 11, 10, l3_cast_info) \
-  _(0x04, 13, 12, l2_cast_info) \
-  _(0x04, 15, 14, vlan_info) \
-  _(0x04, 31, 16, byte_count) \
-  _(0x08, 11,  0, gem_port_id) \
-  _(0x08, 13, 12, color) \
-  _(0x08, 14, 14, gop_sop_u) \
-  _(0x08, 15, 15, key_hash_enable) \
-  _(0x08, 31, 16, l4chk) \
-  _(0x0c, 31,  0, timestamp) \
-  _(0x10, 31,  0, buf_phys_ptr_lo) \
-  _(0x14,  7,  0, buf_phys_ptr_hi) \
-  _(0x14, 31,  8, key_hash) \
-  _(0x18, 31,  0, buf_virt_ptr_lo) \
-  _(0x1c,  7,  0, buf_virt_ptr_hi) \
-  _(0x1c, 14,  8, buf_qset_no) \
-  _(0x1c, 15, 15, buf_type) \
-  _(0x1c, 21, 16, mod_dscp) \
-  _(0x1c, 24, 22, mod_pri) \
-  _(0x1c, 25, 25, mdscp) \
-  _(0x1c, 26, 26, mpri) \
-  _(0x1c, 27, 27, mgpid) \
-  _(0x1c, 31, 29, port_num)
-
-u8 *
-format_mrvl_pp2_input_trace (u8 * s, va_list * args)
-{
-  vlib_main_t *vm = va_arg (*args, vlib_main_t *);
-  vlib_node_t *node = va_arg (*args, vlib_node_t *);
-  mrvl_pp2_input_trace_t *t = va_arg (*args, mrvl_pp2_input_trace_t *);
-  vnet_main_t *vnm = vnet_get_main ();
-  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, t->hw_if_index);
-  u32 indent = format_get_indent (s);
-  struct pp2_ppio_desc *d = &t->desc;
-  u32 r32;
-
-  s = format (s, "pp2: %v (%d) next-node %U",
-	      hi->name, t->hw_if_index, format_vlib_next_node_name, vm,
-	      node->index, t->next_index);
-  s = format (s, "\n%U", format_white_space, indent + 2);
-
-#define _(a, b, c, n) \
-  r32 = mrvl_get_u32_bits (d, a, b, c);				\
-  if (r32 > 9)							\
-    s = format (s, "%s %u (0x%x)", #n, r32, r32);		\
-  else								\
-    s = format (s, "%s %u", #n,r32);				\
-  if (format_get_indent (s) > 72)				\
-    s = format (s, "\n%U", format_white_space, indent + 2);	\
-  else s = format (s, " ");
-
-  foreach_pp2_rx_desc_field;
-#undef _
-  return s;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/marvell/pp2/input.c b/src/plugins/marvell/pp2/input.c
deleted file mode 100644
index 2545f91..0000000
--- a/src/plugins/marvell/pp2/input.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *------------------------------------------------------------------
- */
-
-#define _GNU_SOURCE
-#include <stdint.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include <vlib/vlib.h>
-#include <vlib/unix/unix.h>
-#include <vnet/ethernet/ethernet.h>
-#include <vnet/devices/devices.h>
-#include <vnet/interface/rx_queue_funcs.h>
-
-#include <marvell/pp2/pp2.h>
-
-#define foreach_mrvl_pp2_input_error \
-  _(PPIO_RECV, "pp2_ppio_recv error") \
-  _(BPOOL_GET_NUM_BUFFS, "pp2_bpool_get_num_buffs error") \
-  _(BPOOL_PUT_BUFFS, "pp2_bpool_put_buffs error") \
-  _(BUFFER_ALLOC, "buffer alloc error") \
-  _(MAC_CE, "MAC error (CRC error)") \
-  _(MAC_OR, "overrun error") \
-  _(MAC_RSVD, "unknown MAC error") \
-  _(MAC_RE, "resource error") \
-  _(IP_HDR, "ip4 header error")
-
-typedef enum
-{
-#define _(f,s) MRVL_PP2_INPUT_ERROR_##f,
-  foreach_mrvl_pp2_input_error
-#undef _
-    MRVL_PP2_INPUT_N_ERROR,
-} mrvl_pp2_input_error_t;
-
-static __clib_unused char *mrvl_pp2_input_error_strings[] = {
-#define _(n,s) s,
-  foreach_mrvl_pp2_input_error
-#undef _
-};
-
-static_always_inline void
-mrvl_pp2_input_trace (vlib_main_t * vm, vlib_node_runtime_t * node, u32 next0,
-		      vlib_buffer_t * b0, uword * n_trace,
-		      mrvl_pp2_if_t * ppif, struct pp2_ppio_desc *d)
-{
-  if (PREDICT_TRUE (
-	vlib_trace_buffer (vm, node, next0, b0, /* follow_chain */ 0)))
-    {
-      mrvl_pp2_input_trace_t *tr;
-      vlib_set_trace_count (vm, node, --(*n_trace));
-      tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
-      tr->next_index = next0;
-      tr->hw_if_index = ppif->hw_if_index;
-      clib_memcpy_fast (&tr->desc, d, sizeof (struct pp2_ppio_desc));
-    }
-}
-
-static_always_inline u16
-mrvl_pp2_set_buf_data_len_flags (vlib_buffer_t * b, struct pp2_ppio_desc *d,
-				 u32 add_flags)
-{
-  u16 len;
-  len = pp2_ppio_inq_desc_get_pkt_len (d);
-  b->total_length_not_including_first_buffer = 0;
-  b->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID | add_flags;
-
-  if (add_flags & VNET_BUFFER_F_L2_HDR_OFFSET_VALID)
-    vnet_buffer (b)->l2_hdr_offset = 2;
-
-  if (add_flags & VNET_BUFFER_F_L3_HDR_OFFSET_VALID)
-    {
-      u16 offset = DM_RXD_GET_L3_OFF (d);
-      vnet_buffer (b)->l3_hdr_offset = offset;
-      b->current_data = offset;
-      b->current_length = len - offset + 2;
-    }
-  else
-    {
-      b->current_data = 2;
-      b->current_length = len;
-    }
-
-  if (add_flags & VNET_BUFFER_F_L3_HDR_OFFSET_VALID)
-    vnet_buffer (b)->l4_hdr_offset = vnet_buffer (b)->l3_hdr_offset +
-      DM_RXD_GET_IPHDR_LEN (d) * 4;
-
-  return len;
-}
-
-static_always_inline u16
-mrvl_pp2_next_from_desc (vlib_node_runtime_t * node, struct pp2_ppio_desc * d,
-			 vlib_buffer_t * b, u32 * next)
-{
-  u8 l3_info;
-  /* ES bit set means MAC error  - drop and count */
-  if (PREDICT_FALSE (DM_RXD_GET_ES (d)))
-    {
-      *next = VNET_DEVICE_INPUT_NEXT_DROP;
-      u8 ec = DM_RXD_GET_EC (d);
-      if (ec == 0)
-	b->error = node->errors[MRVL_PP2_INPUT_ERROR_MAC_CE];
-      else if (ec == 1)
-	b->error = node->errors[MRVL_PP2_INPUT_ERROR_MAC_OR];
-      else if (ec == 2)
-	b->error = node->errors[MRVL_PP2_INPUT_ERROR_MAC_RSVD];
-      else if (ec == 3)
-	b->error = node->errors[MRVL_PP2_INPUT_ERROR_MAC_RE];
-      return mrvl_pp2_set_buf_data_len_flags (b, d, 0);
-    }
-  l3_info = DM_RXD_GET_L3_PRS_INFO (d);
-
-  /* ipv4 packet can be value 1, 2 or 3 */
-  if (PREDICT_TRUE ((l3_info - 1) < 3))
-    {
-      if (PREDICT_FALSE (DM_RXD_GET_L3_IP4_HDR_ERR (d) != 0))
-	{
-	  *next = VNET_DEVICE_INPUT_NEXT_DROP;
-	  b->error = node->errors[MRVL_PP2_INPUT_ERROR_IP_HDR];
-	  return mrvl_pp2_set_buf_data_len_flags (b, d, 0);
-	}
-      *next = VNET_DEVICE_INPUT_NEXT_IP4_NCS_INPUT;
-      return mrvl_pp2_set_buf_data_len_flags
-	(b, d,
-	 VNET_BUFFER_F_L2_HDR_OFFSET_VALID |
-	 VNET_BUFFER_F_L3_HDR_OFFSET_VALID |
-	 VNET_BUFFER_F_L4_HDR_OFFSET_VALID | VNET_BUFFER_F_IS_IP4);
-    }
-
-  /* ipv4 packet can be value 4 or 5 */
-  if (PREDICT_TRUE ((l3_info - 4) < 2))
-    {
-      *next = VNET_DEVICE_INPUT_NEXT_IP6_INPUT;
-      return mrvl_pp2_set_buf_data_len_flags
-	(b, d,
-	 VNET_BUFFER_F_L2_HDR_OFFSET_VALID |
-	 VNET_BUFFER_F_L3_HDR_OFFSET_VALID |
-	 VNET_BUFFER_F_L4_HDR_OFFSET_VALID | VNET_BUFFER_F_IS_IP6);
-    }
-
-  *next = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
-  return mrvl_pp2_set_buf_data_len_flags (b, d,
-					  VNET_BUFFER_F_L2_HDR_OFFSET_VALID);
-}
-
-static_always_inline uword
-mrvl_pp2_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
-			      vlib_frame_t * frame, mrvl_pp2_if_t * ppif,
-			      u16 qid)
-{
-  vnet_main_t *vnm = vnet_get_main ();
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  u32 thread_index = vm->thread_index;
-  mrvl_pp2_inq_t *inq = vec_elt_at_index (ppif->inqs, qid);
-  uword n_trace = vlib_get_trace_count (vm, node);
-  mrvl_pp2_per_thread_data_t *ptd =
-    vec_elt_at_index (ppm->per_thread_data, thread_index);
-  u32 next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
-  u32 sw_if_index[VLIB_N_RX_TX];
-  u32 n_rx_packets = 0;
-  u32 n_rx_bytes = 0;
-  u32 *to_next = 0;
-  struct pp2_ppio_desc *d;
-  u16 n_desc = VLIB_FRAME_SIZE;
-  u32 n_bufs;
-  u32 *buffers;
-  int i;
-
-  vec_validate_aligned (ptd->descs, n_desc, CLIB_CACHE_LINE_BYTES);
-  if (PREDICT_FALSE (pp2_ppio_recv (ppif->ppio, 0, qid, ptd->descs, &n_desc)))
-    {
-      vlib_error_count (vm, node->node_index, MRVL_PP2_INPUT_ERROR_PPIO_RECV,
-			1);
-      n_desc = 0;
-    }
-  n_rx_packets = n_desc;
-
-  for (i = 0; i < n_desc; i++)
-    ptd->buffers[i] = pp2_ppio_inq_desc_get_cookie (&ptd->descs[i]);
-
-  d = ptd->descs;
-  buffers = ptd->buffers;
-  sw_if_index[VLIB_RX] = ppif->sw_if_index;
-  sw_if_index[VLIB_TX] = (u32) ~ 0;
-  while (n_desc)
-    {
-      u32 n_left_to_next;
-      vlib_buffer_t *b0, *b1;
-      u32 bi0, bi1;
-      u32 next0, next1;
-      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-      while (n_desc >= 4 && n_left_to_next >= 2)
-	{
-	  /* prefetch */
-	  bi0 = buffers[0];
-	  bi1 = buffers[1];
-	  to_next[0] = bi0;
-	  to_next[1] = bi1;
-	  b0 = vlib_get_buffer (vm, bi0);
-	  b1 = vlib_get_buffer (vm, bi1);
-
-	  if (PREDICT_TRUE (ppif->per_interface_next_index == ~0))
-	    {
-	      n_rx_bytes += mrvl_pp2_next_from_desc (node, d, b0, &next0);
-	      n_rx_bytes += mrvl_pp2_next_from_desc (node, d + 1, b1, &next1);
-	      vnet_feature_start_device_input (ppif->sw_if_index, &next0, b0);
-	      vnet_feature_start_device_input (ppif->sw_if_index, &next1, b1);
-	    }
-	  else
-	    {
-	      n_rx_bytes += mrvl_pp2_set_buf_data_len_flags (b0, d, 0);
-	      n_rx_bytes += mrvl_pp2_set_buf_data_len_flags (b1, d + 1, 0);
-	      next0 = next1 = ppif->per_interface_next_index;
-	    }
-
-	  clib_memcpy_fast (vnet_buffer (b0)->sw_if_index, sw_if_index,
-			    sizeof (sw_if_index));
-	  clib_memcpy_fast (vnet_buffer (b1)->sw_if_index, sw_if_index,
-			    sizeof (sw_if_index));
-
-	  if (PREDICT_FALSE (n_trace > 0))
-	    {
-	      mrvl_pp2_input_trace (vm, node, next0, b0, &n_trace, ppif, d);
-	      if (n_trace > 0)
-		mrvl_pp2_input_trace (vm, node, next1, b1, &n_trace, ppif,
-				      d + 1);
-	    }
-
-	  to_next += 2;
-	  n_left_to_next -= 2;
-	  d += 2;
-	  buffers += 2;
-	  n_desc -= 2;
-
-	  /* enqueue */
-	  vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
-					   n_left_to_next, bi0, bi1, next0,
-					   next1);
-
-	}
-      while (n_desc && n_left_to_next)
-	{
-	  u32 bi0 = buffers[0];
-	  to_next[0] = bi0;
-	  b0 = vlib_get_buffer (vm, bi0);
-
-	  if (PREDICT_TRUE (ppif->per_interface_next_index == ~0))
-	    {
-	      n_rx_bytes += mrvl_pp2_next_from_desc (node, d, b0, &next0);
-	      vnet_feature_start_device_input (ppif->sw_if_index, &next0, b0);
-	    }
-	  else
-	    {
-	      n_rx_bytes += mrvl_pp2_set_buf_data_len_flags (b0, d, 0);
-	      next0 = ppif->per_interface_next_index;
-	    }
-
-	  clib_memcpy_fast (vnet_buffer (b0)->sw_if_index, sw_if_index,
-			    sizeof (sw_if_index));
-
-	  if (PREDICT_FALSE (n_trace > 0))
-	    mrvl_pp2_input_trace (vm, node, next0, b0, &n_trace, ppif, d);
-
-	  to_next += 1;
-	  n_left_to_next--;
-	  d++;
-	  buffers++;
-	  n_desc--;
-
-	  /* enqueue */
-	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
-					   n_left_to_next, bi0, next0);
-	}
-      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
-    }
-  vlib_increment_combined_counter (vnm->
-				   interface_main.combined_sw_if_counters +
-				   VNET_INTERFACE_COUNTER_RX, thread_index,
-				   ppif->hw_if_index, n_rx_packets,
-				   n_rx_bytes);
-
-  if (PREDICT_FALSE (pp2_bpool_get_num_buffs (inq->bpool, &n_bufs)))
-    {
-      vlib_error_count (vm, node->node_index,
-			MRVL_PP2_INPUT_ERROR_BPOOL_GET_NUM_BUFFS, 1);
-      goto done;
-    }
-
-  n_bufs = inq->size - n_bufs;
-  while (n_bufs >= MRVL_PP2_BUFF_BATCH_SZ)
-    {
-      u16 n_alloc, i;
-      struct buff_release_entry *e = ptd->bre;
-      u32 *buffers = ptd->buffers;
-
-      n_alloc = vlib_buffer_alloc (vm, ptd->buffers, MRVL_PP2_BUFF_BATCH_SZ);
-      i = n_alloc;
-
-      if (PREDICT_FALSE (n_alloc == 0))
-	{
-	  vlib_error_count (vm, node->node_index,
-			    MRVL_PP2_INPUT_ERROR_BUFFER_ALLOC, 1);
-	  goto done;
-	}
-
-      while (i--)
-	{
-	  u32 bi = buffers[0];
-	  vlib_buffer_t *b = vlib_get_buffer (vm, bi);
-	  e->buff.addr = vlib_buffer_get_pa (vm, b) - 64;
-	  e->buff.cookie = bi;
-	  e->bpool = inq->bpool;
-	  e++;
-	  buffers++;
-	}
-
-      i = n_alloc;
-      if (PREDICT_FALSE (pp2_bpool_put_buffs (ptd->hif, ptd->bre, &i)))
-	{
-	  vlib_error_count (vm, node->node_index,
-			    MRVL_PP2_INPUT_ERROR_BPOOL_PUT_BUFFS, 1);
-	  vlib_buffer_free (vm, ptd->buffers, n_alloc);
-	  goto done;
-	}
-
-      if (PREDICT_FALSE (i != n_alloc))
-	vlib_buffer_free (vm, ptd->buffers + i, n_alloc - i);
-
-      n_bufs -= i;
-    }
-
-done:
-  return n_rx_packets;
-}
-
-uword
-mrvl_pp2_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
-		   vlib_frame_t * frame)
-{
-  u32 n_rx = 0;
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  vnet_hw_if_rxq_poll_vector_t *pv;
-
-  pv = vnet_hw_if_get_rxq_poll_vector (vm, node);
-
-  for (int i = 0; i < vec_len (pv); i++)
-    {
-      mrvl_pp2_if_t *ppif;
-      ppif = vec_elt_at_index (ppm->interfaces, pv[i].dev_instance);
-      if (ppif->flags & MRVL_PP2_IF_F_ADMIN_UP)
-	n_rx +=
-	  mrvl_pp2_device_input_inline (vm, node, frame, ppif, pv[i].queue_id);
-    }
-  return n_rx;
-}
-
-VLIB_REGISTER_NODE (mrvl_pp2_input_node) = {
-  .function = mrvl_pp2_input_fn,
-  .flags = VLIB_NODE_FLAG_TRACE_SUPPORTED,
-  .name = "mrvl-pp2-input",
-  .sibling_of = "device-input",
-  .format_trace = format_mrvl_pp2_input_trace,
-  .type = VLIB_NODE_TYPE_INPUT,
-  .state = VLIB_NODE_STATE_POLLING,
-  .n_errors = MRVL_PP2_INPUT_N_ERROR,
-  .error_strings = mrvl_pp2_input_error_strings,
-};
-
-
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/marvell/pp2/output.c b/src/plugins/marvell/pp2/output.c
deleted file mode 100644
index 911b2f5..0000000
--- a/src/plugins/marvell/pp2/output.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *------------------------------------------------------------------
- */
-
-#include <stdint.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-
-#include <vlib/vlib.h>
-#include <vlib/unix/unix.h>
-#include <vnet/ethernet/ethernet.h>
-#include <vnet/devices/devices.h>
-
-#include <marvell/pp2/pp2.h>
-
-uword
-mrvl_pp2_interface_tx (vlib_main_t * vm,
-		       vlib_node_runtime_t * node, vlib_frame_t * frame)
-{
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  vnet_interface_output_runtime_t *rd = (void *) node->runtime_data;
-  mrvl_pp2_if_t *ppif = pool_elt_at_index (ppm->interfaces, rd->dev_instance);
-  u32 thread_index = vm->thread_index;
-  mrvl_pp2_per_thread_data_t *ptd =
-    vec_elt_at_index (ppm->per_thread_data, thread_index);
-  u8 qid = thread_index;
-  mrvl_pp2_outq_t *outq = vec_elt_at_index (ppif->outqs, qid);
-  u32 *buffers = vlib_frame_vector_args (frame);
-  u16 n_desc = frame->n_vectors, n_left = n_desc, n_sent = n_desc, n_done;
-  struct pp2_ppio_desc *d;
-  u16 mask = outq->size - 1;
-
-  if (PREDICT_FALSE (pp2_ppio_get_num_outq_done (ppif->ppio, ptd->hif, qid,
-						 &n_done)))
-    {
-      n_done = 0;
-      vlib_error_count (vm, node->node_index,
-			MRVL_PP2_TX_ERROR_PPIO_GET_NUM_OUTQ_DONE, 1);
-    }
-
-  if (n_done)
-    {
-      u16 n_free = clib_min (n_done, outq->size - (outq->tail & mask));
-      vlib_buffer_free (vm, outq->buffers + (outq->tail & mask), n_free);
-      if (PREDICT_FALSE (n_free < n_done))
-	vlib_buffer_free (vm, outq->buffers, n_done - n_free);
-      outq->tail += n_done;
-    }
-
-  vec_validate_aligned (ptd->descs, n_left, CLIB_CACHE_LINE_BYTES);
-  d = ptd->descs;
-  while (n_left)
-    {
-      u32 bi0 = buffers[0];
-      vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0);
-      u64 paddr = vlib_buffer_get_pa (vm, b0);
-
-      pp2_ppio_outq_desc_reset (d);
-      pp2_ppio_outq_desc_set_phys_addr (d, paddr + b0->current_data);
-      pp2_ppio_outq_desc_set_pkt_offset (d, 0);
-      pp2_ppio_outq_desc_set_pkt_len (d, b0->current_length);
-      d++;
-      buffers++;
-      n_left--;
-    }
-
-  if (pp2_ppio_send (ppif->ppio, ptd->hif, qid, ptd->descs, &n_sent))
-    {
-      n_sent = 0;
-      vlib_error_count (vm, node->node_index, MRVL_PP2_TX_ERROR_PPIO_SEND, 1);
-    }
-
-  /* free unsent buffers */
-  if (PREDICT_FALSE (n_sent != n_desc))
-    {
-      vlib_buffer_free (vm, vlib_frame_vector_args (frame) + n_sent,
-			frame->n_vectors - n_sent);
-      vlib_error_count (vm, node->node_index, MRVL_PP2_TX_ERROR_NO_FREE_SLOTS,
-			frame->n_vectors - n_sent);
-    }
-
-  /* store buffer index for each enqueued packet into the ring
-     so we can know what to free after packet is sent */
-  if (n_sent)
-    {
-      u16 slot = outq->head & mask;
-      buffers = vlib_frame_vector_args (frame);
-      u16 n_copy = clib_min (outq->size - slot, n_sent);
-
-      vlib_buffer_copy_indices (outq->buffers + slot, buffers, n_copy);
-      if (PREDICT_FALSE (n_copy < n_sent))
-	clib_memcpy_fast (outq->buffers, buffers + n_copy,
-			  (n_sent - n_copy) * sizeof (u32));
-
-      outq->head += n_sent;
-    }
-
-  return n_sent;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/marvell/pp2/pp2.c b/src/plugins/marvell/pp2/pp2.c
deleted file mode 100644
index 030ab9b..0000000
--- a/src/plugins/marvell/pp2/pp2.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *------------------------------------------------------------------
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#include <vlib/vlib.h>
-#include <vlib/unix/unix.h>
-#include <vnet/plugin/plugin.h>
-#include <marvell/pp2/pp2.h>
-#include <vnet/interface/rx_queue_funcs.h>
-
-/* size of DMA memory used by musdk (not used for buffers) */
-#define MV_SYS_DMA_MEM_SZ		(2 << 20)
-/* number of HIFs reserved (first X) */
-#define NUM_HIFS_RSVD			4
-/* number of buffer pools reserved (first X) */
-#define NUM_BPOOLS_RSVD			7
-
-mrvl_pp2_main_t mrvl_pp2_main;
-extern vnet_device_class_t ppa2_device_class;
-
-static void
-mrvl_pp2_main_deinit ()
-{
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  int i;
-  vec_foreach_index (i, ppm->per_thread_data)
-  {
-    mrvl_pp2_per_thread_data_t *ptd = vec_elt_at_index (ppm->per_thread_data,
-							i);
-    if (ptd->hif)
-      pp2_hif_deinit (ptd->hif);
-    vec_free (ptd->descs);
-  }
-  vec_free (ppm->per_thread_data);
-  pp2_deinit ();
-  mv_sys_dma_mem_destroy ();
-}
-
-static clib_error_t *
-mrvl_pp2_main_init ()
-{
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  vlib_thread_main_t *tm = vlib_get_thread_main ();
-  clib_error_t *err = 0;
-  struct pp2_init_params init_params = { 0 };
-  int i, rv;
-  u8 *s = 0;
-
-  rv = mv_sys_dma_mem_init (MV_SYS_DMA_MEM_SZ);
-  if (rv)
-    return clib_error_return (0, "mv_sys_dma_mem_init failed, rv = %u", rv);
-
-  init_params.hif_reserved_map = ((1 << NUM_HIFS_RSVD) - 1);
-  init_params.bm_pool_reserved_map = ((1 << NUM_BPOOLS_RSVD) - 1);
-  rv = pp2_init (&init_params);
-  if (rv)
-    {
-      err = clib_error_return (0, "mrvl_pp2_init failed, rv = %u", rv);
-      goto done;
-    }
-
-  vec_validate_aligned (ppm->per_thread_data, tm->n_vlib_mains - 1,
-			CLIB_CACHE_LINE_BYTES);
-
-  vec_foreach_index (i, ppm->per_thread_data)
-  {
-    mrvl_pp2_per_thread_data_t *ptd = vec_elt_at_index (ppm->per_thread_data,
-							i);
-    struct pp2_hif_params hif_params = { 0 };
-    vec_reset_length (s);
-    s = format (s, "hif-%d%c", NUM_HIFS_RSVD + i, 0);
-    hif_params.match = (char *) s;
-    hif_params.out_size = 2048;	/* FIXME */
-    if (pp2_hif_init (&hif_params, &ptd->hif))
-      {
-	err = clib_error_return (0, "hif '%s' init failed", s);
-	goto done;
-      }
-  }
-
-done:
-  if (err)
-    mrvl_pp2_main_deinit ();
-  vec_free (s);
-  return err;
-}
-
-static u32
-mrvl_pp2_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi,
-			  u32 flags)
-{
-  /* nothing for now */
-  return 0;
-}
-
-void
-mrvl_pp2_delete_if (mrvl_pp2_if_t * ppif)
-{
-  vlib_main_t *vm = vlib_get_main ();
-  vnet_main_t *vnm = vnet_get_main ();
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  mrvl_pp2_outq_t *outq;
-  mrvl_pp2_inq_t *inq;
-
-  if (ppif->hw_if_index != ~0)
-      ethernet_delete_interface (vnm, ppif->hw_if_index);
-
-  if (ppif->ppio)
-    {
-      pp2_ppio_disable (ppif->ppio);
-      pp2_ppio_deinit (ppif->ppio);
-    }
-
-  /* free buffers hanging in the tx ring */
-  vec_foreach (outq, ppif->outqs)
-    {
-      while (outq->tail < outq->head)
-	{
-	  u16 slot = outq->tail & (outq->size - 1);
-	  vlib_buffer_free (vm, outq->buffers + slot, 1);
-	  outq->tail++;
-	}
-      vec_free (outq->buffers);
-    }
-  vec_free (ppif->outqs);
-
-  /* free buffers hangin in the rx buffer pool */
-  vec_foreach (inq, ppif->inqs)
-    if (inq->bpool)
-      {
-	u32 n_bufs = 0;
-	pp2_bpool_get_num_buffs (inq->bpool, &n_bufs);
-	while (n_bufs--)
-	  {
-	    struct pp2_buff_inf binf;
-	    if (pp2_bpool_get_buff (ppm->per_thread_data[0].hif, inq->bpool,
-				    &binf) == 0)
-	      {
-	         u32 bi = binf.cookie;
-	         vlib_buffer_free (vm, &bi, 1);
-	      }
-	  }
-	pp2_bpool_deinit (inq->bpool);
-      }
-  vec_free (ppif->inqs);
-
-
-  pool_put (ppm->interfaces, ppif);
-
-  if (pool_elts (ppm->interfaces) == 0)
-    mrvl_pp2_main_deinit ();
-}
-
-void
-mrvl_pp2_create_if (mrvl_pp2_create_if_args_t * args)
-{
-  vlib_main_t *vm = vlib_get_main ();
-  vnet_main_t *vnm = vnet_get_main ();
-  vlib_thread_main_t *tm = vlib_get_thread_main ();
-  vnet_eth_interface_registration_t eir = {};
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  struct pp2_bpool_params bpool_params = { 0 };
-  struct pp2_ppio_params ppio_params = { 0 };
-  struct pp2_ppio_inq_params inq_params = { 0 };
-  vnet_sw_interface_t *sw;
-  mrvl_pp2_if_t *ppif = 0;
-  u8 pp2_id, port_id, *s = 0;
-  eth_addr_t mac_addr;
-  u8 n_outqs, n_inqs = 1;
-  int i;
-
-  if (tm->n_vlib_mains > PP2_PPIO_MAX_NUM_OUTQS)
-    {
-      args->rv = VNET_API_ERROR_INIT_FAILED;
-      args->error = clib_error_return (0, "number of threads (main + workers)"
-				       " is bigger than number of output "
-				       "queues (%u)", PP2_PPIO_MAX_NUM_OUTQS);
-      return;
-    }
-  n_outqs = tm->n_vlib_mains;
-
-  /* defaults */
-  args->tx_q_sz = args->tx_q_sz ? args->tx_q_sz : 2 * VLIB_FRAME_SIZE;
-  args->rx_q_sz = args->rx_q_sz ? args->rx_q_sz : 2 * VLIB_FRAME_SIZE;
-
-  if (vec_len (ppm->per_thread_data) == 0)
-    {
-      if ((args->error = mrvl_pp2_main_init ()) != 0)
-	{
-	  args->rv = VNET_API_ERROR_INIT_FAILED;
-	  return;
-	}
-    }
-
-  pool_get_zero (ppm->interfaces, ppif);
-  ppif->dev_instance = ppif - ppm->interfaces;
-  ppif->hw_if_index = ~0;
-  vec_validate_aligned (ppif->inqs, n_inqs - 1, CLIB_CACHE_LINE_BYTES);
-  vec_validate_aligned (ppif->outqs, n_outqs - 1, CLIB_CACHE_LINE_BYTES);
-
-  for (i = 0; i < n_inqs; i++)
-    {
-      mrvl_pp2_inq_t *inq = vec_elt_at_index (ppif->inqs, i);
-      inq->size = args->rx_q_sz;
-    }
-  for (i = 0; i < n_outqs; i++)
-    {
-      mrvl_pp2_outq_t *outq = vec_elt_at_index (ppif->outqs, i);
-      outq->size = args->tx_q_sz;
-      vec_validate_aligned (outq->buffers, outq->size, CLIB_CACHE_LINE_BYTES);
-    }
-
-  if (pp2_netdev_get_ppio_info ((char *) args->name, &pp2_id, &port_id))
-    {
-      args->rv = VNET_API_ERROR_INVALID_INTERFACE;
-      args->error = clib_error_return (0, "Invalid interface '%s'",
-				       args->name);
-      goto error;
-    }
-
-  /* FIXME bpool bit select per pp */
-  s = format (s, "pool-%d:%d%c", pp2_id, pp2_id + 8, 0);
-  bpool_params.match = (char *) s;
-  bpool_params.buff_len = vlib_buffer_get_default_data_size (vm);
-  /* FIXME +64 ? */
-  if (pp2_bpool_init (&bpool_params, &ppif->inqs[0].bpool))
-    {
-      args->rv = VNET_API_ERROR_INIT_FAILED;
-      args->error = clib_error_return (0, "bpool '%s' init failed", s);
-      goto error;
-    }
-  vec_reset_length (s);
-
-  s = format (s, "ppio-%d:%d%c", pp2_id, port_id, 0);
-  ppio_params.match = (char *) s;
-  ppio_params.type = PP2_PPIO_T_NIC;
-  inq_params.size = args->rx_q_sz;
-  ppio_params.inqs_params.num_tcs = 1;
-  ppio_params.inqs_params.tcs_params[0].pkt_offset = 0;
-  ppio_params.inqs_params.tcs_params[0].num_in_qs = n_inqs;
-  ppio_params.inqs_params.tcs_params[0].inqs_params = &inq_params;
-  ppio_params.inqs_params.tcs_params[0].pools[0][0] = ppif->inqs[0].bpool;
-  ppio_params.outqs_params.num_outqs = n_outqs;
-  for (i = 0; i < n_outqs; i++)
-    {
-      ppio_params.outqs_params.outqs_params[i].weight = 1;
-      ppio_params.outqs_params.outqs_params[i].size = args->tx_q_sz;
-    }
-  if (pp2_ppio_init (&ppio_params, &ppif->ppio))
-    {
-      args->rv = VNET_API_ERROR_INIT_FAILED;
-      args->error = clib_error_return (0, "ppio '%s' init failed", s);
-      goto error;
-    }
-  vec_reset_length (s);
-
-  if (pp2_ppio_get_mac_addr (ppif->ppio, mac_addr))
-    {
-      args->rv = VNET_API_ERROR_INIT_FAILED;
-      args->error =
-	clib_error_return (0, "%s: pp2_ppio_get_mac_addr failed", s);
-      goto error;
-    }
-
-  eir.dev_class_index = mrvl_pp2_device_class.index;
-  eir.dev_instance = ppif->dev_instance;
-  eir.address = mac_addr;
-  eir.cb.flag_change = mrvl_pp2_eth_flag_change;
-  ppif->hw_if_index = vnet_eth_register_interface (vnm, &eir);
-
-  sw = vnet_get_hw_sw_interface (vnm, ppif->hw_if_index);
-  ppif->sw_if_index = sw->sw_if_index;
-  ppif->per_interface_next_index = ~0;
-  args->sw_if_index = sw->sw_if_index;
-  vnet_hw_if_set_input_node (vnm, ppif->hw_if_index,
-			     mrvl_pp2_input_node.index);
-  /* FIXME: only one RX queue ? */
-  ppif->inqs[0].queue_index = vnet_hw_if_register_rx_queue (
-    vnm, ppif->hw_if_index, 0, VNET_HW_IF_RXQ_THREAD_ANY);
-
-  vnet_hw_if_set_rx_queue_mode (vnm, ppif->inqs[0].queue_index,
-				VNET_HW_IF_RX_MODE_POLLING);
-  vnet_hw_if_update_runtime_data (vnm, ppif->hw_if_index);
-  vnet_hw_interface_set_flags (vnm, ppif->hw_if_index,
-			       VNET_HW_INTERFACE_FLAG_LINK_UP);
-  goto done;
-
-error:
-  mrvl_pp2_delete_if (ppif);
-done:
-  vec_free (s);
-}
-
-static clib_error_t *
-mrvl_pp2_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index,
-				  u32 flags)
-{
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
-  mrvl_pp2_if_t *ppif = pool_elt_at_index (ppm->interfaces, hw->dev_instance);
-  static clib_error_t *error = 0;
-  int is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
-  int rv;
-
-  if (is_up)
-    rv = pp2_ppio_enable (ppif->ppio);
-  else
-    rv = pp2_ppio_disable (ppif->ppio);
-
-  if (rv)
-    return clib_error_return (0, "failed to %s interface",
-			      is_up ? "enable" : "disable");
-
-  if (is_up)
-    ppif->flags |= MRVL_PP2_IF_F_ADMIN_UP;
-  else
-    ppif->flags &= ~MRVL_PP2_IF_F_ADMIN_UP;
-
-  return error;
-}
-
-static void
-mrvl_pp2_clear_interface_counters (u32 instance)
-{
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  mrvl_pp2_if_t *ppif = pool_elt_at_index (ppm->interfaces, instance);
-  struct pp2_ppio_statistics stats;
-
-  pp2_ppio_get_statistics (ppif->ppio, &stats, 1);
-}
-
-static void
-mrvl_pp2_set_interface_next_node (vnet_main_t * vnm, u32 hw_if_index,
-				  u32 node_index)
-{
-  mrvl_pp2_main_t *ppm = &mrvl_pp2_main;
-  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
-  mrvl_pp2_if_t *ppif = pool_elt_at_index (ppm->interfaces, hw->dev_instance);
-
-  /* Shut off redirection */
-  if (node_index == ~0)
-    {
-      ppif->per_interface_next_index = node_index;
-      return;
-    }
-
-  ppif->per_interface_next_index =
-    vlib_node_add_next (vlib_get_main (), mrvl_pp2_input_node.index,
-			node_index);
-}
-
-static char *mrvl_pp2_tx_func_error_strings[] = {
-#define _(n,s) s,
-  foreach_mrvl_pp2_tx_func_error
-#undef _
-};
-
-VNET_DEVICE_CLASS (mrvl_pp2_device_class,) =
-{
-  .name = "Marvell PPv2 interface",
-  .format_device_name = format_mrvl_pp2_interface_name,
-  .format_device = format_mrvl_pp2_interface,
-  .tx_function = mrvl_pp2_interface_tx,
-  .tx_function_n_errors = MRVL_PP2_TX_N_ERROR,
-  .tx_function_error_strings = mrvl_pp2_tx_func_error_strings,
-  .admin_up_down_function = mrvl_pp2_interface_admin_up_down,
-  .clear_counters = mrvl_pp2_clear_interface_counters,
-  .rx_redirect_to_node = mrvl_pp2_set_interface_next_node,
-};
-
-static clib_error_t *
-mrvl_pp2_init (vlib_main_t * vm)
-{
-  return 0;
-}
-
-VLIB_INIT_FUNCTION (mrvl_pp2_init);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/marvell/pp2/pp2.h b/src/plugins/marvell/pp2/pp2.h
deleted file mode 100644
index abb8e57..0000000
--- a/src/plugins/marvell/pp2/pp2.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *------------------------------------------------------------------
- */
-
-#define MVCONF_DBG_LEVEL 0
-#define MVCONF_PP2_BPOOL_COOKIE_SIZE 32
-#define MVCONF_PP2_BPOOL_DMA_ADDR_SIZE 64
-#define MVCONF_DMA_PHYS_ADDR_T_SIZE 64
-#define MVCONF_SYS_DMA_UIO
-#define MVCONF_TYPES_PUBLIC
-#define MVCONF_DMA_PHYS_ADDR_T_PUBLIC
-
-#include <vlib/vlib.h>
-
-#include "mv_std.h"
-#include "env/mv_sys_dma.h"
-#include "drivers/mv_pp2.h"
-#include <drivers/mv_pp2_bpool.h>
-#include <drivers/mv_pp2_ppio.h>
-
-typedef struct
-{
-  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
-  u16 size;
-  u32 queue_index;
-  struct pp2_bpool *bpool;
-} mrvl_pp2_inq_t;
-
-typedef struct
-{
-  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
-  u16 size;
-  u32 *buffers;
-  u16 head;
-  u16 tail;
-} mrvl_pp2_outq_t;
-
-typedef struct
-{
-  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
-  u32 flags;
-#define MRVL_PP2_IF_F_ADMIN_UP (1 << 0)
-  struct pp2_ppio *ppio;
-  u32 per_interface_next_index;
-
-  mrvl_pp2_inq_t *inqs;
-  mrvl_pp2_outq_t *outqs;
-
-  u32 dev_instance;
-  u32 sw_if_index;
-  u32 hw_if_index;
-} mrvl_pp2_if_t;
-
-#define MRVL_PP2_BUFF_BATCH_SZ VLIB_FRAME_SIZE
-
-typedef struct
-{
-  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
-  struct pp2_hif *hif;
-  struct pp2_ppio_desc *descs;
-  struct buff_release_entry bre[MRVL_PP2_BUFF_BATCH_SZ];
-  u32 buffers[VLIB_FRAME_SIZE];
-} mrvl_pp2_per_thread_data_t;
-
-typedef struct
-{
-  mrvl_pp2_if_t *interfaces;
-  mrvl_pp2_per_thread_data_t *per_thread_data;
-
-  /* API message ID base */
-  u16 msg_id_base;
-} mrvl_pp2_main_t;
-
-extern vnet_device_class_t mrvl_pp2_device_class;
-extern mrvl_pp2_main_t mrvl_pp2_main;
-
-typedef struct
-{
-  u8 *name;
-  u16 rx_q_sz;
-  u16 tx_q_sz;
-
-  /* return */
-  i32 rv;
-  u32 sw_if_index;
-  clib_error_t *error;
-} mrvl_pp2_create_if_args_t;
-
-void mrvl_pp2_create_if (mrvl_pp2_create_if_args_t * args);
-void mrvl_pp2_delete_if (mrvl_pp2_if_t * dfif);
-clib_error_t *mrvl_pp2_plugin_api_hookup (vlib_main_t * vm);
-
-/* output.c */
-
-#define foreach_mrvl_pp2_tx_func_error \
-  _(NO_FREE_SLOTS, "no free tx slots")			\
-  _(PPIO_SEND, "pp2_ppio_send errors")			\
-  _(PPIO_GET_NUM_OUTQ_DONE, "pp2_ppio_get_num_outq_done errors")
-
-typedef enum
-{
-#define _(f,s) MRVL_PP2_TX_ERROR_##f,
-  foreach_mrvl_pp2_tx_func_error
-#undef _
-    MRVL_PP2_TX_N_ERROR,
-} mrvl_pp2_tx_func_error_t;
-
-uword mrvl_pp2_interface_tx (vlib_main_t * vm, vlib_node_runtime_t * node,
-			     vlib_frame_t * frame);
-
-/* input.c */
-
-typedef struct
-{
-  u32 next_index;
-  u32 hw_if_index;
-  struct pp2_ppio_desc desc;
-} mrvl_pp2_input_trace_t;
-
-extern vlib_node_registration_t mrvl_pp2_input_node;
-
-/* format.c */
-format_function_t format_mrvl_pp2_input_trace;
-format_function_t format_mrvl_pp2_interface;
-format_function_t format_mrvl_pp2_interface_name;
-
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/marvell/pp2/pp2_api.c b/src/plugins/marvell/pp2/pp2_api.c
deleted file mode 100644
index c1f3a9e..0000000
--- a/src/plugins/marvell/pp2/pp2_api.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2019 Arm Limited.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *------------------------------------------------------------------
- */
-
-#include <vlib/vlib.h>
-#include <vlib/unix/unix.h>
-#include <vnet/ethernet/ethernet.h>
-
-#include <marvell/pp2/pp2.h>
-
-#include <vlibapi/api.h>
-#include <vlibmemory/api.h>
-
-/* define message IDs */
-#include <marvell/pp2/pp2.api_enum.h>
-#include <marvell/pp2/pp2.api_types.h>
-
-#define REPLY_MSG_ID_BASE (pp2->msg_id_base)
-#include <vlibapi/api_helper_macros.h>
-
-static void
-vl_api_mrvl_pp2_create_t_handler (vl_api_mrvl_pp2_create_t * mp)
-{
-  mrvl_pp2_main_t *pp2 = &mrvl_pp2_main;
-  mrvl_pp2_create_if_args_t args = { 0 };
-  vl_api_mrvl_pp2_create_reply_t *rmp;
-  int rv;
-
-  args.name = format (0, "%s", mp->if_name);
-  args.rx_q_sz = ntohs (mp->rx_q_sz);
-  args.tx_q_sz = ntohs (mp->tx_q_sz);
-  mrvl_pp2_create_if (&args);
-  rv = args.rv;
-  vec_free (args.name);
-  if (args.error)
-    {
-      clib_error_free (args.error);
-    }
-  REPLY_MACRO2 (VL_API_MRVL_PP2_CREATE_REPLY,
-		({ rmp->sw_if_index = ntohl (args.sw_if_index); }));
-}
-
-static void
-vl_api_mrvl_pp2_delete_t_handler (vl_api_mrvl_pp2_delete_t * mp)
-{
-  vnet_main_t *vnm = vnet_get_main ();
-  vnet_hw_interface_t *hw;
-  mrvl_pp2_main_t *pp2 = &mrvl_pp2_main;
-  vl_api_mrvl_pp2_delete_reply_t *rmp;
-  mrvl_pp2_if_t *dif;
-  int rv = 0;
-  mp->sw_if_index = ntohl (mp->sw_if_index);
-  hw = vnet_get_sup_hw_interface (vnm, mp->sw_if_index);
-  if (hw == NULL || mrvl_pp2_device_class.index != hw->dev_class_index)
-    {
-      rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
-      goto reply;
-    }
-
-  dif = pool_elt_at_index (pp2->interfaces, hw->dev_instance);
-
-  mrvl_pp2_delete_if (dif);
-
-reply:
-  REPLY_MACRO (VL_API_MRVL_PP2_DELETE_REPLY);
-}
-
-#include <marvell/pp2/pp2.api.c>
-/* set up the API message handling tables */
-clib_error_t *
-mrvl_pp2_plugin_api_hookup (vlib_main_t * vm)
-{
-  mrvl_pp2_main_t *pp2 = &mrvl_pp2_main;
-
-  /* ask for a correctly-sized block of API message decode slots */
-  pp2->msg_id_base = setup_message_id_table ();
-
-  return 0;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/marvell/pp2/pp2_test.c b/src/plugins/marvell/pp2/pp2_test.c
deleted file mode 100644
index 26a9e9a..0000000
--- a/src/plugins/marvell/pp2/pp2_test.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- *------------------------------------------------------------------
- * Copyright (c) 2019 Arm Limited.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *------------------------------------------------------------------
- */
-
-#include <vlib/vlib.h>
-#include <vlib/unix/unix.h>
-#include <vnet/ethernet/ethernet.h>
-
-#include <vat/vat.h>
-#include <vlibapi/api.h>
-#include <vlibmemory/api.h>
-
-#include <vppinfra/error.h>
-#include <marvell/pp2/pp2.h>
-
-#define __plugin_msg_base pp2_test_main.msg_id_base
-#include <vlibapi/vat_helper_macros.h>
-
-/* declare message IDs */
-#include <marvell/pp2/pp2.api_enum.h>
-#include <marvell/pp2/pp2.api_types.h>
-
-typedef struct
-{
-  /* API message ID base */
-  u16 msg_id_base;
-  vat_main_t *vat_main;
-} pp2_test_main_t;
-
-pp2_test_main_t pp2_test_main;
-
-/* mrvl_pp2 create API */
-static int
-api_mrvl_pp2_create (vat_main_t * vam)
-{
-  unformat_input_t *i = vam->input;
-  vl_api_mrvl_pp2_create_t *mp;
-  mrvl_pp2_create_if_args_t args;
-  int ret;
-  u16 size;
-
-  clib_memset (&args, 0, sizeof (mrvl_pp2_create_if_args_t));
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "name %s", &args.name))
-	;
-      else if (unformat (i, "rx-queue-size %u", &size))
-	args.rx_q_sz = size;
-      else if (unformat (i, "tx-queue-size %u", &size))
-	args.tx_q_sz = size;
-      else
-	{
-	  clib_warning ("unknown input '%U'", format_unformat_error, i);
-	  return -99;
-	}
-    }
-
-  M (MRVL_PP2_CREATE, mp);
-
-  strncpy_s ((char *) mp->if_name, ARRAY_LEN (mp->if_name),
-	     (char *) (args.name), strlen ((char *) args.name));
-  mp->rx_q_sz = clib_host_to_net_u16 (args.rx_q_sz);
-  mp->tx_q_sz = clib_host_to_net_u16 (args.tx_q_sz);
-
-  S (mp);
-  W (ret);
-
-  vec_free (args.name);
-
-  return ret;
-}
-
-/* mrvl_pp2 create reply handler */
-static void
-vl_api_mrvl_pp2_create_reply_t_handler (vl_api_mrvl_pp2_create_reply_t * mp)
-{
-  vat_main_t *vam = pp2_test_main.vat_main;
-  i32 retval = ntohl (mp->retval);
-
-  if (retval == 0)
-    {
-      fformat (vam->ofp, "created mrvl_pp2 with sw_if_index %d\n",
-	       ntohl (mp->sw_if_index));
-    }
-
-  vam->retval = retval;
-  vam->result_ready = 1;
-  vam->regenerate_interface_table = 1;
-}
-
-
-/* mrvl_pp2 delete API */
-static int
-api_mrvl_pp2_delete (vat_main_t * vam)
-{
-  unformat_input_t *i = vam->input;
-  //vnet_main_t *vnm = vnet_get_main ();
-  vl_api_mrvl_pp2_delete_t *mp;
-  u32 sw_if_index = 0;
-  int ret;
-
-  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (i, "sw_if_index %d", &sw_if_index))
-	;
-      else
-	{
-	  clib_warning ("unknown input '%U'", format_unformat_error, i);
-	  return -99;
-	}
-    }
-
-  M (MRVL_PP2_DELETE, mp);
-
-  mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
-
-  S (mp);
-  W (ret);
-
-  return ret;
-}
-
-#include <marvell/pp2/pp2.api_test.c>
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dev/errors.h b/src/vnet/dev/errors.h
index 430a6ae..6ececad 100644
--- a/src/vnet/dev/errors.h
+++ b/src/vnet/dev/errors.h
@@ -41,6 +41,7 @@
   _ (UNSUPPORTED_DEVICE, "unsupported device")                                \
   _ (UNSUPPORTED_DEVICE_VER, "unsupported device version")                    \
   _ (ALREADY_DONE, "already done")                                            \
-  _ (NO_SUCH_INTERFACE, "no such interface")
+  _ (NO_SUCH_INTERFACE, "no such interface")                                  \
+  _ (INIT_FAILED, "init failed")
 
 #endif /* _VNET_DEV_ERRORS_H_ */