tools: move to usertools
authorThomas Monjalon <thomas.monjalon@6wind.com>
Thu, 15 Dec 2016 21:25:36 +0000 (22:25 +0100)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 4 Jan 2017 20:17:32 +0000 (21:17 +0100)
Rename tools/ into usertools/ to differentiate from buildtools/
and devtools/ while making clear these scripts are part of
DPDK runtime.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
Tested-by: Ferruh Yigit <ferruh.yigit@intel.com>
29 files changed:
MAINTAINERS
doc/guides/cryptodevs/qat.rst
doc/guides/faq/faq.rst
doc/guides/howto/lm_bond_virtio_sriov.rst
doc/guides/howto/lm_virtio_vhost_user.rst
doc/guides/linux_gsg/build_dpdk.rst
doc/guides/linux_gsg/nic_perf_intel_platform.rst
doc/guides/linux_gsg/quick_start.rst
doc/guides/nics/bnx2x.rst
doc/guides/nics/cxgbe.rst
doc/guides/nics/ena.rst
doc/guides/nics/i40e.rst
doc/guides/nics/qede.rst
doc/guides/nics/thunderx.rst
doc/guides/nics/virtio.rst
doc/guides/sample_app_ug/vhost.rst
doc/guides/testpmd_app_ug/testpmd_funcs.rst
doc/guides/xen/pkt_switch.rst
lib/librte_eal/common/eal_common_options.c
mk/rte.sdkinstall.mk
pkg/dpdk.spec
tools/cpu_layout.py [deleted file]
tools/dpdk-devbind.py [deleted file]
tools/dpdk-pmdinfo.py [deleted file]
tools/dpdk-setup.sh [deleted file]
usertools/cpu_layout.py [new file with mode: 0755]
usertools/dpdk-devbind.py [new file with mode: 0755]
usertools/dpdk-pmdinfo.py [new file with mode: 0755]
usertools/dpdk-setup.sh [new file with mode: 0755]

index f2c2607..9645c9b 100644 (file)
@@ -74,7 +74,7 @@ F: scripts/validate-abi.sh
 
 Driver information
 F: buildtools/pmdinfogen/
-F: tools/dpdk-pmdinfo.py
+F: usertools/dpdk-pmdinfo.py
 F: doc/guides/tools/pmdinfo.rst
 
 
index 52a9ae3..03d5c2d 100644 (file)
@@ -413,4 +413,4 @@ The other way to bind the VFs to the DPDK UIO driver is by using the ``dpdk-devb
 .. code-block:: console
 
     cd $RTE_SDK
-    ./tools/dpdk-devbind.py -b igb_uio 0000:03:01.1
+    ./usertools/dpdk-devbind.py -b igb_uio 0000:03:01.1
index 0adc549..5a324b2 100644 (file)
@@ -50,7 +50,7 @@ When you stop and restart the test application, it looks to see if the pages are
 If you look in the directory, you will see ``n`` number of 2M pages files. If you specified 1024, you will see 1024 page files.
 These are then placed in memory segments to get contiguous memory.
 
-If you need to change the number of pages, it is easier to first remove the pages. The tools/dpdk-setup.sh script provides an option to do this.
+If you need to change the number of pages, it is easier to first remove the pages. The usertools/dpdk-setup.sh script provides an option to do this.
 See the "Quick Start Setup Script" section in the :ref:`DPDK Getting Started Guide <linux_gsg>` for more information.
 
 
index fe9803e..169b64e 100644 (file)
@@ -613,17 +613,17 @@ Set up DPDK in the Virtual Machine
    cat  /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
 
    ifconfig -a
-   /root/dpdk/tools/dpdk-devbind.py --status
+   /root/dpdk/usertools/dpdk-devbind.py --status
 
    rmmod virtio-pci ixgbevf
 
    modprobe uio
    insmod /root/dpdk/x86_64-default-linuxapp-gcc/kmod/igb_uio.ko
 
-   /root/dpdk/tools/dpdk-devbind.py -b igb_uio 0000:00:03.0
-   /root/dpdk/tools/dpdk-devbind.py -b igb_uio 0000:00:04.0
+   /root/dpdk/usertools/dpdk-devbind.py -b igb_uio 0000:00:03.0
+   /root/dpdk/usertools/dpdk-devbind.py -b igb_uio 0000:00:04.0
 
-   /root/dpdk/tools/dpdk-devbind.py --status
+   /root/dpdk/usertools/dpdk-devbind.py --status
 
 run_testpmd_bonding_in_vm.sh
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 4937781..0a0fcfc 100644 (file)
@@ -90,14 +90,14 @@ For Fortville NIC.
 
 .. code-block:: console
 
-   cd /root/dpdk/tools
+   cd /root/dpdk/usertools
    ./dpdk-devbind.py -b igb_uio 0000:02:00.0
 
 For Niantic NIC.
 
 .. code-block:: console
 
-   cd /root/dpdk/tools
+   cd /root/dpdk/usertools
    ./dpdk-devbind.py -b igb_uio 0000:09:00.0
 
 On host_server_1: Terminal 3
@@ -171,14 +171,14 @@ For Fortville NIC.
 
 .. code-block:: console
 
-   cd /root/dpdk/tools
+   cd /root/dpdk/usertools
    ./dpdk-devbind.py -b igb_uio 0000:03:00.0
 
 For Niantic NIC.
 
 .. code-block:: console
 
-   cd /root/dpdk/tools
+   cd /root/dpdk/usertools
    ./dpdk-devbind.py -b igb_uio 0000:06:00.0
 
 On host_server_2: Terminal 3
@@ -444,17 +444,17 @@ setup_dpdk_virtio_in_vm.sh
    cat  /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
 
    ifconfig -a
-   /root/dpdk/tools/dpdk-devbind.py --status
+   /root/dpdk/usertools/dpdk-devbind.py --status
 
    rmmod virtio-pci
 
    modprobe uio
    insmod /root/dpdk/x86_64-default-linuxapp-gcc/kmod/igb_uio.ko
 
-   /root/dpdk/tools/dpdk-devbind.py -b igb_uio 0000:00:03.0
-   /root/dpdk/tools/dpdk-devbind.py -b igb_uio 0000:00:04.0
+   /root/dpdk/usertools/dpdk-devbind.py -b igb_uio 0000:00:03.0
+   /root/dpdk/usertools/dpdk-devbind.py -b igb_uio 0000:00:04.0
 
-   /root/dpdk/tools/dpdk-devbind.py --status
+   /root/dpdk/usertools/dpdk-devbind.py --status
 
 run_testpmd_in_vm.sh
 ~~~~~~~~~~~~~~~~~~~~
index 51a6210..eadade2 100644 (file)
@@ -58,7 +58,7 @@ The DPDK is composed of several directories:
 
 *   examples: Source code of DPDK application examples
 
-*   config, tools, scripts, mk: Framework-related makefiles, scripts and configuration
+*   config, buildtools, mk: Framework-related makefiles, scripts and configuration
 
 Installation of DPDK Target Environments
 ----------------------------------------
@@ -188,7 +188,7 @@ however please consult your distributions documentation to make sure that is the
 Also, to use VFIO, both kernel and BIOS must support and be configured to use IO virtualization (such as IntelĀ® VT-d).
 
 For proper operation of VFIO when running DPDK applications as a non-privileged user, correct permissions should also be set up.
-This can be done by using the DPDK setup script (called dpdk-setup.sh and located in the tools directory).
+This can be done by using the DPDK setup script (called dpdk-setup.sh and located in the usertools directory).
 
 .. _linux_gsg_binding_kernel:
 
@@ -208,7 +208,7 @@ Any network ports under Linux* control will be ignored by the DPDK poll-mode dri
 
 To bind ports to the ``uio_pci_generic``, ``igb_uio`` or ``vfio-pci`` module for DPDK use,
 and then subsequently return ports to Linux* control,
-a utility script called dpdk_nic _bind.py is provided in the tools subdirectory.
+a utility script called dpdk_nic _bind.py is provided in the usertools subdirectory.
 This utility can be used to provide a view of the current state of the network ports on the system,
 and to bind and unbind those ports from the different kernel modules, including the uio and vfio modules.
 The following are some examples of how the script can be used.
@@ -235,7 +235,7 @@ To see the status of all network ports on the system:
 
 .. code-block:: console
 
-    ./tools/dpdk-devbind.py --status
+    ./usertools/dpdk-devbind.py --status
 
     Network devices using DPDK-compatible driver
     ============================================
@@ -257,16 +257,16 @@ To bind device ``eth1``,``04:00.1``, to the ``uio_pci_generic`` driver:
 
 .. code-block:: console
 
-    ./tools/dpdk-devbind.py --bind=uio_pci_generic 04:00.1
+    ./usertools/dpdk-devbind.py --bind=uio_pci_generic 04:00.1
 
 or, alternatively,
 
 .. code-block:: console
 
-    ./tools/dpdk-devbind.py --bind=uio_pci_generic eth1
+    ./usertools/dpdk-devbind.py --bind=uio_pci_generic eth1
 
 To restore device ``82:00.0`` to its original kernel binding:
 
 .. code-block:: console
 
-    ./tools/dpdk-devbind.py --bind=ixgbe 82:00.0
+    ./usertools/dpdk-devbind.py --bind=ixgbe 82:00.0
index d4a8362..8f34faf 100644 (file)
@@ -158,7 +158,7 @@ Configurations before running DPDK
 
       cd dpdk_folder
 
-      tools/cpu_layout.py
+      usertools/cpu_layout.py
 
    Or run ``lscpu`` to check the the cores on each socket.
 
@@ -192,10 +192,10 @@ Configurations before running DPDK
 
 
       # Bind ports 82:00.0 and 85:00.0 to dpdk driver
-      ./dpdk_folder/tools/dpdk-devbind.py -b igb_uio 82:00.0 85:00.0
+      ./dpdk_folder/usertools/dpdk-devbind.py -b igb_uio 82:00.0 85:00.0
 
       # Check the port driver status
-      ./dpdk_folder/tools/dpdk-devbind.py --status
+      ./dpdk_folder/usertools/dpdk-devbind.py --status
 
    See ``dpdk-devbind.py --help`` for more details.
 
index 6e858c2..b158d0f 100644 (file)
@@ -33,7 +33,7 @@
 Quick Start Setup Script
 ========================
 
-The dpdk-setup.sh script, found in the tools subdirectory, allows the user to perform the following tasks:
+The dpdk-setup.sh script, found in the usertools subdirectory, allows the user to perform the following tasks:
 
 *   Build the DPDK libraries
 
@@ -108,7 +108,7 @@ Some options in the script prompt the user for further data before proceeding.
 
 .. code-block:: console
 
-    source tools/dpdk-setup.sh
+    source usertools/dpdk-setup.sh
 
     ------------------------------------------------------------------------
 
index 6d1768a..c011df1 100644 (file)
@@ -207,7 +207,7 @@ devices managed by ``librte_pmd_bnx2x`` in Linux operating system.
 #. Bind the QLogic adapters to ``igb_uio`` or ``vfio-pci`` loaded in the
    previous step::
 
-      ./tools/dpdk-devbind.py --bind igb_uio 0000:84:00.0 0000:84:00.1
+      ./usertools/dpdk-devbind.py --bind igb_uio 0000:84:00.0 0000:84:00.1
 
    or
 
@@ -219,7 +219,7 @@ devices managed by ``librte_pmd_bnx2x`` in Linux operating system.
 
       sudo chmod 0666 /dev/vfio/*
 
-      ./tools/dpdk-devbind.py --bind vfio-pci 0000:84:00.0 0000:84:00.1
+      ./usertools/dpdk-devbind.py --bind vfio-pci 0000:84:00.0 0000:84:00.1
 
 #. Start ``testpmd`` with basic parameters:
 
index d8236b0..7aa6953 100644 (file)
@@ -285,7 +285,7 @@ devices managed by librte_pmd_cxgbe in Linux operating system.
 
    .. code-block:: console
 
-      ./tools/dpdk-devbind.py --bind igb_uio 0000:02:00.4
+      ./usertools/dpdk-devbind.py --bind igb_uio 0000:02:00.4
 
    or
 
@@ -297,7 +297,7 @@ devices managed by librte_pmd_cxgbe in Linux operating system.
 
       sudo chmod 0666 /dev/vfio/*
 
-      ./tools/dpdk-devbind.py --bind vfio-pci 0000:02:00.4
+      ./usertools/dpdk-devbind.py --bind vfio-pci 0000:02:00.4
 
    .. note::
 
index 073b35a..c2738e8 100644 (file)
@@ -225,7 +225,7 @@ devices managed by librte_pmd_ena.
 
    .. code-block:: console
 
-      ./tools/dpdk-devbind.py --bind=igb_uio 0000:02:00.1
+      ./usertools/dpdk-devbind.py --bind=igb_uio 0000:02:00.1
 
 #. Start testpmd with basic parameters:
 
index 5780268..0cc9268 100644 (file)
@@ -164,13 +164,13 @@ devices managed by ``librte_pmd_i40e`` in the Linux operating system.
 
    .. code-block:: console
 
-      ./tools/dpdk-devbind.py --bind igb_uio 0000:83:00.0
+      ./usertools/dpdk-devbind.py --bind igb_uio 0000:83:00.0
 
    Or setup VFIO permissions for regular users and then bind to ``vfio-pci``:
 
    .. code-block:: console
 
-      ./tools/dpdk-devbind.py --bind vfio-pci 0000:83:00.0
+      ./usertools/dpdk-devbind.py --bind vfio-pci 0000:83:00.0
 
 #. Start ``testpmd`` with basic parameters:
 
index d22ecdd..9d70217 100644 (file)
@@ -175,7 +175,7 @@ devices managed by ``librte_pmd_qede`` in Linux operating system.
 
    .. code-block:: console
 
-      ./tools/dpdk-devbind.py --bind igb_uio 0000:84:00.0 0000:84:00.1 \
+      ./usertools/dpdk-devbind.py --bind igb_uio 0000:84:00.0 0000:84:00.1 \
                                               0000:84:00.2 0000:84:00.3
 
 #. Start ``testpmd`` with basic parameters:
index 187c9a4..e6ac441 100644 (file)
@@ -149,7 +149,7 @@ managed by ``librte_pmd_thunderx_nicvf`` in the Linux operating system.
 
    .. code-block:: console
 
-      ./tools/dpdk-devbind.py --bind vfio-pci 0002:01:00.2
+      ./usertools/dpdk-devbind.py --bind vfio-pci 0002:01:00.2
 
 #. Start ``testpmd`` with basic parameters:
 
@@ -253,7 +253,7 @@ This section provides instructions to configure SR-IOV with Linux OS.
 
    .. code-block:: console
 
-      ./tools/dpdk-devbind.py --status
+      ./usertools/dpdk-devbind.py --status
 
    Example output:
 
@@ -275,14 +275,14 @@ This section provides instructions to configure SR-IOV with Linux OS.
 
    .. code-block:: console
 
-      ./tools/dpdk-devbind.py --bind vfio-pci 0002:01:00.1
-      ./tools/dpdk-devbind.py --bind vfio-pci 0002:01:00.2
+      ./usertools/dpdk-devbind.py --bind vfio-pci 0002:01:00.1
+      ./usertools/dpdk-devbind.py --bind vfio-pci 0002:01:00.2
 
 #. Verify VF bind using ``dpdk-devbind.py``:
 
    .. code-block:: console
 
-      ./tools/dpdk-devbind.py --status
+      ./usertools/dpdk-devbind.py --status
 
    Example output:
 
@@ -352,7 +352,7 @@ driver' list, secondary VFs are on the remaining on the remaining part of the li
    .. note::
 
       The VNIC driver in the multiqueue setup works differently than other drivers like `ixgbe`.
-      We need to bind separately each specific queue set device with the ``tools/dpdk-devbind.py`` utility.
+      We need to bind separately each specific queue set device with the ``usertools/dpdk-devbind.py`` utility.
 
    .. note::
 
@@ -372,7 +372,7 @@ on a non-NUMA machine.
 
    .. code-block:: console
 
-      # tools/dpdk-devbind.py --status
+      # usertools/dpdk-devbind.py --status
 
       Network devices using DPDK-compatible driver
       ============================================
@@ -416,17 +416,17 @@ We will choose four secondary queue sets from the ending of the list (0002:01:01
 
    .. code-block:: console
 
-      tools/dpdk-devbind.py -b vfio-pci 0002:01:00.2
-      tools/dpdk-devbind.py -b vfio-pci 0002:01:00.3
+      usertools/dpdk-devbind.py -b vfio-pci 0002:01:00.2
+      usertools/dpdk-devbind.py -b vfio-pci 0002:01:00.3
 
 #. Bind four primary VFs to the ``vfio-pci`` driver:
 
    .. code-block:: console
 
-      tools/dpdk-devbind.py -b vfio-pci 0002:01:01.7
-      tools/dpdk-devbind.py -b vfio-pci 0002:01:02.0
-      tools/dpdk-devbind.py -b vfio-pci 0002:01:02.1
-      tools/dpdk-devbind.py -b vfio-pci 0002:01:02.2
+      usertools/dpdk-devbind.py -b vfio-pci 0002:01:01.7
+      usertools/dpdk-devbind.py -b vfio-pci 0002:01:02.0
+      usertools/dpdk-devbind.py -b vfio-pci 0002:01:02.1
+      usertools/dpdk-devbind.py -b vfio-pci 0002:01:02.2
 
 The nicvf thunderx driver will make use of attached secondary VFs automatically during the interface configuration stage.
 
index 5431015..c90e517 100644 (file)
@@ -172,7 +172,7 @@ Host2VM communication example
         modprobe uio
         echo 512 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
         modprobe uio_pci_generic
-        python tools/dpdk-devbind.py -b uio_pci_generic 00:03.0
+        python usertools/dpdk-devbind.py -b uio_pci_generic 00:03.0
 
     We use testpmd as the forwarding application in this example.
 
index 1f6d0d9..95db988 100644 (file)
@@ -115,7 +115,7 @@ could be done by:
 .. code-block:: console
 
    modprobe uio_pci_generic
-   $RTE_SDK/tools/dpdk-devbind.py -b=uio_pci_generic 0000:00:04.0
+   $RTE_SDK/usertools/dpdk-devbind.py -b=uio_pci_generic 0000:00:04.0
 
 Then start testpmd for packet forwarding testing.
 
index cacdef1..c611dc5 100644 (file)
@@ -1061,7 +1061,7 @@ For example, to move a pci device using ixgbe under DPDK management:
 .. code-block:: console
 
    # Check the status of the available devices.
-   ./tools/dpdk-devbind.py --status
+   ./usertools/dpdk-devbind.py --status
 
    Network devices using DPDK-compatible driver
    ============================================
@@ -1073,11 +1073,11 @@ For example, to move a pci device using ixgbe under DPDK management:
 
 
    # Bind the device to igb_uio.
-   sudo ./tools/dpdk-devbind.py -b igb_uio 0000:0a:00.0
+   sudo ./usertools/dpdk-devbind.py -b igb_uio 0000:0a:00.0
 
 
    # Recheck the status of the devices.
-   ./tools/dpdk-devbind.py --status
+   ./usertools/dpdk-devbind.py --status
    Network devices using DPDK-compatible driver
    ============================================
    0000:0a:00.0 '82599ES 10-Gigabit' drv=igb_uio unused=
@@ -1180,9 +1180,9 @@ For example, to move a pci device under kernel management:
 
 .. code-block:: console
 
-   sudo ./tools/dpdk-devbind.py -b ixgbe 0000:0a:00.0
+   sudo ./usertools/dpdk-devbind.py -b ixgbe 0000:0a:00.0
 
-   ./tools/dpdk-devbind.py --status
+   ./usertools/dpdk-devbind.py --status
 
    Network devices using DPDK-compatible driver
    ============================================
index a45841b..0b4ddfd 100644 (file)
@@ -323,7 +323,7 @@ Building and Running the Switching Backend
     .. code-block:: console
 
         modprobe uio_pci_generic
-        python tools/dpdk-devbind.py -b uio_pci_generic 0000:09:00:00.0
+        python usertools/dpdk-devbind.py -b uio_pci_generic 0000:09:00:00.0
 
     In this case, 0000:09:00.0 is the PCI address for the NIC controller.
 
index 611e581..f36bc55 100644 (file)
@@ -118,7 +118,7 @@ static const char *default_solib_dir = RTE_EAL_PMD_PATH;
 /*
  * Stringified version of solib path used by dpdk-pmdinfo.py
  * Note: PLEASE DO NOT ALTER THIS without making a corresponding
- * change to tools/dpdk-pmdinfo.py
+ * change to usertools/dpdk-pmdinfo.py
  */
 static const char dpdk_solib_path[] __attribute__((used)) =
 "DPDK_PLUGIN_PATH=" RTE_EAL_PMD_PATH;
index 896bc14..dbac2a2 100644 (file)
@@ -124,15 +124,11 @@ install-runtime:
            tar -xf -      -C $(DESTDIR)$(bindir) --strip-components=1 \
                --keep-newer-files
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(datadir))
-       $(Q)cp -a $(RTE_SDK)/tools $(DESTDIR)$(datadir)
-       $(Q)$(call rte_symlink,    $(DESTDIR)$(datadir)/tools/dpdk-setup.sh, \
-                                  $(DESTDIR)$(datadir)/tools/setup.sh)
-       $(Q)$(call rte_symlink,    $(DESTDIR)$(datadir)/tools/dpdk-devbind.py, \
-                                  $(DESTDIR)$(datadir)/tools/dpdk_nic_bind.py)
+       $(Q)cp -a $(RTE_SDK)/usertools $(DESTDIR)$(datadir)
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(sbindir))
-       $(Q)$(call rte_symlink,    $(DESTDIR)$(datadir)/tools/dpdk-devbind.py, \
+       $(Q)$(call rte_symlink,    $(DESTDIR)$(datadir)/usertools/dpdk-devbind.py, \
                                   $(DESTDIR)$(sbindir)/dpdk-devbind)
-       $(Q)$(call rte_symlink,    $(DESTDIR)$(datadir)/tools/dpdk-pmdinfo.py, \
+       $(Q)$(call rte_symlink,    $(DESTDIR)$(datadir)/usertools/dpdk-pmdinfo.py, \
                                   $(DESTDIR)$(bindir)/dpdk-pmdinfo)
 ifneq ($(wildcard $O/doc/man/*/*.1),)
        $(Q)$(call rte_mkdir,      $(DESTDIR)$(mandir)/man1)
index d12509a..43ff954 100644 (file)
@@ -94,7 +94,7 @@ make install O=%{target} DESTDIR=%{buildroot} \
 
 %files
 %dir %{_datadir}/dpdk
-%{_datadir}/dpdk/tools
+%{_datadir}/dpdk/usertools
 /lib/modules/%(uname -r)/extra/*
 %{_sbindir}/*
 %{_bindir}/*
diff --git a/tools/cpu_layout.py b/tools/cpu_layout.py
deleted file mode 100755 (executable)
index 0e049a6..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/env python
-
-#
-#   BSD LICENSE
-#
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-from __future__ import print_function
-import sys
-
-sockets = []
-cores = []
-core_map = {}
-
-fd = open("/proc/cpuinfo")
-lines = fd.readlines()
-fd.close()
-
-core_details = []
-core_lines = {}
-for line in lines:
-    if len(line.strip()) != 0:
-        name, value = line.split(":", 1)
-        core_lines[name.strip()] = value.strip()
-    else:
-        core_details.append(core_lines)
-        core_lines = {}
-
-for core in core_details:
-    for field in ["processor", "core id", "physical id"]:
-        if field not in core:
-            print("Error getting '%s' value from /proc/cpuinfo" % field)
-            sys.exit(1)
-        core[field] = int(core[field])
-
-    if core["core id"] not in cores:
-        cores.append(core["core id"])
-    if core["physical id"] not in sockets:
-        sockets.append(core["physical id"])
-    key = (core["physical id"], core["core id"])
-    if key not in core_map:
-        core_map[key] = []
-    core_map[key].append(core["processor"])
-
-print("============================================================")
-print("Core and Socket Information (as reported by '/proc/cpuinfo')")
-print("============================================================\n")
-print("cores = ", cores)
-print("sockets = ", sockets)
-print("")
-
-max_processor_len = len(str(len(cores) * len(sockets) * 2 - 1))
-max_core_map_len = max_processor_len * 2 + len('[, ]') + len('Socket ')
-max_core_id_len = len(str(max(cores)))
-
-output = " ".ljust(max_core_id_len + len('Core '))
-for s in sockets:
-    output += " Socket %s" % str(s).ljust(max_core_map_len - len('Socket '))
-print(output)
-
-output = " ".ljust(max_core_id_len + len('Core '))
-for s in sockets:
-    output += " --------".ljust(max_core_map_len)
-    output += " "
-print(output)
-
-for c in cores:
-    output = "Core %s" % str(c).ljust(max_core_id_len)
-    for s in sockets:
-        output += " " + str(core_map[(s, c)]).ljust(max_core_map_len)
-    print(output)
diff --git a/tools/dpdk-devbind.py b/tools/dpdk-devbind.py
deleted file mode 100755 (executable)
index e057b87..0000000
+++ /dev/null
@@ -1,652 +0,0 @@
-#! /usr/bin/env python
-#
-#   BSD LICENSE
-#
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-import sys
-import os
-import getopt
-import subprocess
-from os.path import exists, abspath, dirname, basename
-
-# The PCI base class for NETWORK devices
-NETWORK_BASE_CLASS = "02"
-CRYPTO_BASE_CLASS = "0b"
-
-# global dict ethernet devices present. Dictionary indexed by PCI address.
-# Each device within this is itself a dictionary of device properties
-devices = {}
-# list of supported DPDK drivers
-dpdk_drivers = ["igb_uio", "vfio-pci", "uio_pci_generic"]
-
-# command-line arg flags
-b_flag = None
-status_flag = False
-force_flag = False
-args = []
-
-
-def usage():
-    '''Print usage information for the program'''
-    argv0 = basename(sys.argv[0])
-    print("""
-Usage:
-------
-
-     %(argv0)s [options] DEVICE1 DEVICE2 ....
-
-where DEVICE1, DEVICE2 etc, are specified via PCI "domain:bus:slot.func" syntax
-or "bus:slot.func" syntax. For devices bound to Linux kernel drivers, they may
-also be referred to by Linux interface name e.g. eth0, eth1, em0, em1, etc.
-
-Options:
-    --help, --usage:
-        Display usage information and quit
-
-    -s, --status:
-        Print the current status of all known network and crypto devices.
-        For each device, it displays the PCI domain, bus, slot and function,
-        along with a text description of the device. Depending upon whether the
-        device is being used by a kernel driver, the igb_uio driver, or no
-        driver, other relevant information will be displayed:
-        * the Linux interface name e.g. if=eth0
-        * the driver being used e.g. drv=igb_uio
-        * any suitable drivers not currently using that device
-            e.g. unused=igb_uio
-        NOTE: if this flag is passed along with a bind/unbind option, the
-        status display will always occur after the other operations have taken
-        place.
-
-    -b driver, --bind=driver:
-        Select the driver to use or \"none\" to unbind the device
-
-    -u, --unbind:
-        Unbind a device (Equivalent to \"-b none\")
-
-    --force:
-        By default, network devices which are used by Linux - as indicated by
-        having routes in the routing table - cannot be modified. Using the
-        --force flag overrides this behavior, allowing active links to be
-        forcibly unbound.
-        WARNING: This can lead to loss of network connection and should be used
-        with caution.
-
-Examples:
----------
-
-To display current device status:
-        %(argv0)s --status
-
-To bind eth1 from the current driver and move to use igb_uio
-        %(argv0)s --bind=igb_uio eth1
-
-To unbind 0000:01:00.0 from using any driver
-        %(argv0)s -u 0000:01:00.0
-
-To bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver
-        %(argv0)s -b ixgbe 02:00.0 02:00.1
-
-    """ % locals())  # replace items from local variables
-
-
-# This is roughly compatible with check_output function in subprocess module
-# which is only available in python 2.7.
-def check_output(args, stderr=None):
-    '''Run a command and capture its output'''
-    return subprocess.Popen(args, stdout=subprocess.PIPE,
-                            stderr=stderr).communicate()[0]
-
-
-def find_module(mod):
-    '''find the .ko file for kernel module named mod.
-    Searches the $RTE_SDK/$RTE_TARGET directory, the kernel
-    modules directory and finally under the parent directory of
-    the script '''
-    # check $RTE_SDK/$RTE_TARGET directory
-    if 'RTE_SDK' in os.environ and 'RTE_TARGET' in os.environ:
-        path = "%s/%s/kmod/%s.ko" % (os.environ['RTE_SDK'],
-                                     os.environ['RTE_TARGET'], mod)
-        if exists(path):
-            return path
-
-    # check using depmod
-    try:
-        depmod_out = check_output(["modinfo", "-n", mod],
-                                  stderr=subprocess.STDOUT).lower()
-        if "error" not in depmod_out:
-            path = depmod_out.strip()
-            if exists(path):
-                return path
-    except:  # if modinfo can't find module, it fails, so continue
-        pass
-
-    # check for a copy based off current path
-    tools_dir = dirname(abspath(sys.argv[0]))
-    if tools_dir.endswith("tools"):
-        base_dir = dirname(tools_dir)
-        find_out = check_output(["find", base_dir, "-name", mod + ".ko"])
-        if len(find_out) > 0:  # something matched
-            path = find_out.splitlines()[0]
-            if exists(path):
-                return path
-
-
-def check_modules():
-    '''Checks that igb_uio is loaded'''
-    global dpdk_drivers
-
-    # list of supported modules
-    mods = [{"Name": driver, "Found": False} for driver in dpdk_drivers]
-
-    # first check if module is loaded
-    try:
-        # Get list of sysfs modules (both built-in and dynamically loaded)
-        sysfs_path = '/sys/module/'
-
-        # Get the list of directories in sysfs_path
-        sysfs_mods = [os.path.join(sysfs_path, o) for o
-                      in os.listdir(sysfs_path)
-                      if os.path.isdir(os.path.join(sysfs_path, o))]
-
-        # Extract the last element of '/sys/module/abc' in the array
-        sysfs_mods = [a.split('/')[-1] for a in sysfs_mods]
-
-        # special case for vfio_pci (module is named vfio-pci,
-        # but its .ko is named vfio_pci)
-        sysfs_mods = map(lambda a:
-                         a if a != 'vfio_pci' else 'vfio-pci', sysfs_mods)
-
-        for mod in mods:
-            if mod["Name"] in sysfs_mods:
-                mod["Found"] = True
-    except:
-        pass
-
-    # check if we have at least one loaded module
-    if True not in [mod["Found"] for mod in mods] and b_flag is not None:
-        if b_flag in dpdk_drivers:
-            print("Error - no supported modules(DPDK driver) are loaded")
-            sys.exit(1)
-        else:
-            print("Warning - no supported modules(DPDK driver) are loaded")
-
-    # change DPDK driver list to only contain drivers that are loaded
-    dpdk_drivers = [mod["Name"] for mod in mods if mod["Found"]]
-
-
-def has_driver(dev_id):
-    '''return true if a device is assigned to a driver. False otherwise'''
-    return "Driver_str" in devices[dev_id]
-
-
-def get_pci_device_details(dev_id):
-    '''This function gets additional details for a PCI device'''
-    device = {}
-
-    extra_info = check_output(["lspci", "-vmmks", dev_id]).splitlines()
-
-    # parse lspci details
-    for line in extra_info:
-        if len(line) == 0:
-            continue
-        name, value = line.decode().split("\t", 1)
-        name = name.strip(":") + "_str"
-        device[name] = value
-    # check for a unix interface name
-    device["Interface"] = ""
-    for base, dirs, _ in os.walk("/sys/bus/pci/devices/%s/" % dev_id):
-        if "net" in dirs:
-            device["Interface"] = \
-                ",".join(os.listdir(os.path.join(base, "net")))
-            break
-    # check if a port is used for ssh connection
-    device["Ssh_if"] = False
-    device["Active"] = ""
-
-    return device
-
-
-def get_nic_details():
-    '''This function populates the "devices" dictionary. The keys used are
-    the pci addresses (domain:bus:slot.func). The values are themselves
-    dictionaries - one for each NIC.'''
-    global devices
-    global dpdk_drivers
-
-    # clear any old data
-    devices = {}
-    # first loop through and read details for all devices
-    # request machine readable format, with numeric IDs
-    dev = {}
-    dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines()
-    for dev_line in dev_lines:
-        if len(dev_line) == 0:
-            if dev["Class"][0:2] == NETWORK_BASE_CLASS:
-                # convert device and vendor ids to numbers, then add to global
-                dev["Vendor"] = int(dev["Vendor"], 16)
-                dev["Device"] = int(dev["Device"], 16)
-                # use dict to make copy of dev
-                devices[dev["Slot"]] = dict(dev)
-        else:
-            name, value = dev_line.decode().split("\t", 1)
-            dev[name.rstrip(":")] = value
-
-    # check what is the interface if any for an ssh connection if
-    # any to this host, so we can mark it later.
-    ssh_if = []
-    route = check_output(["ip", "-o", "route"])
-    # filter out all lines for 169.254 routes
-    route = "\n".join(filter(lambda ln: not ln.startswith("169.254"),
-                             route.decode().splitlines()))
-    rt_info = route.split()
-    for i in range(len(rt_info) - 1):
-        if rt_info[i] == "dev":
-            ssh_if.append(rt_info[i+1])
-
-    # based on the basic info, get extended text details
-    for d in devices.keys():
-        # get additional info and add it to existing data
-        devices[d] = devices[d].copy()
-        devices[d].update(get_pci_device_details(d).items())
-
-        for _if in ssh_if:
-            if _if in devices[d]["Interface"].split(","):
-                devices[d]["Ssh_if"] = True
-                devices[d]["Active"] = "*Active*"
-                break
-
-        # add igb_uio to list of supporting modules if needed
-        if "Module_str" in devices[d]:
-            for driver in dpdk_drivers:
-                if driver not in devices[d]["Module_str"]:
-                    devices[d]["Module_str"] = \
-                        devices[d]["Module_str"] + ",%s" % driver
-        else:
-            devices[d]["Module_str"] = ",".join(dpdk_drivers)
-
-        # make sure the driver and module strings do not have any duplicates
-        if has_driver(d):
-            modules = devices[d]["Module_str"].split(",")
-            if devices[d]["Driver_str"] in modules:
-                modules.remove(devices[d]["Driver_str"])
-                devices[d]["Module_str"] = ",".join(modules)
-
-
-def get_crypto_details():
-    '''This function populates the "devices" dictionary. The keys used are
-    the pci addresses (domain:bus:slot.func). The values are themselves
-    dictionaries - one for each NIC.'''
-    global devices
-    global dpdk_drivers
-
-    # clear any old data
-    # devices = {}
-    # first loop through and read details for all devices
-    # request machine readable format, with numeric IDs
-    dev = {}
-    dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines()
-    for dev_line in dev_lines:
-        if len(dev_line) == 0:
-            if dev["Class"][0:2] == CRYPTO_BASE_CLASS:
-                # convert device and vendor ids to numbers, then add to global
-                dev["Vendor"] = int(dev["Vendor"], 16)
-                dev["Device"] = int(dev["Device"], 16)
-                # use dict to make copy of dev
-                devices[dev["Slot"]] = dict(dev)
-        else:
-            name, value = dev_line.decode().split("\t", 1)
-            dev[name.rstrip(":")] = value
-
-    # based on the basic info, get extended text details
-    for d in devices.keys():
-        # get additional info and add it to existing data
-        devices[d] = devices[d].copy()
-        devices[d].update(get_pci_device_details(d).items())
-
-        # add igb_uio to list of supporting modules if needed
-        if "Module_str" in devices[d]:
-            for driver in dpdk_drivers:
-                if driver not in devices[d]["Module_str"]:
-                    devices[d]["Module_str"] = \
-                        devices[d]["Module_str"] + ",%s" % driver
-        else:
-            devices[d]["Module_str"] = ",".join(dpdk_drivers)
-
-        # make sure the driver and module strings do not have any duplicates
-        if has_driver(d):
-            modules = devices[d]["Module_str"].split(",")
-            if devices[d]["Driver_str"] in modules:
-                modules.remove(devices[d]["Driver_str"])
-                devices[d]["Module_str"] = ",".join(modules)
-
-
-def dev_id_from_dev_name(dev_name):
-    '''Take a device "name" - a string passed in by user to identify a NIC
-    device, and determine the device id - i.e. the domain:bus:slot.func - for
-    it, which can then be used to index into the devices array'''
-
-    # check if it's already a suitable index
-    if dev_name in devices:
-        return dev_name
-    # check if it's an index just missing the domain part
-    elif "0000:" + dev_name in devices:
-        return "0000:" + dev_name
-    else:
-        # check if it's an interface name, e.g. eth1
-        for d in devices.keys():
-            if dev_name in devices[d]["Interface"].split(","):
-                return devices[d]["Slot"]
-    # if nothing else matches - error
-    print("Unknown device: %s. "
-          "Please specify device in \"bus:slot.func\" format" % dev_name)
-    sys.exit(1)
-
-
-def unbind_one(dev_id, force):
-    '''Unbind the device identified by "dev_id" from its current driver'''
-    dev = devices[dev_id]
-    if not has_driver(dev_id):
-        print("%s %s %s is not currently managed by any driver\n" %
-              (dev["Slot"], dev["Device_str"], dev["Interface"]))
-        return
-
-    # prevent us disconnecting ourselves
-    if dev["Ssh_if"] and not force:
-        print("Routing table indicates that interface %s is active. "
-              "Skipping unbind" % (dev_id))
-        return
-
-    # write to /sys to unbind
-    filename = "/sys/bus/pci/drivers/%s/unbind" % dev["Driver_str"]
-    try:
-        f = open(filename, "a")
-    except:
-        print("Error: unbind failed for %s - Cannot open %s"
-              % (dev_id, filename))
-        sys.exit(1)
-    f.write(dev_id)
-    f.close()
-
-
-def bind_one(dev_id, driver, force):
-    '''Bind the device given by "dev_id" to the driver "driver". If the device
-    is already bound to a different driver, it will be unbound first'''
-    dev = devices[dev_id]
-    saved_driver = None  # used to rollback any unbind in case of failure
-
-    # prevent disconnection of our ssh session
-    if dev["Ssh_if"] and not force:
-        print("Routing table indicates that interface %s is active. "
-              "Not modifying" % (dev_id))
-        return
-
-    # unbind any existing drivers we don't want
-    if has_driver(dev_id):
-        if dev["Driver_str"] == driver:
-            print("%s already bound to driver %s, skipping\n"
-                  % (dev_id, driver))
-            return
-        else:
-            saved_driver = dev["Driver_str"]
-            unbind_one(dev_id, force)
-            dev["Driver_str"] = ""  # clear driver string
-
-    # if we are binding to one of DPDK drivers, add PCI id's to that driver
-    if driver in dpdk_drivers:
-        filename = "/sys/bus/pci/drivers/%s/new_id" % driver
-        try:
-            f = open(filename, "w")
-        except:
-            print("Error: bind failed for %s - Cannot open %s"
-                  % (dev_id, filename))
-            return
-        try:
-            f.write("%04x %04x" % (dev["Vendor"], dev["Device"]))
-            f.close()
-        except:
-            print("Error: bind failed for %s - Cannot write new PCI ID to "
-                  "driver %s" % (dev_id, driver))
-            return
-
-    # do the bind by writing to /sys
-    filename = "/sys/bus/pci/drivers/%s/bind" % driver
-    try:
-        f = open(filename, "a")
-    except:
-        print("Error: bind failed for %s - Cannot open %s"
-              % (dev_id, filename))
-        if saved_driver is not None:  # restore any previous driver
-            bind_one(dev_id, saved_driver, force)
-        return
-    try:
-        f.write(dev_id)
-        f.close()
-    except:
-        # for some reason, closing dev_id after adding a new PCI ID to new_id
-        # results in IOError. however, if the device was successfully bound,
-        # we don't care for any errors and can safely ignore IOError
-        tmp = get_pci_device_details(dev_id)
-        if "Driver_str" in tmp and tmp["Driver_str"] == driver:
-            return
-        print("Error: bind failed for %s - Cannot bind to driver %s"
-              % (dev_id, driver))
-        if saved_driver is not None:  # restore any previous driver
-            bind_one(dev_id, saved_driver, force)
-        return
-
-
-def unbind_all(dev_list, force=False):
-    """Unbind method, takes a list of device locations"""
-    dev_list = map(dev_id_from_dev_name, dev_list)
-    for d in dev_list:
-        unbind_one(d, force)
-
-
-def bind_all(dev_list, driver, force=False):
-    """Bind method, takes a list of device locations"""
-    global devices
-
-    dev_list = map(dev_id_from_dev_name, dev_list)
-
-    for d in dev_list:
-        bind_one(d, driver, force)
-
-    # when binding devices to a generic driver (i.e. one that doesn't have a
-    # PCI ID table), some devices that are not bound to any other driver could
-    # be bound even if no one has asked them to. hence, we check the list of
-    # drivers again, and see if some of the previously-unbound devices were
-    # erroneously bound.
-    for d in devices.keys():
-        # skip devices that were already bound or that we know should be bound
-        if "Driver_str" in devices[d] or d in dev_list:
-            continue
-
-        # update information about this device
-        devices[d] = dict(devices[d].items() +
-                          get_pci_device_details(d).items())
-
-        # check if updated information indicates that the device was bound
-        if "Driver_str" in devices[d]:
-            unbind_one(d, force)
-
-
-def display_devices(title, dev_list, extra_params=None):
-    '''Displays to the user the details of a list of devices given in
-    "dev_list". The "extra_params" parameter, if given, should contain a string
-     with %()s fields in it for replacement by the named fields in each
-     device's dictionary.'''
-    strings = []  # this holds the strings to print. We sort before printing
-    print("\n%s" % title)
-    print("="*len(title))
-    if len(dev_list) == 0:
-        strings.append("<none>")
-    else:
-        for dev in dev_list:
-            if extra_params is not None:
-                strings.append("%s '%s' %s" % (dev["Slot"],
-                                               dev["Device_str"],
-                                               extra_params % dev))
-            else:
-                strings.append("%s '%s'" % (dev["Slot"], dev["Device_str"]))
-    # sort before printing, so that the entries appear in PCI order
-    strings.sort()
-    print("\n".join(strings))  # print one per line
-
-
-def show_status():
-    '''Function called when the script is passed the "--status" option.
-    Displays to the user what devices are bound to the igb_uio driver, the
-    kernel driver or to no driver'''
-    global dpdk_drivers
-    kernel_drv = []
-    dpdk_drv = []
-    no_drv = []
-
-    # split our list of network devices into the three categories above
-    for d in devices.keys():
-        if NETWORK_BASE_CLASS in devices[d]["Class"]:
-            if not has_driver(d):
-                no_drv.append(devices[d])
-                continue
-            if devices[d]["Driver_str"] in dpdk_drivers:
-                dpdk_drv.append(devices[d])
-            else:
-                kernel_drv.append(devices[d])
-
-    # print each category separately, so we can clearly see what's used by DPDK
-    display_devices("Network devices using DPDK-compatible driver", dpdk_drv,
-                    "drv=%(Driver_str)s unused=%(Module_str)s")
-    display_devices("Network devices using kernel driver", kernel_drv,
-                    "if=%(Interface)s drv=%(Driver_str)s "
-                    "unused=%(Module_str)s %(Active)s")
-    display_devices("Other network devices", no_drv, "unused=%(Module_str)s")
-
-    # split our list of crypto devices into the three categories above
-    kernel_drv = []
-    dpdk_drv = []
-    no_drv = []
-
-    for d in devices.keys():
-        if CRYPTO_BASE_CLASS in devices[d]["Class"]:
-            if not has_driver(d):
-                no_drv.append(devices[d])
-                continue
-            if devices[d]["Driver_str"] in dpdk_drivers:
-                dpdk_drv.append(devices[d])
-            else:
-                kernel_drv.append(devices[d])
-
-    display_devices("Crypto devices using DPDK-compatible driver", dpdk_drv,
-                    "drv=%(Driver_str)s unused=%(Module_str)s")
-    display_devices("Crypto devices using kernel driver", kernel_drv,
-                    "drv=%(Driver_str)s "
-                    "unused=%(Module_str)s")
-    display_devices("Other crypto devices", no_drv, "unused=%(Module_str)s")
-
-
-def parse_args():
-    '''Parses the command-line arguments given by the user and takes the
-    appropriate action for each'''
-    global b_flag
-    global status_flag
-    global force_flag
-    global args
-    if len(sys.argv) <= 1:
-        usage()
-        sys.exit(0)
-
-    try:
-        opts, args = getopt.getopt(sys.argv[1:], "b:us",
-                                   ["help", "usage", "status", "force",
-                                    "bind=", "unbind"])
-    except getopt.GetoptError as error:
-        print(str(error))
-        print("Run '%s --usage' for further information" % sys.argv[0])
-        sys.exit(1)
-
-    for opt, arg in opts:
-        if opt == "--help" or opt == "--usage":
-            usage()
-            sys.exit(0)
-        if opt == "--status" or opt == "-s":
-            status_flag = True
-        if opt == "--force":
-            force_flag = True
-        if opt == "-b" or opt == "-u" or opt == "--bind" or opt == "--unbind":
-            if b_flag is not None:
-                print("Error - Only one bind or unbind may be specified\n")
-                sys.exit(1)
-            if opt == "-u" or opt == "--unbind":
-                b_flag = "none"
-            else:
-                b_flag = arg
-
-
-def do_arg_actions():
-    '''do the actual action requested by the user'''
-    global b_flag
-    global status_flag
-    global force_flag
-    global args
-
-    if b_flag is None and not status_flag:
-        print("Error: No action specified for devices."
-              "Please give a -b or -u option")
-        print("Run '%s --usage' for further information" % sys.argv[0])
-        sys.exit(1)
-
-    if b_flag is not None and len(args) == 0:
-        print("Error: No devices specified.")
-        print("Run '%s --usage' for further information" % sys.argv[0])
-        sys.exit(1)
-
-    if b_flag == "none" or b_flag == "None":
-        unbind_all(args, force_flag)
-    elif b_flag is not None:
-        bind_all(args, b_flag, force_flag)
-    if status_flag:
-        if b_flag is not None:
-            get_nic_details()  # refresh if we have changed anything
-            get_crypto_details()  # refresh if we have changed anything
-        show_status()
-
-
-def main():
-    '''program main function'''
-    parse_args()
-    check_modules()
-    get_nic_details()
-    get_crypto_details()
-    do_arg_actions()
-
-if __name__ == "__main__":
-    main()
diff --git a/tools/dpdk-pmdinfo.py b/tools/dpdk-pmdinfo.py
deleted file mode 100755 (executable)
index 46c1be0..0000000
+++ /dev/null
@@ -1,610 +0,0 @@
-#!/usr/bin/env python
-
-# -------------------------------------------------------------------------
-#
-# Utility to dump PMD_INFO_STRING support from an object file
-#
-# -------------------------------------------------------------------------
-from __future__ import print_function
-import json
-import os
-import platform
-import string
-import sys
-from elftools.common.exceptions import ELFError
-from elftools.common.py3compat import (byte2int, bytes2str, str2bytes)
-from elftools.elf.elffile import ELFFile
-from optparse import OptionParser
-
-# For running from development directory. It should take precedence over the
-# installed pyelftools.
-sys.path.insert(0, '.')
-
-raw_output = False
-pcidb = None
-
-# ===========================================
-
-
-class Vendor:
-    """
-    Class for vendors. This is the top level class
-    for the devices belong to a specific vendor.
-    self.devices is the device dictionary
-    subdevices are in each device.
-    """
-
-    def __init__(self, vendorStr):
-        """
-        Class initializes with the raw line from pci.ids
-        Parsing takes place inside __init__
-        """
-        self.ID = vendorStr.split()[0]
-        self.name = vendorStr.replace("%s " % self.ID, "").rstrip()
-        self.devices = {}
-
-    def addDevice(self, deviceStr):
-        """
-        Adds a device to self.devices
-        takes the raw line from pci.ids
-        """
-        s = deviceStr.strip()
-        devID = s.split()[0]
-        if devID in self.devices:
-            pass
-        else:
-            self.devices[devID] = Device(deviceStr)
-
-    def report(self):
-        print(self.ID, self.name)
-        for id, dev in self.devices.items():
-            dev.report()
-
-    def find_device(self, devid):
-        # convert to a hex string and remove 0x
-        devid = hex(devid)[2:]
-        try:
-            return self.devices[devid]
-        except:
-            return Device("%s  Unknown Device" % devid)
-
-
-class Device:
-
-    def __init__(self, deviceStr):
-        """
-        Class for each device.
-        Each vendor has its own devices dictionary.
-        """
-        s = deviceStr.strip()
-        self.ID = s.split()[0]
-        self.name = s.replace("%s  " % self.ID, "")
-        self.subdevices = {}
-
-    def report(self):
-        print("\t%s\t%s" % (self.ID, self.name))
-        for subID, subdev in self.subdevices.items():
-            subdev.report()
-
-    def addSubDevice(self, subDeviceStr):
-        """
-        Adds a subvendor, subdevice to device.
-        Uses raw line from pci.ids
-        """
-        s = subDeviceStr.strip()
-        spl = s.split()
-        subVendorID = spl[0]
-        subDeviceID = spl[1]
-        subDeviceName = s.split("  ")[-1]
-        devID = "%s:%s" % (subVendorID, subDeviceID)
-        self.subdevices[devID] = SubDevice(
-            subVendorID, subDeviceID, subDeviceName)
-
-    def find_subid(self, subven, subdev):
-        subven = hex(subven)[2:]
-        subdev = hex(subdev)[2:]
-        devid = "%s:%s" % (subven, subdev)
-
-        try:
-            return self.subdevices[devid]
-        except:
-            if (subven == "ffff" and subdev == "ffff"):
-                return SubDevice("ffff", "ffff", "(All Subdevices)")
-            else:
-                return SubDevice(subven, subdev, "(Unknown Subdevice)")
-
-
-class SubDevice:
-    """
-    Class for subdevices.
-    """
-
-    def __init__(self, vendor, device, name):
-        """
-        Class initializes with vendorid, deviceid and name
-        """
-        self.vendorID = vendor
-        self.deviceID = device
-        self.name = name
-
-    def report(self):
-        print("\t\t%s\t%s\t%s" % (self.vendorID, self.deviceID, self.name))
-
-
-class PCIIds:
-    """
-    Top class for all pci.ids entries.
-    All queries will be asked to this class.
-    PCIIds.vendors["0e11"].devices["0046"].\
-    subdevices["0e11:4091"].name  =  "Smart Array 6i"
-    """
-
-    def __init__(self, filename):
-        """
-        Prepares the directories.
-        Checks local data file.
-        Tries to load from local, if not found, downloads from web
-        """
-        self.version = ""
-        self.date = ""
-        self.vendors = {}
-        self.contents = None
-        self.readLocal(filename)
-        self.parse()
-
-    def reportVendors(self):
-        """Reports the vendors
-        """
-        for vid, v in self.vendors.items():
-            print(v.ID, v.name)
-
-    def report(self, vendor=None):
-        """
-        Reports everything for all vendors or a specific vendor
-        PCIIds.report()  reports everything
-        PCIIDs.report("0e11") reports only "Compaq Computer Corporation"
-        """
-        if vendor is not None:
-            self.vendors[vendor].report()
-        else:
-            for vID, v in self.vendors.items():
-                v.report()
-
-    def find_vendor(self, vid):
-        # convert vid to a hex string and remove the 0x
-        vid = hex(vid)[2:]
-
-        try:
-            return self.vendors[vid]
-        except:
-            return Vendor("%s Unknown Vendor" % (vid))
-
-    def findDate(self, content):
-        for l in content:
-            if l.find("Date:") > -1:
-                return l.split()[-2].replace("-", "")
-        return None
-
-    def parse(self):
-        if len(self.contents) < 1:
-            print("data/%s-pci.ids not found" % self.date)
-        else:
-            vendorID = ""
-            deviceID = ""
-            for l in self.contents:
-                if l[0] == "#":
-                    continue
-                elif len(l.strip()) == 0:
-                    continue
-                else:
-                    if l.find("\t\t") == 0:
-                        self.vendors[vendorID].devices[
-                            deviceID].addSubDevice(l)
-                    elif l.find("\t") == 0:
-                        deviceID = l.strip().split()[0]
-                        self.vendors[vendorID].addDevice(l)
-                    else:
-                        vendorID = l.split()[0]
-                        self.vendors[vendorID] = Vendor(l)
-
-    def readLocal(self, filename):
-        """
-        Reads the local file
-        """
-        self.contents = open(filename).readlines()
-        self.date = self.findDate(self.contents)
-
-    def loadLocal(self):
-        """
-        Loads database from local. If there is no file,
-        it creates a new one from web
-        """
-        self.date = idsfile[0].split("/")[1].split("-")[0]
-        self.readLocal()
-
-
-# =======================================
-
-def search_file(filename, search_path):
-    """ Given a search path, find file with requested name """
-    for path in string.split(search_path, ":"):
-        candidate = os.path.join(path, filename)
-        if os.path.exists(candidate):
-            return os.path.abspath(candidate)
-    return None
-
-
-class ReadElf(object):
-    """ display_* methods are used to emit output into the output stream
-    """
-
-    def __init__(self, file, output):
-        """ file:
-                stream object with the ELF file to read
-
-            output:
-                output stream to write to
-        """
-        self.elffile = ELFFile(file)
-        self.output = output
-
-        # Lazily initialized if a debug dump is requested
-        self._dwarfinfo = None
-
-        self._versioninfo = None
-
-    def _section_from_spec(self, spec):
-        """ Retrieve a section given a "spec" (either number or name).
-            Return None if no such section exists in the file.
-        """
-        try:
-            num = int(spec)
-            if num < self.elffile.num_sections():
-                return self.elffile.get_section(num)
-            else:
-                return None
-        except ValueError:
-            # Not a number. Must be a name then
-            return self.elffile.get_section_by_name(str2bytes(spec))
-
-    def pretty_print_pmdinfo(self, pmdinfo):
-        global pcidb
-
-        for i in pmdinfo["pci_ids"]:
-            vendor = pcidb.find_vendor(i[0])
-            device = vendor.find_device(i[1])
-            subdev = device.find_subid(i[2], i[3])
-            print("%s (%s) : %s (%s) %s" %
-                  (vendor.name, vendor.ID, device.name,
-                   device.ID, subdev.name))
-
-    def parse_pmd_info_string(self, mystring):
-        global raw_output
-        global pcidb
-
-        optional_pmd_info = [
-            {'id': 'params', 'tag': 'PMD PARAMETERS'},
-            {'id': 'kmod', 'tag': 'PMD KMOD DEPENDENCIES'}
-        ]
-
-        i = mystring.index("=")
-        mystring = mystring[i + 2:]
-        pmdinfo = json.loads(mystring)
-
-        if raw_output:
-            print(json.dumps(pmdinfo))
-            return
-
-        print("PMD NAME: " + pmdinfo["name"])
-        for i in optional_pmd_info:
-            try:
-                print("%s: %s" % (i['tag'], pmdinfo[i['id']]))
-            except KeyError:
-                continue
-
-        if (len(pmdinfo["pci_ids"]) != 0):
-            print("PMD HW SUPPORT:")
-            if pcidb is not None:
-                self.pretty_print_pmdinfo(pmdinfo)
-            else:
-                print("VENDOR\t DEVICE\t SUBVENDOR\t SUBDEVICE")
-                for i in pmdinfo["pci_ids"]:
-                    print("0x%04x\t 0x%04x\t 0x%04x\t\t 0x%04x" %
-                          (i[0], i[1], i[2], i[3]))
-
-        print("")
-
-    def display_pmd_info_strings(self, section_spec):
-        """ Display a strings dump of a section. section_spec is either a
-            section number or a name.
-        """
-        section = self._section_from_spec(section_spec)
-        if section is None:
-            return
-
-        data = section.data()
-        dataptr = 0
-
-        while dataptr < len(data):
-            while (dataptr < len(data) and
-                    not (32 <= byte2int(data[dataptr]) <= 127)):
-                dataptr += 1
-
-            if dataptr >= len(data):
-                break
-
-            endptr = dataptr
-            while endptr < len(data) and byte2int(data[endptr]) != 0:
-                endptr += 1
-
-            mystring = bytes2str(data[dataptr:endptr])
-            rc = mystring.find("PMD_INFO_STRING")
-            if (rc != -1):
-                self.parse_pmd_info_string(mystring)
-
-            dataptr = endptr
-
-    def find_librte_eal(self, section):
-        for tag in section.iter_tags():
-            if tag.entry.d_tag == 'DT_NEEDED':
-                if "librte_eal" in tag.needed:
-                    return tag.needed
-        return None
-
-    def search_for_autoload_path(self):
-        scanelf = self
-        scanfile = None
-        library = None
-
-        section = self._section_from_spec(".dynamic")
-        try:
-            eallib = self.find_librte_eal(section)
-            if eallib is not None:
-                ldlibpath = os.environ.get('LD_LIBRARY_PATH')
-                if ldlibpath is None:
-                    ldlibpath = ""
-                dtr = self.get_dt_runpath(section)
-                library = search_file(eallib,
-                                      dtr + ":" + ldlibpath +
-                                      ":/usr/lib64:/lib64:/usr/lib:/lib")
-                if library is None:
-                    return (None, None)
-                if raw_output is False:
-                    print("Scanning for autoload path in %s" % library)
-                scanfile = open(library, 'rb')
-                scanelf = ReadElf(scanfile, sys.stdout)
-        except AttributeError:
-            # Not a dynamic binary
-            pass
-        except ELFError:
-            scanfile.close()
-            return (None, None)
-
-        section = scanelf._section_from_spec(".rodata")
-        if section is None:
-            if scanfile is not None:
-                scanfile.close()
-            return (None, None)
-
-        data = section.data()
-        dataptr = 0
-
-        while dataptr < len(data):
-            while (dataptr < len(data) and
-                    not (32 <= byte2int(data[dataptr]) <= 127)):
-                dataptr += 1
-
-            if dataptr >= len(data):
-                break
-
-            endptr = dataptr
-            while endptr < len(data) and byte2int(data[endptr]) != 0:
-                endptr += 1
-
-            mystring = bytes2str(data[dataptr:endptr])
-            rc = mystring.find("DPDK_PLUGIN_PATH")
-            if (rc != -1):
-                rc = mystring.find("=")
-                return (mystring[rc + 1:], library)
-
-            dataptr = endptr
-        if scanfile is not None:
-            scanfile.close()
-        return (None, None)
-
-    def get_dt_runpath(self, dynsec):
-        for tag in dynsec.iter_tags():
-            if tag.entry.d_tag == 'DT_RUNPATH':
-                return tag.runpath
-        return ""
-
-    def process_dt_needed_entries(self):
-        """ Look to see if there are any DT_NEEDED entries in the binary
-            And process those if there are
-        """
-        global raw_output
-        runpath = ""
-        ldlibpath = os.environ.get('LD_LIBRARY_PATH')
-        if ldlibpath is None:
-            ldlibpath = ""
-
-        dynsec = self._section_from_spec(".dynamic")
-        try:
-            runpath = self.get_dt_runpath(dynsec)
-        except AttributeError:
-            # dynsec is None, just return
-            return
-
-        for tag in dynsec.iter_tags():
-            if tag.entry.d_tag == 'DT_NEEDED':
-                rc = tag.needed.find(b"librte_pmd")
-                if (rc != -1):
-                    library = search_file(tag.needed,
-                                          runpath + ":" + ldlibpath +
-                                          ":/usr/lib64:/lib64:/usr/lib:/lib")
-                    if library is not None:
-                        if raw_output is False:
-                            print("Scanning %s for pmd information" % library)
-                        with open(library, 'rb') as file:
-                            try:
-                                libelf = ReadElf(file, sys.stdout)
-                            except ELFError:
-                                print("%s is no an ELF file" % library)
-                                continue
-                            libelf.process_dt_needed_entries()
-                            libelf.display_pmd_info_strings(".rodata")
-                            file.close()
-
-
-def scan_autoload_path(autoload_path):
-    global raw_output
-
-    if os.path.exists(autoload_path) is False:
-        return
-
-    try:
-        dirs = os.listdir(autoload_path)
-    except OSError:
-        # Couldn't read the directory, give up
-        return
-
-    for d in dirs:
-        dpath = os.path.join(autoload_path, d)
-        if os.path.isdir(dpath):
-            scan_autoload_path(dpath)
-        if os.path.isfile(dpath):
-            try:
-                file = open(dpath, 'rb')
-                readelf = ReadElf(file, sys.stdout)
-            except ELFError:
-                # this is likely not an elf file, skip it
-                continue
-            except IOError:
-                # No permission to read the file, skip it
-                continue
-
-            if raw_output is False:
-                print("Hw Support for library %s" % d)
-            readelf.display_pmd_info_strings(".rodata")
-            file.close()
-
-
-def scan_for_autoload_pmds(dpdk_path):
-    """
-    search the specified application or path for a pmd autoload path
-    then scan said path for pmds and report hw support
-    """
-    global raw_output
-
-    if (os.path.isfile(dpdk_path) is False):
-        if raw_output is False:
-            print("Must specify a file name")
-        return
-
-    file = open(dpdk_path, 'rb')
-    try:
-        readelf = ReadElf(file, sys.stdout)
-    except ElfError:
-        if raw_output is False:
-            print("Unable to parse %s" % file)
-        return
-
-    (autoload_path, scannedfile) = readelf.search_for_autoload_path()
-    if (autoload_path is None or autoload_path is ""):
-        if (raw_output is False):
-            print("No autoload path configured in %s" % dpdk_path)
-        return
-    if (raw_output is False):
-        if (scannedfile is None):
-            scannedfile = dpdk_path
-        print("Found autoload path %s in %s" % (autoload_path, scannedfile))
-
-    file.close()
-    if (raw_output is False):
-        print("Discovered Autoload HW Support:")
-    scan_autoload_path(autoload_path)
-    return
-
-
-def main(stream=None):
-    global raw_output
-    global pcidb
-
-    pcifile_default = "./pci.ids"  # For unknown OS's assume local file
-    if platform.system() == 'Linux':
-        pcifile_default = "/usr/share/hwdata/pci.ids"
-    elif platform.system() == 'FreeBSD':
-        pcifile_default = "/usr/local/share/pciids/pci.ids"
-        if not os.path.exists(pcifile_default):
-            pcifile_default = "/usr/share/misc/pci_vendors"
-
-    optparser = OptionParser(
-        usage='usage: %prog [-hrtp] [-d <pci id file] <elf-file>',
-        description="Dump pmd hardware support info",
-        add_help_option=True)
-    optparser.add_option('-r', '--raw',
-                         action='store_true', dest='raw_output',
-                         help='Dump raw json strings')
-    optparser.add_option("-d", "--pcidb", dest="pcifile",
-                         help="specify a pci database "
-                              "to get vendor names from",
-                         default=pcifile_default, metavar="FILE")
-    optparser.add_option("-t", "--table", dest="tblout",
-                         help="output information on hw support as a "
-                              "hex table",
-                         action='store_true')
-    optparser.add_option("-p", "--plugindir", dest="pdir",
-                         help="scan dpdk for autoload plugins",
-                         action='store_true')
-
-    options, args = optparser.parse_args()
-
-    if options.raw_output:
-        raw_output = True
-
-    if options.pcifile:
-        pcidb = PCIIds(options.pcifile)
-        if pcidb is None:
-            print("Pci DB file not found")
-            exit(1)
-
-    if options.tblout:
-        options.pcifile = None
-        pcidb = None
-
-    if (len(args) == 0):
-        optparser.print_usage()
-        exit(1)
-
-    if options.pdir is True:
-        exit(scan_for_autoload_pmds(args[0]))
-
-    ldlibpath = os.environ.get('LD_LIBRARY_PATH')
-    if (ldlibpath is None):
-        ldlibpath = ""
-
-    if (os.path.exists(args[0]) is True):
-        myelffile = args[0]
-    else:
-        myelffile = search_file(
-            args[0], ldlibpath + ":/usr/lib64:/lib64:/usr/lib:/lib")
-
-    if (myelffile is None):
-        print("File not found")
-        sys.exit(1)
-
-    with open(myelffile, 'rb') as file:
-        try:
-            readelf = ReadElf(file, sys.stdout)
-            readelf.process_dt_needed_entries()
-            readelf.display_pmd_info_strings(".rodata")
-            sys.exit(0)
-
-        except ELFError as ex:
-            sys.stderr.write('ELF error: %s\n' % ex)
-            sys.exit(1)
-
-
-# -------------------------------------------------------------------------
-if __name__ == '__main__':
-    main()
diff --git a/tools/dpdk-setup.sh b/tools/dpdk-setup.sh
deleted file mode 100755 (executable)
index 14ed590..0000000
+++ /dev/null
@@ -1,634 +0,0 @@
-#! /bin/bash
-
-#   BSD LICENSE
-#
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#
-# Run with "source /path/to/dpdk-setup.sh"
-#
-
-#
-# Change to DPDK directory ( <this-script's-dir>/.. ), and export it as RTE_SDK
-#
-cd $(dirname ${BASH_SOURCE[0]})/..
-export RTE_SDK=$PWD
-echo "------------------------------------------------------------------------------"
-echo " RTE_SDK exported as $RTE_SDK"
-echo "------------------------------------------------------------------------------"
-
-HUGEPGSZ=`cat /proc/meminfo  | grep Hugepagesize | cut -d : -f 2 | tr -d ' '`
-
-#
-# Application EAL parameters for setting memory options (amount/channels/ranks).
-#
-EAL_PARAMS='-n 4'
-
-#
-# Sets QUIT variable so script will finish.
-#
-quit()
-{
-       QUIT=$1
-}
-
-# Shortcut for quit.
-q()
-{
-       quit
-}
-
-#
-# Sets up environmental variables for ICC.
-#
-setup_icc()
-{
-       DEFAULT_PATH=/opt/intel/bin/iccvars.sh
-       param=$1
-       shpath=`which iccvars.sh 2> /dev/null`
-       if [ $? -eq 0 ] ; then
-               echo "Loading iccvars.sh from $shpath for $param"
-               source $shpath $param
-       elif [ -f $DEFAULT_PATH ] ; then
-               echo "Loading iccvars.sh from $DEFAULT_PATH for $param"
-               source $DEFAULT_PATH $param
-       else
-               echo "## ERROR: cannot find 'iccvars.sh' script to set up ICC."
-               echo "##     To fix, please add the directory that contains"
-               echo "##     iccvars.sh  to your 'PATH' environment variable."
-               quit
-       fi
-}
-
-#
-# Sets RTE_TARGET and does a "make install".
-#
-setup_target()
-{
-       option=$1
-       export RTE_TARGET=${TARGETS[option]}
-
-       compiler=${RTE_TARGET##*-}
-       if [ "$compiler" == "icc" ] ; then
-               platform=${RTE_TARGET%%-*}
-               if [ "$platform" == "x86_64" ] ; then
-                       setup_icc intel64
-               else
-                       setup_icc ia32
-               fi
-       fi
-       if [ "$QUIT" == "0" ] ; then
-               make install T=${RTE_TARGET}
-       fi
-       echo "------------------------------------------------------------------------------"
-       echo " RTE_TARGET exported as $RTE_TARGET"
-       echo "------------------------------------------------------------------------------"
-}
-
-#
-# Creates hugepage filesystem.
-#
-create_mnt_huge()
-{
-       echo "Creating /mnt/huge and mounting as hugetlbfs"
-       sudo mkdir -p /mnt/huge
-
-       grep -s '/mnt/huge' /proc/mounts > /dev/null
-       if [ $? -ne 0 ] ; then
-               sudo mount -t hugetlbfs nodev /mnt/huge
-       fi
-}
-
-#
-# Removes hugepage filesystem.
-#
-remove_mnt_huge()
-{
-       echo "Unmounting /mnt/huge and removing directory"
-       grep -s '/mnt/huge' /proc/mounts > /dev/null
-       if [ $? -eq 0 ] ; then
-               sudo umount /mnt/huge
-       fi
-
-       if [ -d /mnt/huge ] ; then
-               sudo rm -R /mnt/huge
-       fi
-}
-
-#
-# Unloads igb_uio.ko.
-#
-remove_igb_uio_module()
-{
-       echo "Unloading any existing DPDK UIO module"
-       /sbin/lsmod | grep -s igb_uio > /dev/null
-       if [ $? -eq 0 ] ; then
-               sudo /sbin/rmmod igb_uio
-       fi
-}
-
-#
-# Loads new igb_uio.ko (and uio module if needed).
-#
-load_igb_uio_module()
-{
-       if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko ];then
-               echo "## ERROR: Target does not have the DPDK UIO Kernel Module."
-               echo "       To fix, please try to rebuild target."
-               return
-       fi
-
-       remove_igb_uio_module
-
-       /sbin/lsmod | grep -s uio > /dev/null
-       if [ $? -ne 0 ] ; then
-               modinfo uio > /dev/null
-               if [ $? -eq 0 ]; then
-                       echo "Loading uio module"
-                       sudo /sbin/modprobe uio
-               fi
-       fi
-
-       # UIO may be compiled into kernel, so it may not be an error if it can't
-       # be loaded.
-
-       echo "Loading DPDK UIO module"
-       sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko
-       if [ $? -ne 0 ] ; then
-               echo "## ERROR: Could not load kmod/igb_uio.ko."
-               quit
-       fi
-}
-
-#
-# Unloads VFIO modules.
-#
-remove_vfio_module()
-{
-       echo "Unloading any existing VFIO module"
-       /sbin/lsmod | grep -s vfio > /dev/null
-       if [ $? -eq 0 ] ; then
-               sudo /sbin/rmmod vfio-pci
-               sudo /sbin/rmmod vfio_iommu_type1
-               sudo /sbin/rmmod vfio
-       fi
-}
-
-#
-# Loads new vfio-pci (and vfio module if needed).
-#
-load_vfio_module()
-{
-       remove_vfio_module
-
-       VFIO_PATH="kernel/drivers/vfio/pci/vfio-pci.ko"
-
-       echo "Loading VFIO module"
-       /sbin/lsmod | grep -s vfio_pci > /dev/null
-       if [ $? -ne 0 ] ; then
-               if [ -f /lib/modules/$(uname -r)/$VFIO_PATH ] ; then
-                       sudo /sbin/modprobe vfio-pci
-               fi
-       fi
-
-       # make sure regular users can read /dev/vfio
-       echo "chmod /dev/vfio"
-       sudo chmod a+x /dev/vfio
-       if [ $? -ne 0 ] ; then
-               echo "FAIL"
-               quit
-       fi
-       echo "OK"
-
-       # check if /dev/vfio/vfio exists - that way we
-       # know we either loaded the module, or it was
-       # compiled into the kernel
-       if [ ! -e /dev/vfio/vfio ] ; then
-               echo "## ERROR: VFIO not found!"
-       fi
-}
-
-#
-# Unloads the rte_kni.ko module.
-#
-remove_kni_module()
-{
-       echo "Unloading any existing DPDK KNI module"
-       /sbin/lsmod | grep -s rte_kni > /dev/null
-       if [ $? -eq 0 ] ; then
-               sudo /sbin/rmmod rte_kni
-       fi
-}
-
-#
-# Loads the rte_kni.ko module.
-#
-load_kni_module()
-{
-    # Check that the KNI module is already built.
-       if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko ];then
-               echo "## ERROR: Target does not have the DPDK KNI Module."
-               echo "       To fix, please try to rebuild target."
-               return
-       fi
-
-    # Unload existing version if present.
-       remove_kni_module
-
-    # Now try load the KNI module.
-       echo "Loading DPDK KNI module"
-       sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko
-       if [ $? -ne 0 ] ; then
-               echo "## ERROR: Could not load kmod/rte_kni.ko."
-               quit
-       fi
-}
-
-#
-# Sets appropriate permissions on /dev/vfio/* files
-#
-set_vfio_permissions()
-{
-       # make sure regular users can read /dev/vfio
-       echo "chmod /dev/vfio"
-       sudo chmod a+x /dev/vfio
-       if [ $? -ne 0 ] ; then
-               echo "FAIL"
-               quit
-       fi
-       echo "OK"
-
-       # make sure regular user can access everything inside /dev/vfio
-       echo "chmod /dev/vfio/*"
-       sudo chmod 0666 /dev/vfio/*
-       if [ $? -ne 0 ] ; then
-               echo "FAIL"
-               quit
-       fi
-       echo "OK"
-
-       # since permissions are only to be set when running as
-       # regular user, we only check ulimit here
-       #
-       # warn if regular user is only allowed
-       # to memlock <64M of memory
-       MEMLOCK_AMNT=`ulimit -l`
-
-       if [ "$MEMLOCK_AMNT" != "unlimited" ] ; then
-               MEMLOCK_MB=`expr $MEMLOCK_AMNT / 1024`
-               echo ""
-               echo "Current user memlock limit: ${MEMLOCK_MB} MB"
-               echo ""
-               echo "This is the maximum amount of memory you will be"
-               echo "able to use with DPDK and VFIO if run as current user."
-               echo -n "To change this, please adjust limits.conf memlock "
-               echo "limit for current user."
-
-               if [ $MEMLOCK_AMNT -lt 65536 ] ; then
-                       echo ""
-                       echo "## WARNING: memlock limit is less than 64MB"
-                       echo -n "## DPDK with VFIO may not be able to initialize "
-                       echo "if run as current user."
-               fi
-       fi
-}
-
-#
-# Removes all reserved hugepages.
-#
-clear_huge_pages()
-{
-       echo > .echo_tmp
-       for d in /sys/devices/system/node/node? ; do
-               echo "echo 0 > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp
-       done
-       echo "Removing currently reserved hugepages"
-       sudo sh .echo_tmp
-       rm -f .echo_tmp
-
-       remove_mnt_huge
-}
-
-#
-# Creates hugepages.
-#
-set_non_numa_pages()
-{
-       clear_huge_pages
-
-       echo ""
-       echo "  Input the number of ${HUGEPGSZ} hugepages"
-       echo "  Example: to have 128MB of hugepages available in a 2MB huge page system,"
-       echo "  enter '64' to reserve 64 * 2MB pages"
-       echo -n "Number of pages: "
-       read Pages
-
-       echo "echo $Pages > /sys/kernel/mm/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" > .echo_tmp
-
-       echo "Reserving hugepages"
-       sudo sh .echo_tmp
-       rm -f .echo_tmp
-
-       create_mnt_huge
-}
-
-#
-# Creates hugepages on specific NUMA nodes.
-#
-set_numa_pages()
-{
-       clear_huge_pages
-
-       echo ""
-       echo "  Input the number of ${HUGEPGSZ} hugepages for each node"
-       echo "  Example: to have 128MB of hugepages available per node in a 2MB huge page system,"
-       echo "  enter '64' to reserve 64 * 2MB pages on each node"
-
-       echo > .echo_tmp
-       for d in /sys/devices/system/node/node? ; do
-               node=$(basename $d)
-               echo -n "Number of pages for $node: "
-               read Pages
-               echo "echo $Pages > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp
-       done
-       echo "Reserving hugepages"
-       sudo sh .echo_tmp
-       rm -f .echo_tmp
-
-       create_mnt_huge
-}
-
-#
-# Run unit test application.
-#
-run_test_app()
-{
-       echo ""
-       echo "  Enter hex bitmask of cores to execute test app on"
-       echo "  Example: to execute app on cores 0 to 7, enter 0xff"
-       echo -n "bitmask: "
-       read Bitmask
-       echo "Launching app"
-       sudo ${RTE_TARGET}/app/test -c $Bitmask $EAL_PARAMS
-}
-
-#
-# Run unit testpmd application.
-#
-run_testpmd_app()
-{
-       echo ""
-       echo "  Enter hex bitmask of cores to execute testpmd app on"
-       echo "  Example: to execute app on cores 0 to 7, enter 0xff"
-       echo -n "bitmask: "
-       read Bitmask
-       echo "Launching app"
-       sudo ${RTE_TARGET}/app/testpmd -c $Bitmask $EAL_PARAMS -- -i
-}
-
-#
-# Print hugepage information.
-#
-grep_meminfo()
-{
-       grep -i huge /proc/meminfo
-}
-
-#
-# Calls dpdk-devbind.py --status to show the devices and what they
-# are all bound to, in terms of drivers.
-#
-show_devices()
-{
-       if [ -d /sys/module/vfio_pci -o -d /sys/module/igb_uio ]; then
-               ${RTE_SDK}/tools/dpdk-devbind.py --status
-       else
-               echo "# Please load the 'igb_uio' or 'vfio-pci' kernel module before "
-               echo "# querying or adjusting device bindings"
-       fi
-}
-
-#
-# Uses dpdk-devbind.py to move devices to work with vfio-pci
-#
-bind_devices_to_vfio()
-{
-       if [ -d /sys/module/vfio_pci ]; then
-               ${RTE_SDK}/tools/dpdk-devbind.py --status
-               echo ""
-               echo -n "Enter PCI address of device to bind to VFIO driver: "
-               read PCI_PATH
-               sudo ${RTE_SDK}/tools/dpdk-devbind.py -b vfio-pci $PCI_PATH &&
-                       echo "OK"
-       else
-               echo "# Please load the 'vfio-pci' kernel module before querying or "
-               echo "# adjusting device bindings"
-       fi
-}
-
-#
-# Uses dpdk-devbind.py to move devices to work with igb_uio
-#
-bind_devices_to_igb_uio()
-{
-       if [ -d /sys/module/igb_uio ]; then
-               ${RTE_SDK}/tools/dpdk-devbind.py --status
-               echo ""
-               echo -n "Enter PCI address of device to bind to IGB UIO driver: "
-               read PCI_PATH
-               sudo ${RTE_SDK}/tools/dpdk-devbind.py -b igb_uio $PCI_PATH && echo "OK"
-       else
-               echo "# Please load the 'igb_uio' kernel module before querying or "
-               echo "# adjusting device bindings"
-       fi
-}
-
-#
-# Uses dpdk-devbind.py to move devices to work with kernel drivers again
-#
-unbind_devices()
-{
-       ${RTE_SDK}/tools/dpdk-devbind.py --status
-       echo ""
-       echo -n "Enter PCI address of device to unbind: "
-       read PCI_PATH
-       echo ""
-       echo -n "Enter name of kernel driver to bind the device to: "
-       read DRV
-       sudo ${RTE_SDK}/tools/dpdk-devbind.py -b $DRV $PCI_PATH && echo "OK"
-}
-
-#
-# Options for building a target. Note that this step MUST be first as it sets
-# up TARGETS[] starting from 1, and this is accessed in setup_target using the
-# user entered option.
-#
-step1_func()
-{
-       TITLE="Select the DPDK environment to build"
-       CONFIG_NUM=1
-       for cfg in config/defconfig_* ; do
-               cfg=${cfg/config\/defconfig_/}
-               TEXT[$CONFIG_NUM]="$cfg"
-               TARGETS[$CONFIG_NUM]=$cfg
-               FUNC[$CONFIG_NUM]="setup_target"
-               let "CONFIG_NUM+=1"
-       done
-}
-
-#
-# Options for setting up environment.
-#
-step2_func()
-{
-       TITLE="Setup linuxapp environment"
-
-       TEXT[1]="Insert IGB UIO module"
-       FUNC[1]="load_igb_uio_module"
-
-       TEXT[2]="Insert VFIO module"
-       FUNC[2]="load_vfio_module"
-
-       TEXT[3]="Insert KNI module"
-       FUNC[3]="load_kni_module"
-
-       TEXT[4]="Setup hugepage mappings for non-NUMA systems"
-       FUNC[4]="set_non_numa_pages"
-
-       TEXT[5]="Setup hugepage mappings for NUMA systems"
-       FUNC[5]="set_numa_pages"
-
-       TEXT[6]="Display current Ethernet/Crypto device settings"
-       FUNC[6]="show_devices"
-
-       TEXT[7]="Bind Ethernet/Crypto device to IGB UIO module"
-       FUNC[7]="bind_devices_to_igb_uio"
-
-       TEXT[8]="Bind Ethernet/Crypto device to VFIO module"
-       FUNC[8]="bind_devices_to_vfio"
-
-       TEXT[9]="Setup VFIO permissions"
-       FUNC[9]="set_vfio_permissions"
-}
-
-#
-# Options for running applications.
-#
-step3_func()
-{
-       TITLE="Run test application for linuxapp environment"
-
-       TEXT[1]="Run test application (\$RTE_TARGET/app/test)"
-       FUNC[1]="run_test_app"
-
-       TEXT[2]="Run testpmd application in interactive mode (\$RTE_TARGET/app/testpmd)"
-       FUNC[2]="run_testpmd_app"
-}
-
-#
-# Other options
-#
-step4_func()
-{
-       TITLE="Other tools"
-
-       TEXT[1]="List hugepage info from /proc/meminfo"
-       FUNC[1]="grep_meminfo"
-
-}
-
-#
-# Options for cleaning up the system
-#
-step5_func()
-{
-       TITLE="Uninstall and system cleanup"
-
-       TEXT[1]="Unbind devices from IGB UIO or VFIO driver"
-       FUNC[1]="unbind_devices"
-
-       TEXT[2]="Remove IGB UIO module"
-       FUNC[2]="remove_igb_uio_module"
-
-       TEXT[3]="Remove VFIO module"
-       FUNC[3]="remove_vfio_module"
-
-       TEXT[4]="Remove KNI module"
-       FUNC[4]="remove_kni_module"
-
-       TEXT[5]="Remove hugepage mappings"
-       FUNC[5]="clear_huge_pages"
-}
-
-STEPS[1]="step1_func"
-STEPS[2]="step2_func"
-STEPS[3]="step3_func"
-STEPS[4]="step4_func"
-STEPS[5]="step5_func"
-
-QUIT=0
-
-while [ "$QUIT" == "0" ]; do
-       OPTION_NUM=1
-
-       for s in $(seq ${#STEPS[@]}) ; do
-               ${STEPS[s]}
-
-               echo "----------------------------------------------------------"
-               echo " Step $s: ${TITLE}"
-               echo "----------------------------------------------------------"
-
-               for i in $(seq ${#TEXT[@]}) ; do
-                       echo "[$OPTION_NUM] ${TEXT[i]}"
-                       OPTIONS[$OPTION_NUM]=${FUNC[i]}
-                       let "OPTION_NUM+=1"
-               done
-
-               # Clear TEXT and FUNC arrays before next step
-               unset TEXT
-               unset FUNC
-
-               echo ""
-       done
-
-       echo "[$OPTION_NUM] Exit Script"
-       OPTIONS[$OPTION_NUM]="quit"
-       echo ""
-       echo -n "Option: "
-       read our_entry
-       echo ""
-       ${OPTIONS[our_entry]} ${our_entry}
-
-       if [ "$QUIT" == "0" ] ; then
-               echo
-               echo -n "Press enter to continue ..."; read
-       fi
-
-done
diff --git a/usertools/cpu_layout.py b/usertools/cpu_layout.py
new file mode 100755 (executable)
index 0000000..0e049a6
--- /dev/null
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+#
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+from __future__ import print_function
+import sys
+
+sockets = []
+cores = []
+core_map = {}
+
+fd = open("/proc/cpuinfo")
+lines = fd.readlines()
+fd.close()
+
+core_details = []
+core_lines = {}
+for line in lines:
+    if len(line.strip()) != 0:
+        name, value = line.split(":", 1)
+        core_lines[name.strip()] = value.strip()
+    else:
+        core_details.append(core_lines)
+        core_lines = {}
+
+for core in core_details:
+    for field in ["processor", "core id", "physical id"]:
+        if field not in core:
+            print("Error getting '%s' value from /proc/cpuinfo" % field)
+            sys.exit(1)
+        core[field] = int(core[field])
+
+    if core["core id"] not in cores:
+        cores.append(core["core id"])
+    if core["physical id"] not in sockets:
+        sockets.append(core["physical id"])
+    key = (core["physical id"], core["core id"])
+    if key not in core_map:
+        core_map[key] = []
+    core_map[key].append(core["processor"])
+
+print("============================================================")
+print("Core and Socket Information (as reported by '/proc/cpuinfo')")
+print("============================================================\n")
+print("cores = ", cores)
+print("sockets = ", sockets)
+print("")
+
+max_processor_len = len(str(len(cores) * len(sockets) * 2 - 1))
+max_core_map_len = max_processor_len * 2 + len('[, ]') + len('Socket ')
+max_core_id_len = len(str(max(cores)))
+
+output = " ".ljust(max_core_id_len + len('Core '))
+for s in sockets:
+    output += " Socket %s" % str(s).ljust(max_core_map_len - len('Socket '))
+print(output)
+
+output = " ".ljust(max_core_id_len + len('Core '))
+for s in sockets:
+    output += " --------".ljust(max_core_map_len)
+    output += " "
+print(output)
+
+for c in cores:
+    output = "Core %s" % str(c).ljust(max_core_id_len)
+    for s in sockets:
+        output += " " + str(core_map[(s, c)]).ljust(max_core_map_len)
+    print(output)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
new file mode 100755 (executable)
index 0000000..e057b87
--- /dev/null
@@ -0,0 +1,652 @@
+#! /usr/bin/env python
+#
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+import sys
+import os
+import getopt
+import subprocess
+from os.path import exists, abspath, dirname, basename
+
+# The PCI base class for NETWORK devices
+NETWORK_BASE_CLASS = "02"
+CRYPTO_BASE_CLASS = "0b"
+
+# global dict ethernet devices present. Dictionary indexed by PCI address.
+# Each device within this is itself a dictionary of device properties
+devices = {}
+# list of supported DPDK drivers
+dpdk_drivers = ["igb_uio", "vfio-pci", "uio_pci_generic"]
+
+# command-line arg flags
+b_flag = None
+status_flag = False
+force_flag = False
+args = []
+
+
+def usage():
+    '''Print usage information for the program'''
+    argv0 = basename(sys.argv[0])
+    print("""
+Usage:
+------
+
+     %(argv0)s [options] DEVICE1 DEVICE2 ....
+
+where DEVICE1, DEVICE2 etc, are specified via PCI "domain:bus:slot.func" syntax
+or "bus:slot.func" syntax. For devices bound to Linux kernel drivers, they may
+also be referred to by Linux interface name e.g. eth0, eth1, em0, em1, etc.
+
+Options:
+    --help, --usage:
+        Display usage information and quit
+
+    -s, --status:
+        Print the current status of all known network and crypto devices.
+        For each device, it displays the PCI domain, bus, slot and function,
+        along with a text description of the device. Depending upon whether the
+        device is being used by a kernel driver, the igb_uio driver, or no
+        driver, other relevant information will be displayed:
+        * the Linux interface name e.g. if=eth0
+        * the driver being used e.g. drv=igb_uio
+        * any suitable drivers not currently using that device
+            e.g. unused=igb_uio
+        NOTE: if this flag is passed along with a bind/unbind option, the
+        status display will always occur after the other operations have taken
+        place.
+
+    -b driver, --bind=driver:
+        Select the driver to use or \"none\" to unbind the device
+
+    -u, --unbind:
+        Unbind a device (Equivalent to \"-b none\")
+
+    --force:
+        By default, network devices which are used by Linux - as indicated by
+        having routes in the routing table - cannot be modified. Using the
+        --force flag overrides this behavior, allowing active links to be
+        forcibly unbound.
+        WARNING: This can lead to loss of network connection and should be used
+        with caution.
+
+Examples:
+---------
+
+To display current device status:
+        %(argv0)s --status
+
+To bind eth1 from the current driver and move to use igb_uio
+        %(argv0)s --bind=igb_uio eth1
+
+To unbind 0000:01:00.0 from using any driver
+        %(argv0)s -u 0000:01:00.0
+
+To bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver
+        %(argv0)s -b ixgbe 02:00.0 02:00.1
+
+    """ % locals())  # replace items from local variables
+
+
+# This is roughly compatible with check_output function in subprocess module
+# which is only available in python 2.7.
+def check_output(args, stderr=None):
+    '''Run a command and capture its output'''
+    return subprocess.Popen(args, stdout=subprocess.PIPE,
+                            stderr=stderr).communicate()[0]
+
+
+def find_module(mod):
+    '''find the .ko file for kernel module named mod.
+    Searches the $RTE_SDK/$RTE_TARGET directory, the kernel
+    modules directory and finally under the parent directory of
+    the script '''
+    # check $RTE_SDK/$RTE_TARGET directory
+    if 'RTE_SDK' in os.environ and 'RTE_TARGET' in os.environ:
+        path = "%s/%s/kmod/%s.ko" % (os.environ['RTE_SDK'],
+                                     os.environ['RTE_TARGET'], mod)
+        if exists(path):
+            return path
+
+    # check using depmod
+    try:
+        depmod_out = check_output(["modinfo", "-n", mod],
+                                  stderr=subprocess.STDOUT).lower()
+        if "error" not in depmod_out:
+            path = depmod_out.strip()
+            if exists(path):
+                return path
+    except:  # if modinfo can't find module, it fails, so continue
+        pass
+
+    # check for a copy based off current path
+    tools_dir = dirname(abspath(sys.argv[0]))
+    if tools_dir.endswith("tools"):
+        base_dir = dirname(tools_dir)
+        find_out = check_output(["find", base_dir, "-name", mod + ".ko"])
+        if len(find_out) > 0:  # something matched
+            path = find_out.splitlines()[0]
+            if exists(path):
+                return path
+
+
+def check_modules():
+    '''Checks that igb_uio is loaded'''
+    global dpdk_drivers
+
+    # list of supported modules
+    mods = [{"Name": driver, "Found": False} for driver in dpdk_drivers]
+
+    # first check if module is loaded
+    try:
+        # Get list of sysfs modules (both built-in and dynamically loaded)
+        sysfs_path = '/sys/module/'
+
+        # Get the list of directories in sysfs_path
+        sysfs_mods = [os.path.join(sysfs_path, o) for o
+                      in os.listdir(sysfs_path)
+                      if os.path.isdir(os.path.join(sysfs_path, o))]
+
+        # Extract the last element of '/sys/module/abc' in the array
+        sysfs_mods = [a.split('/')[-1] for a in sysfs_mods]
+
+        # special case for vfio_pci (module is named vfio-pci,
+        # but its .ko is named vfio_pci)
+        sysfs_mods = map(lambda a:
+                         a if a != 'vfio_pci' else 'vfio-pci', sysfs_mods)
+
+        for mod in mods:
+            if mod["Name"] in sysfs_mods:
+                mod["Found"] = True
+    except:
+        pass
+
+    # check if we have at least one loaded module
+    if True not in [mod["Found"] for mod in mods] and b_flag is not None:
+        if b_flag in dpdk_drivers:
+            print("Error - no supported modules(DPDK driver) are loaded")
+            sys.exit(1)
+        else:
+            print("Warning - no supported modules(DPDK driver) are loaded")
+
+    # change DPDK driver list to only contain drivers that are loaded
+    dpdk_drivers = [mod["Name"] for mod in mods if mod["Found"]]
+
+
+def has_driver(dev_id):
+    '''return true if a device is assigned to a driver. False otherwise'''
+    return "Driver_str" in devices[dev_id]
+
+
+def get_pci_device_details(dev_id):
+    '''This function gets additional details for a PCI device'''
+    device = {}
+
+    extra_info = check_output(["lspci", "-vmmks", dev_id]).splitlines()
+
+    # parse lspci details
+    for line in extra_info:
+        if len(line) == 0:
+            continue
+        name, value = line.decode().split("\t", 1)
+        name = name.strip(":") + "_str"
+        device[name] = value
+    # check for a unix interface name
+    device["Interface"] = ""
+    for base, dirs, _ in os.walk("/sys/bus/pci/devices/%s/" % dev_id):
+        if "net" in dirs:
+            device["Interface"] = \
+                ",".join(os.listdir(os.path.join(base, "net")))
+            break
+    # check if a port is used for ssh connection
+    device["Ssh_if"] = False
+    device["Active"] = ""
+
+    return device
+
+
+def get_nic_details():
+    '''This function populates the "devices" dictionary. The keys used are
+    the pci addresses (domain:bus:slot.func). The values are themselves
+    dictionaries - one for each NIC.'''
+    global devices
+    global dpdk_drivers
+
+    # clear any old data
+    devices = {}
+    # first loop through and read details for all devices
+    # request machine readable format, with numeric IDs
+    dev = {}
+    dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines()
+    for dev_line in dev_lines:
+        if len(dev_line) == 0:
+            if dev["Class"][0:2] == NETWORK_BASE_CLASS:
+                # convert device and vendor ids to numbers, then add to global
+                dev["Vendor"] = int(dev["Vendor"], 16)
+                dev["Device"] = int(dev["Device"], 16)
+                # use dict to make copy of dev
+                devices[dev["Slot"]] = dict(dev)
+        else:
+            name, value = dev_line.decode().split("\t", 1)
+            dev[name.rstrip(":")] = value
+
+    # check what is the interface if any for an ssh connection if
+    # any to this host, so we can mark it later.
+    ssh_if = []
+    route = check_output(["ip", "-o", "route"])
+    # filter out all lines for 169.254 routes
+    route = "\n".join(filter(lambda ln: not ln.startswith("169.254"),
+                             route.decode().splitlines()))
+    rt_info = route.split()
+    for i in range(len(rt_info) - 1):
+        if rt_info[i] == "dev":
+            ssh_if.append(rt_info[i+1])
+
+    # based on the basic info, get extended text details
+    for d in devices.keys():
+        # get additional info and add it to existing data
+        devices[d] = devices[d].copy()
+        devices[d].update(get_pci_device_details(d).items())
+
+        for _if in ssh_if:
+            if _if in devices[d]["Interface"].split(","):
+                devices[d]["Ssh_if"] = True
+                devices[d]["Active"] = "*Active*"
+                break
+
+        # add igb_uio to list of supporting modules if needed
+        if "Module_str" in devices[d]:
+            for driver in dpdk_drivers:
+                if driver not in devices[d]["Module_str"]:
+                    devices[d]["Module_str"] = \
+                        devices[d]["Module_str"] + ",%s" % driver
+        else:
+            devices[d]["Module_str"] = ",".join(dpdk_drivers)
+
+        # make sure the driver and module strings do not have any duplicates
+        if has_driver(d):
+            modules = devices[d]["Module_str"].split(",")
+            if devices[d]["Driver_str"] in modules:
+                modules.remove(devices[d]["Driver_str"])
+                devices[d]["Module_str"] = ",".join(modules)
+
+
+def get_crypto_details():
+    '''This function populates the "devices" dictionary. The keys used are
+    the pci addresses (domain:bus:slot.func). The values are themselves
+    dictionaries - one for each NIC.'''
+    global devices
+    global dpdk_drivers
+
+    # clear any old data
+    # devices = {}
+    # first loop through and read details for all devices
+    # request machine readable format, with numeric IDs
+    dev = {}
+    dev_lines = check_output(["lspci", "-Dvmmn"]).splitlines()
+    for dev_line in dev_lines:
+        if len(dev_line) == 0:
+            if dev["Class"][0:2] == CRYPTO_BASE_CLASS:
+                # convert device and vendor ids to numbers, then add to global
+                dev["Vendor"] = int(dev["Vendor"], 16)
+                dev["Device"] = int(dev["Device"], 16)
+                # use dict to make copy of dev
+                devices[dev["Slot"]] = dict(dev)
+        else:
+            name, value = dev_line.decode().split("\t", 1)
+            dev[name.rstrip(":")] = value
+
+    # based on the basic info, get extended text details
+    for d in devices.keys():
+        # get additional info and add it to existing data
+        devices[d] = devices[d].copy()
+        devices[d].update(get_pci_device_details(d).items())
+
+        # add igb_uio to list of supporting modules if needed
+        if "Module_str" in devices[d]:
+            for driver in dpdk_drivers:
+                if driver not in devices[d]["Module_str"]:
+                    devices[d]["Module_str"] = \
+                        devices[d]["Module_str"] + ",%s" % driver
+        else:
+            devices[d]["Module_str"] = ",".join(dpdk_drivers)
+
+        # make sure the driver and module strings do not have any duplicates
+        if has_driver(d):
+            modules = devices[d]["Module_str"].split(",")
+            if devices[d]["Driver_str"] in modules:
+                modules.remove(devices[d]["Driver_str"])
+                devices[d]["Module_str"] = ",".join(modules)
+
+
+def dev_id_from_dev_name(dev_name):
+    '''Take a device "name" - a string passed in by user to identify a NIC
+    device, and determine the device id - i.e. the domain:bus:slot.func - for
+    it, which can then be used to index into the devices array'''
+
+    # check if it's already a suitable index
+    if dev_name in devices:
+        return dev_name
+    # check if it's an index just missing the domain part
+    elif "0000:" + dev_name in devices:
+        return "0000:" + dev_name
+    else:
+        # check if it's an interface name, e.g. eth1
+        for d in devices.keys():
+            if dev_name in devices[d]["Interface"].split(","):
+                return devices[d]["Slot"]
+    # if nothing else matches - error
+    print("Unknown device: %s. "
+          "Please specify device in \"bus:slot.func\" format" % dev_name)
+    sys.exit(1)
+
+
+def unbind_one(dev_id, force):
+    '''Unbind the device identified by "dev_id" from its current driver'''
+    dev = devices[dev_id]
+    if not has_driver(dev_id):
+        print("%s %s %s is not currently managed by any driver\n" %
+              (dev["Slot"], dev["Device_str"], dev["Interface"]))
+        return
+
+    # prevent us disconnecting ourselves
+    if dev["Ssh_if"] and not force:
+        print("Routing table indicates that interface %s is active. "
+              "Skipping unbind" % (dev_id))
+        return
+
+    # write to /sys to unbind
+    filename = "/sys/bus/pci/drivers/%s/unbind" % dev["Driver_str"]
+    try:
+        f = open(filename, "a")
+    except:
+        print("Error: unbind failed for %s - Cannot open %s"
+              % (dev_id, filename))
+        sys.exit(1)
+    f.write(dev_id)
+    f.close()
+
+
+def bind_one(dev_id, driver, force):
+    '''Bind the device given by "dev_id" to the driver "driver". If the device
+    is already bound to a different driver, it will be unbound first'''
+    dev = devices[dev_id]
+    saved_driver = None  # used to rollback any unbind in case of failure
+
+    # prevent disconnection of our ssh session
+    if dev["Ssh_if"] and not force:
+        print("Routing table indicates that interface %s is active. "
+              "Not modifying" % (dev_id))
+        return
+
+    # unbind any existing drivers we don't want
+    if has_driver(dev_id):
+        if dev["Driver_str"] == driver:
+            print("%s already bound to driver %s, skipping\n"
+                  % (dev_id, driver))
+            return
+        else:
+            saved_driver = dev["Driver_str"]
+            unbind_one(dev_id, force)
+            dev["Driver_str"] = ""  # clear driver string
+
+    # if we are binding to one of DPDK drivers, add PCI id's to that driver
+    if driver in dpdk_drivers:
+        filename = "/sys/bus/pci/drivers/%s/new_id" % driver
+        try:
+            f = open(filename, "w")
+        except:
+            print("Error: bind failed for %s - Cannot open %s"
+                  % (dev_id, filename))
+            return
+        try:
+            f.write("%04x %04x" % (dev["Vendor"], dev["Device"]))
+            f.close()
+        except:
+            print("Error: bind failed for %s - Cannot write new PCI ID to "
+                  "driver %s" % (dev_id, driver))
+            return
+
+    # do the bind by writing to /sys
+    filename = "/sys/bus/pci/drivers/%s/bind" % driver
+    try:
+        f = open(filename, "a")
+    except:
+        print("Error: bind failed for %s - Cannot open %s"
+              % (dev_id, filename))
+        if saved_driver is not None:  # restore any previous driver
+            bind_one(dev_id, saved_driver, force)
+        return
+    try:
+        f.write(dev_id)
+        f.close()
+    except:
+        # for some reason, closing dev_id after adding a new PCI ID to new_id
+        # results in IOError. however, if the device was successfully bound,
+        # we don't care for any errors and can safely ignore IOError
+        tmp = get_pci_device_details(dev_id)
+        if "Driver_str" in tmp and tmp["Driver_str"] == driver:
+            return
+        print("Error: bind failed for %s - Cannot bind to driver %s"
+              % (dev_id, driver))
+        if saved_driver is not None:  # restore any previous driver
+            bind_one(dev_id, saved_driver, force)
+        return
+
+
+def unbind_all(dev_list, force=False):
+    """Unbind method, takes a list of device locations"""
+    dev_list = map(dev_id_from_dev_name, dev_list)
+    for d in dev_list:
+        unbind_one(d, force)
+
+
+def bind_all(dev_list, driver, force=False):
+    """Bind method, takes a list of device locations"""
+    global devices
+
+    dev_list = map(dev_id_from_dev_name, dev_list)
+
+    for d in dev_list:
+        bind_one(d, driver, force)
+
+    # when binding devices to a generic driver (i.e. one that doesn't have a
+    # PCI ID table), some devices that are not bound to any other driver could
+    # be bound even if no one has asked them to. hence, we check the list of
+    # drivers again, and see if some of the previously-unbound devices were
+    # erroneously bound.
+    for d in devices.keys():
+        # skip devices that were already bound or that we know should be bound
+        if "Driver_str" in devices[d] or d in dev_list:
+            continue
+
+        # update information about this device
+        devices[d] = dict(devices[d].items() +
+                          get_pci_device_details(d).items())
+
+        # check if updated information indicates that the device was bound
+        if "Driver_str" in devices[d]:
+            unbind_one(d, force)
+
+
+def display_devices(title, dev_list, extra_params=None):
+    '''Displays to the user the details of a list of devices given in
+    "dev_list". The "extra_params" parameter, if given, should contain a string
+     with %()s fields in it for replacement by the named fields in each
+     device's dictionary.'''
+    strings = []  # this holds the strings to print. We sort before printing
+    print("\n%s" % title)
+    print("="*len(title))
+    if len(dev_list) == 0:
+        strings.append("<none>")
+    else:
+        for dev in dev_list:
+            if extra_params is not None:
+                strings.append("%s '%s' %s" % (dev["Slot"],
+                                               dev["Device_str"],
+                                               extra_params % dev))
+            else:
+                strings.append("%s '%s'" % (dev["Slot"], dev["Device_str"]))
+    # sort before printing, so that the entries appear in PCI order
+    strings.sort()
+    print("\n".join(strings))  # print one per line
+
+
+def show_status():
+    '''Function called when the script is passed the "--status" option.
+    Displays to the user what devices are bound to the igb_uio driver, the
+    kernel driver or to no driver'''
+    global dpdk_drivers
+    kernel_drv = []
+    dpdk_drv = []
+    no_drv = []
+
+    # split our list of network devices into the three categories above
+    for d in devices.keys():
+        if NETWORK_BASE_CLASS in devices[d]["Class"]:
+            if not has_driver(d):
+                no_drv.append(devices[d])
+                continue
+            if devices[d]["Driver_str"] in dpdk_drivers:
+                dpdk_drv.append(devices[d])
+            else:
+                kernel_drv.append(devices[d])
+
+    # print each category separately, so we can clearly see what's used by DPDK
+    display_devices("Network devices using DPDK-compatible driver", dpdk_drv,
+                    "drv=%(Driver_str)s unused=%(Module_str)s")
+    display_devices("Network devices using kernel driver", kernel_drv,
+                    "if=%(Interface)s drv=%(Driver_str)s "
+                    "unused=%(Module_str)s %(Active)s")
+    display_devices("Other network devices", no_drv, "unused=%(Module_str)s")
+
+    # split our list of crypto devices into the three categories above
+    kernel_drv = []
+    dpdk_drv = []
+    no_drv = []
+
+    for d in devices.keys():
+        if CRYPTO_BASE_CLASS in devices[d]["Class"]:
+            if not has_driver(d):
+                no_drv.append(devices[d])
+                continue
+            if devices[d]["Driver_str"] in dpdk_drivers:
+                dpdk_drv.append(devices[d])
+            else:
+                kernel_drv.append(devices[d])
+
+    display_devices("Crypto devices using DPDK-compatible driver", dpdk_drv,
+                    "drv=%(Driver_str)s unused=%(Module_str)s")
+    display_devices("Crypto devices using kernel driver", kernel_drv,
+                    "drv=%(Driver_str)s "
+                    "unused=%(Module_str)s")
+    display_devices("Other crypto devices", no_drv, "unused=%(Module_str)s")
+
+
+def parse_args():
+    '''Parses the command-line arguments given by the user and takes the
+    appropriate action for each'''
+    global b_flag
+    global status_flag
+    global force_flag
+    global args
+    if len(sys.argv) <= 1:
+        usage()
+        sys.exit(0)
+
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "b:us",
+                                   ["help", "usage", "status", "force",
+                                    "bind=", "unbind"])
+    except getopt.GetoptError as error:
+        print(str(error))
+        print("Run '%s --usage' for further information" % sys.argv[0])
+        sys.exit(1)
+
+    for opt, arg in opts:
+        if opt == "--help" or opt == "--usage":
+            usage()
+            sys.exit(0)
+        if opt == "--status" or opt == "-s":
+            status_flag = True
+        if opt == "--force":
+            force_flag = True
+        if opt == "-b" or opt == "-u" or opt == "--bind" or opt == "--unbind":
+            if b_flag is not None:
+                print("Error - Only one bind or unbind may be specified\n")
+                sys.exit(1)
+            if opt == "-u" or opt == "--unbind":
+                b_flag = "none"
+            else:
+                b_flag = arg
+
+
+def do_arg_actions():
+    '''do the actual action requested by the user'''
+    global b_flag
+    global status_flag
+    global force_flag
+    global args
+
+    if b_flag is None and not status_flag:
+        print("Error: No action specified for devices."
+              "Please give a -b or -u option")
+        print("Run '%s --usage' for further information" % sys.argv[0])
+        sys.exit(1)
+
+    if b_flag is not None and len(args) == 0:
+        print("Error: No devices specified.")
+        print("Run '%s --usage' for further information" % sys.argv[0])
+        sys.exit(1)
+
+    if b_flag == "none" or b_flag == "None":
+        unbind_all(args, force_flag)
+    elif b_flag is not None:
+        bind_all(args, b_flag, force_flag)
+    if status_flag:
+        if b_flag is not None:
+            get_nic_details()  # refresh if we have changed anything
+            get_crypto_details()  # refresh if we have changed anything
+        show_status()
+
+
+def main():
+    '''program main function'''
+    parse_args()
+    check_modules()
+    get_nic_details()
+    get_crypto_details()
+    do_arg_actions()
+
+if __name__ == "__main__":
+    main()
diff --git a/usertools/dpdk-pmdinfo.py b/usertools/dpdk-pmdinfo.py
new file mode 100755 (executable)
index 0000000..46c1be0
--- /dev/null
@@ -0,0 +1,610 @@
+#!/usr/bin/env python
+
+# -------------------------------------------------------------------------
+#
+# Utility to dump PMD_INFO_STRING support from an object file
+#
+# -------------------------------------------------------------------------
+from __future__ import print_function
+import json
+import os
+import platform
+import string
+import sys
+from elftools.common.exceptions import ELFError
+from elftools.common.py3compat import (byte2int, bytes2str, str2bytes)
+from elftools.elf.elffile import ELFFile
+from optparse import OptionParser
+
+# For running from development directory. It should take precedence over the
+# installed pyelftools.
+sys.path.insert(0, '.')
+
+raw_output = False
+pcidb = None
+
+# ===========================================
+
+
+class Vendor:
+    """
+    Class for vendors. This is the top level class
+    for the devices belong to a specific vendor.
+    self.devices is the device dictionary
+    subdevices are in each device.
+    """
+
+    def __init__(self, vendorStr):
+        """
+        Class initializes with the raw line from pci.ids
+        Parsing takes place inside __init__
+        """
+        self.ID = vendorStr.split()[0]
+        self.name = vendorStr.replace("%s " % self.ID, "").rstrip()
+        self.devices = {}
+
+    def addDevice(self, deviceStr):
+        """
+        Adds a device to self.devices
+        takes the raw line from pci.ids
+        """
+        s = deviceStr.strip()
+        devID = s.split()[0]
+        if devID in self.devices:
+            pass
+        else:
+            self.devices[devID] = Device(deviceStr)
+
+    def report(self):
+        print(self.ID, self.name)
+        for id, dev in self.devices.items():
+            dev.report()
+
+    def find_device(self, devid):
+        # convert to a hex string and remove 0x
+        devid = hex(devid)[2:]
+        try:
+            return self.devices[devid]
+        except:
+            return Device("%s  Unknown Device" % devid)
+
+
+class Device:
+
+    def __init__(self, deviceStr):
+        """
+        Class for each device.
+        Each vendor has its own devices dictionary.
+        """
+        s = deviceStr.strip()
+        self.ID = s.split()[0]
+        self.name = s.replace("%s  " % self.ID, "")
+        self.subdevices = {}
+
+    def report(self):
+        print("\t%s\t%s" % (self.ID, self.name))
+        for subID, subdev in self.subdevices.items():
+            subdev.report()
+
+    def addSubDevice(self, subDeviceStr):
+        """
+        Adds a subvendor, subdevice to device.
+        Uses raw line from pci.ids
+        """
+        s = subDeviceStr.strip()
+        spl = s.split()
+        subVendorID = spl[0]
+        subDeviceID = spl[1]
+        subDeviceName = s.split("  ")[-1]
+        devID = "%s:%s" % (subVendorID, subDeviceID)
+        self.subdevices[devID] = SubDevice(
+            subVendorID, subDeviceID, subDeviceName)
+
+    def find_subid(self, subven, subdev):
+        subven = hex(subven)[2:]
+        subdev = hex(subdev)[2:]
+        devid = "%s:%s" % (subven, subdev)
+
+        try:
+            return self.subdevices[devid]
+        except:
+            if (subven == "ffff" and subdev == "ffff"):
+                return SubDevice("ffff", "ffff", "(All Subdevices)")
+            else:
+                return SubDevice(subven, subdev, "(Unknown Subdevice)")
+
+
+class SubDevice:
+    """
+    Class for subdevices.
+    """
+
+    def __init__(self, vendor, device, name):
+        """
+        Class initializes with vendorid, deviceid and name
+        """
+        self.vendorID = vendor
+        self.deviceID = device
+        self.name = name
+
+    def report(self):
+        print("\t\t%s\t%s\t%s" % (self.vendorID, self.deviceID, self.name))
+
+
+class PCIIds:
+    """
+    Top class for all pci.ids entries.
+    All queries will be asked to this class.
+    PCIIds.vendors["0e11"].devices["0046"].\
+    subdevices["0e11:4091"].name  =  "Smart Array 6i"
+    """
+
+    def __init__(self, filename):
+        """
+        Prepares the directories.
+        Checks local data file.
+        Tries to load from local, if not found, downloads from web
+        """
+        self.version = ""
+        self.date = ""
+        self.vendors = {}
+        self.contents = None
+        self.readLocal(filename)
+        self.parse()
+
+    def reportVendors(self):
+        """Reports the vendors
+        """
+        for vid, v in self.vendors.items():
+            print(v.ID, v.name)
+
+    def report(self, vendor=None):
+        """
+        Reports everything for all vendors or a specific vendor
+        PCIIds.report()  reports everything
+        PCIIDs.report("0e11") reports only "Compaq Computer Corporation"
+        """
+        if vendor is not None:
+            self.vendors[vendor].report()
+        else:
+            for vID, v in self.vendors.items():
+                v.report()
+
+    def find_vendor(self, vid):
+        # convert vid to a hex string and remove the 0x
+        vid = hex(vid)[2:]
+
+        try:
+            return self.vendors[vid]
+        except:
+            return Vendor("%s Unknown Vendor" % (vid))
+
+    def findDate(self, content):
+        for l in content:
+            if l.find("Date:") > -1:
+                return l.split()[-2].replace("-", "")
+        return None
+
+    def parse(self):
+        if len(self.contents) < 1:
+            print("data/%s-pci.ids not found" % self.date)
+        else:
+            vendorID = ""
+            deviceID = ""
+            for l in self.contents:
+                if l[0] == "#":
+                    continue
+                elif len(l.strip()) == 0:
+                    continue
+                else:
+                    if l.find("\t\t") == 0:
+                        self.vendors[vendorID].devices[
+                            deviceID].addSubDevice(l)
+                    elif l.find("\t") == 0:
+                        deviceID = l.strip().split()[0]
+                        self.vendors[vendorID].addDevice(l)
+                    else:
+                        vendorID = l.split()[0]
+                        self.vendors[vendorID] = Vendor(l)
+
+    def readLocal(self, filename):
+        """
+        Reads the local file
+        """
+        self.contents = open(filename).readlines()
+        self.date = self.findDate(self.contents)
+
+    def loadLocal(self):
+        """
+        Loads database from local. If there is no file,
+        it creates a new one from web
+        """
+        self.date = idsfile[0].split("/")[1].split("-")[0]
+        self.readLocal()
+
+
+# =======================================
+
+def search_file(filename, search_path):
+    """ Given a search path, find file with requested name """
+    for path in string.split(search_path, ":"):
+        candidate = os.path.join(path, filename)
+        if os.path.exists(candidate):
+            return os.path.abspath(candidate)
+    return None
+
+
+class ReadElf(object):
+    """ display_* methods are used to emit output into the output stream
+    """
+
+    def __init__(self, file, output):
+        """ file:
+                stream object with the ELF file to read
+
+            output:
+                output stream to write to
+        """
+        self.elffile = ELFFile(file)
+        self.output = output
+
+        # Lazily initialized if a debug dump is requested
+        self._dwarfinfo = None
+
+        self._versioninfo = None
+
+    def _section_from_spec(self, spec):
+        """ Retrieve a section given a "spec" (either number or name).
+            Return None if no such section exists in the file.
+        """
+        try:
+            num = int(spec)
+            if num < self.elffile.num_sections():
+                return self.elffile.get_section(num)
+            else:
+                return None
+        except ValueError:
+            # Not a number. Must be a name then
+            return self.elffile.get_section_by_name(str2bytes(spec))
+
+    def pretty_print_pmdinfo(self, pmdinfo):
+        global pcidb
+
+        for i in pmdinfo["pci_ids"]:
+            vendor = pcidb.find_vendor(i[0])
+            device = vendor.find_device(i[1])
+            subdev = device.find_subid(i[2], i[3])
+            print("%s (%s) : %s (%s) %s" %
+                  (vendor.name, vendor.ID, device.name,
+                   device.ID, subdev.name))
+
+    def parse_pmd_info_string(self, mystring):
+        global raw_output
+        global pcidb
+
+        optional_pmd_info = [
+            {'id': 'params', 'tag': 'PMD PARAMETERS'},
+            {'id': 'kmod', 'tag': 'PMD KMOD DEPENDENCIES'}
+        ]
+
+        i = mystring.index("=")
+        mystring = mystring[i + 2:]
+        pmdinfo = json.loads(mystring)
+
+        if raw_output:
+            print(json.dumps(pmdinfo))
+            return
+
+        print("PMD NAME: " + pmdinfo["name"])
+        for i in optional_pmd_info:
+            try:
+                print("%s: %s" % (i['tag'], pmdinfo[i['id']]))
+            except KeyError:
+                continue
+
+        if (len(pmdinfo["pci_ids"]) != 0):
+            print("PMD HW SUPPORT:")
+            if pcidb is not None:
+                self.pretty_print_pmdinfo(pmdinfo)
+            else:
+                print("VENDOR\t DEVICE\t SUBVENDOR\t SUBDEVICE")
+                for i in pmdinfo["pci_ids"]:
+                    print("0x%04x\t 0x%04x\t 0x%04x\t\t 0x%04x" %
+                          (i[0], i[1], i[2], i[3]))
+
+        print("")
+
+    def display_pmd_info_strings(self, section_spec):
+        """ Display a strings dump of a section. section_spec is either a
+            section number or a name.
+        """
+        section = self._section_from_spec(section_spec)
+        if section is None:
+            return
+
+        data = section.data()
+        dataptr = 0
+
+        while dataptr < len(data):
+            while (dataptr < len(data) and
+                    not (32 <= byte2int(data[dataptr]) <= 127)):
+                dataptr += 1
+
+            if dataptr >= len(data):
+                break
+
+            endptr = dataptr
+            while endptr < len(data) and byte2int(data[endptr]) != 0:
+                endptr += 1
+
+            mystring = bytes2str(data[dataptr:endptr])
+            rc = mystring.find("PMD_INFO_STRING")
+            if (rc != -1):
+                self.parse_pmd_info_string(mystring)
+
+            dataptr = endptr
+
+    def find_librte_eal(self, section):
+        for tag in section.iter_tags():
+            if tag.entry.d_tag == 'DT_NEEDED':
+                if "librte_eal" in tag.needed:
+                    return tag.needed
+        return None
+
+    def search_for_autoload_path(self):
+        scanelf = self
+        scanfile = None
+        library = None
+
+        section = self._section_from_spec(".dynamic")
+        try:
+            eallib = self.find_librte_eal(section)
+            if eallib is not None:
+                ldlibpath = os.environ.get('LD_LIBRARY_PATH')
+                if ldlibpath is None:
+                    ldlibpath = ""
+                dtr = self.get_dt_runpath(section)
+                library = search_file(eallib,
+                                      dtr + ":" + ldlibpath +
+                                      ":/usr/lib64:/lib64:/usr/lib:/lib")
+                if library is None:
+                    return (None, None)
+                if raw_output is False:
+                    print("Scanning for autoload path in %s" % library)
+                scanfile = open(library, 'rb')
+                scanelf = ReadElf(scanfile, sys.stdout)
+        except AttributeError:
+            # Not a dynamic binary
+            pass
+        except ELFError:
+            scanfile.close()
+            return (None, None)
+
+        section = scanelf._section_from_spec(".rodata")
+        if section is None:
+            if scanfile is not None:
+                scanfile.close()
+            return (None, None)
+
+        data = section.data()
+        dataptr = 0
+
+        while dataptr < len(data):
+            while (dataptr < len(data) and
+                    not (32 <= byte2int(data[dataptr]) <= 127)):
+                dataptr += 1
+
+            if dataptr >= len(data):
+                break
+
+            endptr = dataptr
+            while endptr < len(data) and byte2int(data[endptr]) != 0:
+                endptr += 1
+
+            mystring = bytes2str(data[dataptr:endptr])
+            rc = mystring.find("DPDK_PLUGIN_PATH")
+            if (rc != -1):
+                rc = mystring.find("=")
+                return (mystring[rc + 1:], library)
+
+            dataptr = endptr
+        if scanfile is not None:
+            scanfile.close()
+        return (None, None)
+
+    def get_dt_runpath(self, dynsec):
+        for tag in dynsec.iter_tags():
+            if tag.entry.d_tag == 'DT_RUNPATH':
+                return tag.runpath
+        return ""
+
+    def process_dt_needed_entries(self):
+        """ Look to see if there are any DT_NEEDED entries in the binary
+            And process those if there are
+        """
+        global raw_output
+        runpath = ""
+        ldlibpath = os.environ.get('LD_LIBRARY_PATH')
+        if ldlibpath is None:
+            ldlibpath = ""
+
+        dynsec = self._section_from_spec(".dynamic")
+        try:
+            runpath = self.get_dt_runpath(dynsec)
+        except AttributeError:
+            # dynsec is None, just return
+            return
+
+        for tag in dynsec.iter_tags():
+            if tag.entry.d_tag == 'DT_NEEDED':
+                rc = tag.needed.find(b"librte_pmd")
+                if (rc != -1):
+                    library = search_file(tag.needed,
+                                          runpath + ":" + ldlibpath +
+                                          ":/usr/lib64:/lib64:/usr/lib:/lib")
+                    if library is not None:
+                        if raw_output is False:
+                            print("Scanning %s for pmd information" % library)
+                        with open(library, 'rb') as file:
+                            try:
+                                libelf = ReadElf(file, sys.stdout)
+                            except ELFError:
+                                print("%s is no an ELF file" % library)
+                                continue
+                            libelf.process_dt_needed_entries()
+                            libelf.display_pmd_info_strings(".rodata")
+                            file.close()
+
+
+def scan_autoload_path(autoload_path):
+    global raw_output
+
+    if os.path.exists(autoload_path) is False:
+        return
+
+    try:
+        dirs = os.listdir(autoload_path)
+    except OSError:
+        # Couldn't read the directory, give up
+        return
+
+    for d in dirs:
+        dpath = os.path.join(autoload_path, d)
+        if os.path.isdir(dpath):
+            scan_autoload_path(dpath)
+        if os.path.isfile(dpath):
+            try:
+                file = open(dpath, 'rb')
+                readelf = ReadElf(file, sys.stdout)
+            except ELFError:
+                # this is likely not an elf file, skip it
+                continue
+            except IOError:
+                # No permission to read the file, skip it
+                continue
+
+            if raw_output is False:
+                print("Hw Support for library %s" % d)
+            readelf.display_pmd_info_strings(".rodata")
+            file.close()
+
+
+def scan_for_autoload_pmds(dpdk_path):
+    """
+    search the specified application or path for a pmd autoload path
+    then scan said path for pmds and report hw support
+    """
+    global raw_output
+
+    if (os.path.isfile(dpdk_path) is False):
+        if raw_output is False:
+            print("Must specify a file name")
+        return
+
+    file = open(dpdk_path, 'rb')
+    try:
+        readelf = ReadElf(file, sys.stdout)
+    except ElfError:
+        if raw_output is False:
+            print("Unable to parse %s" % file)
+        return
+
+    (autoload_path, scannedfile) = readelf.search_for_autoload_path()
+    if (autoload_path is None or autoload_path is ""):
+        if (raw_output is False):
+            print("No autoload path configured in %s" % dpdk_path)
+        return
+    if (raw_output is False):
+        if (scannedfile is None):
+            scannedfile = dpdk_path
+        print("Found autoload path %s in %s" % (autoload_path, scannedfile))
+
+    file.close()
+    if (raw_output is False):
+        print("Discovered Autoload HW Support:")
+    scan_autoload_path(autoload_path)
+    return
+
+
+def main(stream=None):
+    global raw_output
+    global pcidb
+
+    pcifile_default = "./pci.ids"  # For unknown OS's assume local file
+    if platform.system() == 'Linux':
+        pcifile_default = "/usr/share/hwdata/pci.ids"
+    elif platform.system() == 'FreeBSD':
+        pcifile_default = "/usr/local/share/pciids/pci.ids"
+        if not os.path.exists(pcifile_default):
+            pcifile_default = "/usr/share/misc/pci_vendors"
+
+    optparser = OptionParser(
+        usage='usage: %prog [-hrtp] [-d <pci id file] <elf-file>',
+        description="Dump pmd hardware support info",
+        add_help_option=True)
+    optparser.add_option('-r', '--raw',
+                         action='store_true', dest='raw_output',
+                         help='Dump raw json strings')
+    optparser.add_option("-d", "--pcidb", dest="pcifile",
+                         help="specify a pci database "
+                              "to get vendor names from",
+                         default=pcifile_default, metavar="FILE")
+    optparser.add_option("-t", "--table", dest="tblout",
+                         help="output information on hw support as a "
+                              "hex table",
+                         action='store_true')
+    optparser.add_option("-p", "--plugindir", dest="pdir",
+                         help="scan dpdk for autoload plugins",
+                         action='store_true')
+
+    options, args = optparser.parse_args()
+
+    if options.raw_output:
+        raw_output = True
+
+    if options.pcifile:
+        pcidb = PCIIds(options.pcifile)
+        if pcidb is None:
+            print("Pci DB file not found")
+            exit(1)
+
+    if options.tblout:
+        options.pcifile = None
+        pcidb = None
+
+    if (len(args) == 0):
+        optparser.print_usage()
+        exit(1)
+
+    if options.pdir is True:
+        exit(scan_for_autoload_pmds(args[0]))
+
+    ldlibpath = os.environ.get('LD_LIBRARY_PATH')
+    if (ldlibpath is None):
+        ldlibpath = ""
+
+    if (os.path.exists(args[0]) is True):
+        myelffile = args[0]
+    else:
+        myelffile = search_file(
+            args[0], ldlibpath + ":/usr/lib64:/lib64:/usr/lib:/lib")
+
+    if (myelffile is None):
+        print("File not found")
+        sys.exit(1)
+
+    with open(myelffile, 'rb') as file:
+        try:
+            readelf = ReadElf(file, sys.stdout)
+            readelf.process_dt_needed_entries()
+            readelf.display_pmd_info_strings(".rodata")
+            sys.exit(0)
+
+        except ELFError as ex:
+            sys.stderr.write('ELF error: %s\n' % ex)
+            sys.exit(1)
+
+
+# -------------------------------------------------------------------------
+if __name__ == '__main__':
+    main()
diff --git a/usertools/dpdk-setup.sh b/usertools/dpdk-setup.sh
new file mode 100755 (executable)
index 0000000..c4fec5a
--- /dev/null
@@ -0,0 +1,634 @@
+#! /bin/bash
+
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#
+# Run with "source /path/to/dpdk-setup.sh"
+#
+
+#
+# Change to DPDK directory ( <this-script's-dir>/.. ), and export it as RTE_SDK
+#
+cd $(dirname ${BASH_SOURCE[0]})/..
+export RTE_SDK=$PWD
+echo "------------------------------------------------------------------------------"
+echo " RTE_SDK exported as $RTE_SDK"
+echo "------------------------------------------------------------------------------"
+
+HUGEPGSZ=`cat /proc/meminfo  | grep Hugepagesize | cut -d : -f 2 | tr -d ' '`
+
+#
+# Application EAL parameters for setting memory options (amount/channels/ranks).
+#
+EAL_PARAMS='-n 4'
+
+#
+# Sets QUIT variable so script will finish.
+#
+quit()
+{
+       QUIT=$1
+}
+
+# Shortcut for quit.
+q()
+{
+       quit
+}
+
+#
+# Sets up environmental variables for ICC.
+#
+setup_icc()
+{
+       DEFAULT_PATH=/opt/intel/bin/iccvars.sh
+       param=$1
+       shpath=`which iccvars.sh 2> /dev/null`
+       if [ $? -eq 0 ] ; then
+               echo "Loading iccvars.sh from $shpath for $param"
+               source $shpath $param
+       elif [ -f $DEFAULT_PATH ] ; then
+               echo "Loading iccvars.sh from $DEFAULT_PATH for $param"
+               source $DEFAULT_PATH $param
+       else
+               echo "## ERROR: cannot find 'iccvars.sh' script to set up ICC."
+               echo "##     To fix, please add the directory that contains"
+               echo "##     iccvars.sh  to your 'PATH' environment variable."
+               quit
+       fi
+}
+
+#
+# Sets RTE_TARGET and does a "make install".
+#
+setup_target()
+{
+       option=$1
+       export RTE_TARGET=${TARGETS[option]}
+
+       compiler=${RTE_TARGET##*-}
+       if [ "$compiler" == "icc" ] ; then
+               platform=${RTE_TARGET%%-*}
+               if [ "$platform" == "x86_64" ] ; then
+                       setup_icc intel64
+               else
+                       setup_icc ia32
+               fi
+       fi
+       if [ "$QUIT" == "0" ] ; then
+               make install T=${RTE_TARGET}
+       fi
+       echo "------------------------------------------------------------------------------"
+       echo " RTE_TARGET exported as $RTE_TARGET"
+       echo "------------------------------------------------------------------------------"
+}
+
+#
+# Creates hugepage filesystem.
+#
+create_mnt_huge()
+{
+       echo "Creating /mnt/huge and mounting as hugetlbfs"
+       sudo mkdir -p /mnt/huge
+
+       grep -s '/mnt/huge' /proc/mounts > /dev/null
+       if [ $? -ne 0 ] ; then
+               sudo mount -t hugetlbfs nodev /mnt/huge
+       fi
+}
+
+#
+# Removes hugepage filesystem.
+#
+remove_mnt_huge()
+{
+       echo "Unmounting /mnt/huge and removing directory"
+       grep -s '/mnt/huge' /proc/mounts > /dev/null
+       if [ $? -eq 0 ] ; then
+               sudo umount /mnt/huge
+       fi
+
+       if [ -d /mnt/huge ] ; then
+               sudo rm -R /mnt/huge
+       fi
+}
+
+#
+# Unloads igb_uio.ko.
+#
+remove_igb_uio_module()
+{
+       echo "Unloading any existing DPDK UIO module"
+       /sbin/lsmod | grep -s igb_uio > /dev/null
+       if [ $? -eq 0 ] ; then
+               sudo /sbin/rmmod igb_uio
+       fi
+}
+
+#
+# Loads new igb_uio.ko (and uio module if needed).
+#
+load_igb_uio_module()
+{
+       if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko ];then
+               echo "## ERROR: Target does not have the DPDK UIO Kernel Module."
+               echo "       To fix, please try to rebuild target."
+               return
+       fi
+
+       remove_igb_uio_module
+
+       /sbin/lsmod | grep -s uio > /dev/null
+       if [ $? -ne 0 ] ; then
+               modinfo uio > /dev/null
+               if [ $? -eq 0 ]; then
+                       echo "Loading uio module"
+                       sudo /sbin/modprobe uio
+               fi
+       fi
+
+       # UIO may be compiled into kernel, so it may not be an error if it can't
+       # be loaded.
+
+       echo "Loading DPDK UIO module"
+       sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko
+       if [ $? -ne 0 ] ; then
+               echo "## ERROR: Could not load kmod/igb_uio.ko."
+               quit
+       fi
+}
+
+#
+# Unloads VFIO modules.
+#
+remove_vfio_module()
+{
+       echo "Unloading any existing VFIO module"
+       /sbin/lsmod | grep -s vfio > /dev/null
+       if [ $? -eq 0 ] ; then
+               sudo /sbin/rmmod vfio-pci
+               sudo /sbin/rmmod vfio_iommu_type1
+               sudo /sbin/rmmod vfio
+       fi
+}
+
+#
+# Loads new vfio-pci (and vfio module if needed).
+#
+load_vfio_module()
+{
+       remove_vfio_module
+
+       VFIO_PATH="kernel/drivers/vfio/pci/vfio-pci.ko"
+
+       echo "Loading VFIO module"
+       /sbin/lsmod | grep -s vfio_pci > /dev/null
+       if [ $? -ne 0 ] ; then
+               if [ -f /lib/modules/$(uname -r)/$VFIO_PATH ] ; then
+                       sudo /sbin/modprobe vfio-pci
+               fi
+       fi
+
+       # make sure regular users can read /dev/vfio
+       echo "chmod /dev/vfio"
+       sudo chmod a+x /dev/vfio
+       if [ $? -ne 0 ] ; then
+               echo "FAIL"
+               quit
+       fi
+       echo "OK"
+
+       # check if /dev/vfio/vfio exists - that way we
+       # know we either loaded the module, or it was
+       # compiled into the kernel
+       if [ ! -e /dev/vfio/vfio ] ; then
+               echo "## ERROR: VFIO not found!"
+       fi
+}
+
+#
+# Unloads the rte_kni.ko module.
+#
+remove_kni_module()
+{
+       echo "Unloading any existing DPDK KNI module"
+       /sbin/lsmod | grep -s rte_kni > /dev/null
+       if [ $? -eq 0 ] ; then
+               sudo /sbin/rmmod rte_kni
+       fi
+}
+
+#
+# Loads the rte_kni.ko module.
+#
+load_kni_module()
+{
+    # Check that the KNI module is already built.
+       if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko ];then
+               echo "## ERROR: Target does not have the DPDK KNI Module."
+               echo "       To fix, please try to rebuild target."
+               return
+       fi
+
+    # Unload existing version if present.
+       remove_kni_module
+
+    # Now try load the KNI module.
+       echo "Loading DPDK KNI module"
+       sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko
+       if [ $? -ne 0 ] ; then
+               echo "## ERROR: Could not load kmod/rte_kni.ko."
+               quit
+       fi
+}
+
+#
+# Sets appropriate permissions on /dev/vfio/* files
+#
+set_vfio_permissions()
+{
+       # make sure regular users can read /dev/vfio
+       echo "chmod /dev/vfio"
+       sudo chmod a+x /dev/vfio
+       if [ $? -ne 0 ] ; then
+               echo "FAIL"
+               quit
+       fi
+       echo "OK"
+
+       # make sure regular user can access everything inside /dev/vfio
+       echo "chmod /dev/vfio/*"
+       sudo chmod 0666 /dev/vfio/*
+       if [ $? -ne 0 ] ; then
+               echo "FAIL"
+               quit
+       fi
+       echo "OK"
+
+       # since permissions are only to be set when running as
+       # regular user, we only check ulimit here
+       #
+       # warn if regular user is only allowed
+       # to memlock <64M of memory
+       MEMLOCK_AMNT=`ulimit -l`
+
+       if [ "$MEMLOCK_AMNT" != "unlimited" ] ; then
+               MEMLOCK_MB=`expr $MEMLOCK_AMNT / 1024`
+               echo ""
+               echo "Current user memlock limit: ${MEMLOCK_MB} MB"
+               echo ""
+               echo "This is the maximum amount of memory you will be"
+               echo "able to use with DPDK and VFIO if run as current user."
+               echo -n "To change this, please adjust limits.conf memlock "
+               echo "limit for current user."
+
+               if [ $MEMLOCK_AMNT -lt 65536 ] ; then
+                       echo ""
+                       echo "## WARNING: memlock limit is less than 64MB"
+                       echo -n "## DPDK with VFIO may not be able to initialize "
+                       echo "if run as current user."
+               fi
+       fi
+}
+
+#
+# Removes all reserved hugepages.
+#
+clear_huge_pages()
+{
+       echo > .echo_tmp
+       for d in /sys/devices/system/node/node? ; do
+               echo "echo 0 > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp
+       done
+       echo "Removing currently reserved hugepages"
+       sudo sh .echo_tmp
+       rm -f .echo_tmp
+
+       remove_mnt_huge
+}
+
+#
+# Creates hugepages.
+#
+set_non_numa_pages()
+{
+       clear_huge_pages
+
+       echo ""
+       echo "  Input the number of ${HUGEPGSZ} hugepages"
+       echo "  Example: to have 128MB of hugepages available in a 2MB huge page system,"
+       echo "  enter '64' to reserve 64 * 2MB pages"
+       echo -n "Number of pages: "
+       read Pages
+
+       echo "echo $Pages > /sys/kernel/mm/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" > .echo_tmp
+
+       echo "Reserving hugepages"
+       sudo sh .echo_tmp
+       rm -f .echo_tmp
+
+       create_mnt_huge
+}
+
+#
+# Creates hugepages on specific NUMA nodes.
+#
+set_numa_pages()
+{
+       clear_huge_pages
+
+       echo ""
+       echo "  Input the number of ${HUGEPGSZ} hugepages for each node"
+       echo "  Example: to have 128MB of hugepages available per node in a 2MB huge page system,"
+       echo "  enter '64' to reserve 64 * 2MB pages on each node"
+
+       echo > .echo_tmp
+       for d in /sys/devices/system/node/node? ; do
+               node=$(basename $d)
+               echo -n "Number of pages for $node: "
+               read Pages
+               echo "echo $Pages > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp
+       done
+       echo "Reserving hugepages"
+       sudo sh .echo_tmp
+       rm -f .echo_tmp
+
+       create_mnt_huge
+}
+
+#
+# Run unit test application.
+#
+run_test_app()
+{
+       echo ""
+       echo "  Enter hex bitmask of cores to execute test app on"
+       echo "  Example: to execute app on cores 0 to 7, enter 0xff"
+       echo -n "bitmask: "
+       read Bitmask
+       echo "Launching app"
+       sudo ${RTE_TARGET}/app/test -c $Bitmask $EAL_PARAMS
+}
+
+#
+# Run unit testpmd application.
+#
+run_testpmd_app()
+{
+       echo ""
+       echo "  Enter hex bitmask of cores to execute testpmd app on"
+       echo "  Example: to execute app on cores 0 to 7, enter 0xff"
+       echo -n "bitmask: "
+       read Bitmask
+       echo "Launching app"
+       sudo ${RTE_TARGET}/app/testpmd -c $Bitmask $EAL_PARAMS -- -i
+}
+
+#
+# Print hugepage information.
+#
+grep_meminfo()
+{
+       grep -i huge /proc/meminfo
+}
+
+#
+# Calls dpdk-devbind.py --status to show the devices and what they
+# are all bound to, in terms of drivers.
+#
+show_devices()
+{
+       if [ -d /sys/module/vfio_pci -o -d /sys/module/igb_uio ]; then
+               ${RTE_SDK}/usertools/dpdk-devbind.py --status
+       else
+               echo "# Please load the 'igb_uio' or 'vfio-pci' kernel module before "
+               echo "# querying or adjusting device bindings"
+       fi
+}
+
+#
+# Uses dpdk-devbind.py to move devices to work with vfio-pci
+#
+bind_devices_to_vfio()
+{
+       if [ -d /sys/module/vfio_pci ]; then
+               ${RTE_SDK}/usertools/dpdk-devbind.py --status
+               echo ""
+               echo -n "Enter PCI address of device to bind to VFIO driver: "
+               read PCI_PATH
+               sudo ${RTE_SDK}/usertools/dpdk-devbind.py -b vfio-pci $PCI_PATH &&
+                       echo "OK"
+       else
+               echo "# Please load the 'vfio-pci' kernel module before querying or "
+               echo "# adjusting device bindings"
+       fi
+}
+
+#
+# Uses dpdk-devbind.py to move devices to work with igb_uio
+#
+bind_devices_to_igb_uio()
+{
+       if [ -d /sys/module/igb_uio ]; then
+               ${RTE_SDK}/usertools/dpdk-devbind.py --status
+               echo ""
+               echo -n "Enter PCI address of device to bind to IGB UIO driver: "
+               read PCI_PATH
+               sudo ${RTE_SDK}/usertools/dpdk-devbind.py -b igb_uio $PCI_PATH && echo "OK"
+       else
+               echo "# Please load the 'igb_uio' kernel module before querying or "
+               echo "# adjusting device bindings"
+       fi
+}
+
+#
+# Uses dpdk-devbind.py to move devices to work with kernel drivers again
+#
+unbind_devices()
+{
+       ${RTE_SDK}/usertools/dpdk-devbind.py --status
+       echo ""
+       echo -n "Enter PCI address of device to unbind: "
+       read PCI_PATH
+       echo ""
+       echo -n "Enter name of kernel driver to bind the device to: "
+       read DRV
+       sudo ${RTE_SDK}/usertools/dpdk-devbind.py -b $DRV $PCI_PATH && echo "OK"
+}
+
+#
+# Options for building a target. Note that this step MUST be first as it sets
+# up TARGETS[] starting from 1, and this is accessed in setup_target using the
+# user entered option.
+#
+step1_func()
+{
+       TITLE="Select the DPDK environment to build"
+       CONFIG_NUM=1
+       for cfg in config/defconfig_* ; do
+               cfg=${cfg/config\/defconfig_/}
+               TEXT[$CONFIG_NUM]="$cfg"
+               TARGETS[$CONFIG_NUM]=$cfg
+               FUNC[$CONFIG_NUM]="setup_target"
+               let "CONFIG_NUM+=1"
+       done
+}
+
+#
+# Options for setting up environment.
+#
+step2_func()
+{
+       TITLE="Setup linuxapp environment"
+
+       TEXT[1]="Insert IGB UIO module"
+       FUNC[1]="load_igb_uio_module"
+
+       TEXT[2]="Insert VFIO module"
+       FUNC[2]="load_vfio_module"
+
+       TEXT[3]="Insert KNI module"
+       FUNC[3]="load_kni_module"
+
+       TEXT[4]="Setup hugepage mappings for non-NUMA systems"
+       FUNC[4]="set_non_numa_pages"
+
+       TEXT[5]="Setup hugepage mappings for NUMA systems"
+       FUNC[5]="set_numa_pages"
+
+       TEXT[6]="Display current Ethernet/Crypto device settings"
+       FUNC[6]="show_devices"
+
+       TEXT[7]="Bind Ethernet/Crypto device to IGB UIO module"
+       FUNC[7]="bind_devices_to_igb_uio"
+
+       TEXT[8]="Bind Ethernet/Crypto device to VFIO module"
+       FUNC[8]="bind_devices_to_vfio"
+
+       TEXT[9]="Setup VFIO permissions"
+       FUNC[9]="set_vfio_permissions"
+}
+
+#
+# Options for running applications.
+#
+step3_func()
+{
+       TITLE="Run test application for linuxapp environment"
+
+       TEXT[1]="Run test application (\$RTE_TARGET/app/test)"
+       FUNC[1]="run_test_app"
+
+       TEXT[2]="Run testpmd application in interactive mode (\$RTE_TARGET/app/testpmd)"
+       FUNC[2]="run_testpmd_app"
+}
+
+#
+# Other options
+#
+step4_func()
+{
+       TITLE="Other tools"
+
+       TEXT[1]="List hugepage info from /proc/meminfo"
+       FUNC[1]="grep_meminfo"
+
+}
+
+#
+# Options for cleaning up the system
+#
+step5_func()
+{
+       TITLE="Uninstall and system cleanup"
+
+       TEXT[1]="Unbind devices from IGB UIO or VFIO driver"
+       FUNC[1]="unbind_devices"
+
+       TEXT[2]="Remove IGB UIO module"
+       FUNC[2]="remove_igb_uio_module"
+
+       TEXT[3]="Remove VFIO module"
+       FUNC[3]="remove_vfio_module"
+
+       TEXT[4]="Remove KNI module"
+       FUNC[4]="remove_kni_module"
+
+       TEXT[5]="Remove hugepage mappings"
+       FUNC[5]="clear_huge_pages"
+}
+
+STEPS[1]="step1_func"
+STEPS[2]="step2_func"
+STEPS[3]="step3_func"
+STEPS[4]="step4_func"
+STEPS[5]="step5_func"
+
+QUIT=0
+
+while [ "$QUIT" == "0" ]; do
+       OPTION_NUM=1
+
+       for s in $(seq ${#STEPS[@]}) ; do
+               ${STEPS[s]}
+
+               echo "----------------------------------------------------------"
+               echo " Step $s: ${TITLE}"
+               echo "----------------------------------------------------------"
+
+               for i in $(seq ${#TEXT[@]}) ; do
+                       echo "[$OPTION_NUM] ${TEXT[i]}"
+                       OPTIONS[$OPTION_NUM]=${FUNC[i]}
+                       let "OPTION_NUM+=1"
+               done
+
+               # Clear TEXT and FUNC arrays before next step
+               unset TEXT
+               unset FUNC
+
+               echo ""
+       done
+
+       echo "[$OPTION_NUM] Exit Script"
+       OPTIONS[$OPTION_NUM]="quit"
+       echo ""
+       echo -n "Option: "
+       read our_entry
+       echo ""
+       ${OPTIONS[our_entry]} ${our_entry}
+
+       if [ "$QUIT" == "0" ] ; then
+               echo
+               echo -n "Press enter to continue ..."; read
+       fi
+
+done