[v3,01/11] net/igc: add igc PMD

Message ID 20200413063037.13728-2-alvinx.zhang@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series igc pmd |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-testing success Testing PASS
ci/Intel-compilation success Compilation OK

Commit Message

Alvin Zhang April 13, 2020, 6:30 a.m. UTC
  From: Alvin Zhang <alvinx.zhang@intel.com>

Implement device detection and loading.
Add igc driver guid docs.

Signed-off-by: Alvin Zhang <alvinx.zhang@intel.com>

v2: Update release note. Modify codes according to comments
v3: Modify codes according to comments
    Fix secondary process hotplug fault
---
 MAINTAINERS                             |   7 +
 config/common_base                      |   7 +
 doc/guides/nics/features/igc.ini        |   8 ++
 doc/guides/nics/igc.rst                 |  42 ++++++
 doc/guides/nics/index.rst               |   1 +
 doc/guides/rel_notes/release_20_05.rst  |   5 +
 drivers/net/Makefile                    |   1 +
 drivers/net/igc/Makefile                |  25 ++++
 drivers/net/igc/igc_ethdev.c            | 246 ++++++++++++++++++++++++++++++++
 drivers/net/igc/igc_ethdev.h            |  18 +++
 drivers/net/igc/igc_logs.c              |  22 +++
 drivers/net/igc/igc_logs.h              |  34 +++++
 drivers/net/igc/meson.build             |   7 +
 drivers/net/igc/rte_pmd_igc_version.map |   3 +
 drivers/net/meson.build                 |   1 +
 mk/rte.app.mk                           |   1 +
 16 files changed, 428 insertions(+)
 create mode 100644 doc/guides/nics/features/igc.ini
 create mode 100644 doc/guides/nics/igc.rst
 create mode 100644 drivers/net/igc/Makefile
 create mode 100644 drivers/net/igc/igc_ethdev.c
 create mode 100644 drivers/net/igc/igc_ethdev.h
 create mode 100644 drivers/net/igc/igc_logs.c
 create mode 100644 drivers/net/igc/igc_logs.h
 create mode 100644 drivers/net/igc/meson.build
 create mode 100644 drivers/net/igc/rte_pmd_igc_version.map
  

Comments

Stephen Hemminger April 13, 2020, 3:19 p.m. UTC | #1
On Mon, 13 Apr 2020 14:30:27 +0800
alvinx.zhang@intel.com wrote:

> +	if (dev->data->mac_addrs == NULL) {
> +		PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to "
> +				"store MAC addresses", RTE_ETHER_ADDR_LEN);

Stylistic note.
Please don't break messages across multiple lines, it makes it harder to
read, and also harder for users to search for error messages.

If you are concerned about checkpatch, checkpatch allows long lines for
messages.

		PMD_INIT_LOG(ERR,
			     "Failed allocation for MAC address");
  

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 2f5709b..9ec0f20 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -691,6 +691,13 @@  F: drivers/net/ice/
 F: doc/guides/nics/ice.rst
 F: doc/guides/nics/features/ice.ini
 
+Intel igc
+M: Alvin Zhang <alvinx.zhang@intel.com>
+T: git://dpdk.org/next/dpdk-next-net-intel
+F: drivers/net/igc/
+F: doc/guides/nics/igc.rst
+F: doc/guides/nics/features/igc.ini
+
 Intel ipn3ke
 M: Rosen Xu <rosen.xu@intel.com>
 T: git://dpdk.org/next/dpdk-next-net-intel
diff --git a/config/common_base b/config/common_base
index c31175f..00d8d07 100644
--- a/config/common_base
+++ b/config/common_base
@@ -353,6 +353,13 @@  CONFIG_RTE_LIBRTE_IAVF_16BYTE_RX_DESC=n
 CONFIG_RTE_LIBRTE_IPN3KE_PMD=n
 
 #
+# Compile burst-oriented IGC PMD drivers
+#
+CONFIG_RTE_LIBRTE_IGC_PMD=y
+CONFIG_RTE_LIBRTE_IGC_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_IGC_DEBUG_TX=n
+
+#
 # Compile burst-oriented Mellanox ConnectX-3 (MLX4) PMD
 #
 CONFIG_RTE_LIBRTE_MLX4_PMD=n
diff --git a/doc/guides/nics/features/igc.ini b/doc/guides/nics/features/igc.ini
new file mode 100644
index 0000000..ad75cc4
--- /dev/null
+++ b/doc/guides/nics/features/igc.ini
@@ -0,0 +1,8 @@ 
+; Supported features of the 'igc' network poll mode driver.
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+[Features]
+Linux UIO            = Y
+Linux VFIO           = Y
+x86-64               = Y
diff --git a/doc/guides/nics/igc.rst b/doc/guides/nics/igc.rst
new file mode 100644
index 0000000..8dcbf2c
--- /dev/null
+++ b/doc/guides/nics/igc.rst
@@ -0,0 +1,42 @@ 
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2019-2020 Intel Corporation.
+
+IGC Poll Mode Driver
+======================
+
+The IGC PMD (librte_pmd_igc) provides poll mode driver support for Foxville
+I225 Series Network Adapters.
+
+- For information about I225, please refer to:
+  `https://ark.intel.com/content/www/us/en/ark/products/series/184686/
+  intel-ethernet-controller-i225-series.html`
+
+Config File Options
+~~~~~~~~~~~~~~~~~~~
+
+The following options can be modified in the ``config`` file.
+Please note that enabling debugging options may affect system performance.
+
+- ``CONFIG_RTE_LIBRTE_IGC_PMD`` (default ``y``)
+
+  Toggle compilation of the ``librte_pmd_igc`` driver.
+
+- ``CONFIG_RTE_LIBRTE_IGC_DEBUG_*`` (default ``n``)
+
+  Toggle display of generic debugging messages.
+
+
+Driver compilation and testing
+------------------------------
+
+Refer to the document :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
+for details.
+
+
+Supported Chipsets and NICs
+---------------------------
+
+Foxville LM (I225 LM): Client 2.5G LAN vPro Corporate
+Foxville V (I225 V): Client 2.5G LAN Consumer
+Foxville I (I225 I): Client 2.5G Industrial Temp
+Foxville V (I225 K): Client 2.5G LAN Consumer
diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst
index 6d88028..7312d56 100644
--- a/doc/guides/nics/index.rst
+++ b/doc/guides/nics/index.rst
@@ -32,6 +32,7 @@  Network Interface Controller Drivers
     i40e
     ice
     igb
+    igc
     ionic
     ipn3ke
     ixgbe
diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
index 4b81893..b802bdd 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -99,6 +99,11 @@  New Features
 
   * Added generic filter support.
 
+* **Added a new driver for Intel Foxville I225 devices.**
+
+  Added the new ``igc`` net driver for Intel Foxville I225 devices. See the
+  :doc:`../nics/igc` NIC guide for more details on this new driver.
+
 Removed Items
 -------------
 
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 4a7f155..361974e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -34,6 +34,7 @@  DIRS-$(CONFIG_RTE_LIBRTE_HNS3_PMD) += hns3
 DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e
 DIRS-$(CONFIG_RTE_LIBRTE_IAVF_PMD) += iavf
 DIRS-$(CONFIG_RTE_LIBRTE_ICE_PMD) += ice
+DIRS-$(CONFIG_RTE_LIBRTE_IGC_PMD) += igc
 DIRS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic
 DIRS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += ipn3ke
 DIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe
diff --git a/drivers/net/igc/Makefile b/drivers/net/igc/Makefile
new file mode 100644
index 0000000..ee1d8d8
--- /dev/null
+++ b/drivers/net/igc/Makefile
@@ -0,0 +1,25 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019-2020 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_igc.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_ethdev
+LDLIBS += -lrte_bus_pci
+
+EXPORT_MAP := rte_pmd_igc_version.map
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_IGC_PMD) += igc_logs.c
+SRCS-$(CONFIG_RTE_LIBRTE_IGC_PMD) += igc_ethdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/igc/igc_ethdev.c b/drivers/net/igc/igc_ethdev.c
new file mode 100644
index 0000000..29cf6eb
--- /dev/null
+++ b/drivers/net/igc/igc_ethdev.c
@@ -0,0 +1,246 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Intel Corporation
+ */
+
+#include <stdint.h>
+
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_ethdev_driver.h>
+#include <rte_ethdev_pci.h>
+#include <rte_malloc.h>
+
+#include "igc_logs.h"
+#include "igc_ethdev.h"
+
+#define IGC_INTEL_VENDOR_ID		0x8086
+#define IGC_DEV_ID_I225_LM		0x15F2
+#define IGC_DEV_ID_I225_V		0x15F3
+#define IGC_DEV_ID_I225_K		0x3100
+#define IGC_DEV_ID_I225_I		0x15F8
+#define IGC_DEV_ID_I220_V		0x15F7
+
+static const struct rte_pci_id pci_id_igc_map[] = {
+	{ RTE_PCI_DEVICE(IGC_INTEL_VENDOR_ID, IGC_DEV_ID_I225_LM) },
+	{ RTE_PCI_DEVICE(IGC_INTEL_VENDOR_ID, IGC_DEV_ID_I225_V)  },
+	{ RTE_PCI_DEVICE(IGC_INTEL_VENDOR_ID, IGC_DEV_ID_I225_I)  },
+	{ RTE_PCI_DEVICE(IGC_INTEL_VENDOR_ID, IGC_DEV_ID_I225_K)  },
+	{ .vendor_id = 0, /* sentinel */ },
+};
+
+static int eth_igc_configure(struct rte_eth_dev *dev);
+static int eth_igc_link_update(struct rte_eth_dev *dev, int wait_to_complete);
+static void eth_igc_stop(struct rte_eth_dev *dev);
+static int eth_igc_start(struct rte_eth_dev *dev);
+static void eth_igc_close(struct rte_eth_dev *dev);
+static int eth_igc_reset(struct rte_eth_dev *dev);
+static int eth_igc_promiscuous_enable(struct rte_eth_dev *dev);
+static int eth_igc_promiscuous_disable(struct rte_eth_dev *dev);
+static int eth_igc_infos_get(struct rte_eth_dev *dev,
+			struct rte_eth_dev_info *dev_info);
+static int
+eth_igc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
+		uint16_t nb_rx_desc, unsigned int socket_id,
+		const struct rte_eth_rxconf *rx_conf,
+		struct rte_mempool *mb_pool);
+static int
+eth_igc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
+		uint16_t nb_desc, unsigned int socket_id,
+		const struct rte_eth_txconf *tx_conf);
+
+static const struct eth_dev_ops eth_igc_ops = {
+	.dev_configure		= eth_igc_configure,
+	.link_update		= eth_igc_link_update,
+	.dev_stop		= eth_igc_stop,
+	.dev_start		= eth_igc_start,
+	.dev_close		= eth_igc_close,
+	.dev_reset		= eth_igc_reset,
+	.promiscuous_enable	= eth_igc_promiscuous_enable,
+	.promiscuous_disable	= eth_igc_promiscuous_disable,
+	.dev_infos_get		= eth_igc_infos_get,
+	.rx_queue_setup		= eth_igc_rx_queue_setup,
+	.tx_queue_setup		= eth_igc_tx_queue_setup,
+};
+
+static int
+eth_igc_configure(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	RTE_SET_USED(dev);
+	return 0;
+}
+
+static int
+eth_igc_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+	PMD_INIT_FUNC_TRACE();
+	RTE_SET_USED(dev);
+	RTE_SET_USED(wait_to_complete);
+	return 0;
+}
+
+static void
+eth_igc_stop(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	RTE_SET_USED(dev);
+}
+
+static int
+eth_igc_start(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	RTE_SET_USED(dev);
+	return 0;
+}
+
+static void
+eth_igc_close(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	 RTE_SET_USED(dev);
+}
+
+static int
+eth_igc_dev_init(struct rte_eth_dev *dev)
+{
+	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+
+	PMD_INIT_FUNC_TRACE();
+	dev->dev_ops = &eth_igc_ops;
+
+	/*
+	 * for secondary processes, we don't initialize any further as primary
+	 * has already done this work. Only check we don't need a different
+	 * RX function.
+	 */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	dev->data->mac_addrs = rte_zmalloc("igc",
+		RTE_ETHER_ADDR_LEN, 0);
+	if (dev->data->mac_addrs == NULL) {
+		PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to "
+				"store MAC addresses", RTE_ETHER_ADDR_LEN);
+		return -ENOMEM;
+	}
+
+	/* Pass the information to the rte_eth_dev_close() that it should also
+	 * release the private port resources.
+	 */
+	dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
+
+	PMD_INIT_LOG(DEBUG, "port_id %d vendorID=0x%x deviceID=0x%x",
+			dev->data->port_id, pci_dev->id.vendor_id,
+			pci_dev->id.device_id);
+
+	return 0;
+}
+
+static int
+eth_igc_dev_uninit(__rte_unused struct rte_eth_dev *eth_dev)
+{
+	PMD_INIT_FUNC_TRACE();
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	eth_igc_close(eth_dev);
+	return 0;
+}
+
+static int
+eth_igc_reset(struct rte_eth_dev *dev)
+{
+	int ret;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ret = eth_igc_dev_uninit(dev);
+	if (ret)
+		return ret;
+
+	return eth_igc_dev_init(dev);
+}
+
+static int
+eth_igc_promiscuous_enable(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	RTE_SET_USED(dev);
+	return 0;
+}
+
+static int
+eth_igc_promiscuous_disable(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	RTE_SET_USED(dev);
+	return 0;
+}
+
+static int
+eth_igc_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
+{
+	PMD_INIT_FUNC_TRACE();
+	RTE_SET_USED(dev);
+	dev_info->max_rx_queues = IGC_QUEUE_PAIRS_NUM;
+	dev_info->max_tx_queues = IGC_QUEUE_PAIRS_NUM;
+	return 0;
+}
+
+static int
+eth_igc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
+		uint16_t nb_rx_desc, unsigned int socket_id,
+		const struct rte_eth_rxconf *rx_conf,
+		struct rte_mempool *mb_pool)
+{
+	PMD_INIT_FUNC_TRACE();
+	RTE_SET_USED(dev);
+	RTE_SET_USED(rx_queue_id);
+	RTE_SET_USED(nb_rx_desc);
+	RTE_SET_USED(socket_id);
+	RTE_SET_USED(rx_conf);
+	RTE_SET_USED(mb_pool);
+	return 0;
+}
+
+static int
+eth_igc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
+		uint16_t nb_desc, unsigned int socket_id,
+		const struct rte_eth_txconf *tx_conf)
+{
+	PMD_INIT_FUNC_TRACE();
+	RTE_SET_USED(dev);
+	RTE_SET_USED(queue_idx);
+	RTE_SET_USED(nb_desc);
+	RTE_SET_USED(socket_id);
+	RTE_SET_USED(tx_conf);
+	return 0;
+}
+
+static int
+eth_igc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+	struct rte_pci_device *pci_dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	return rte_eth_dev_pci_generic_probe(pci_dev, 0, eth_igc_dev_init);
+}
+
+static int
+eth_igc_pci_remove(struct rte_pci_device *pci_dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	return rte_eth_dev_pci_generic_remove(pci_dev, eth_igc_dev_uninit);
+}
+
+static struct rte_pci_driver rte_igc_pmd = {
+	.id_table = pci_id_igc_map,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
+	.probe = eth_igc_pci_probe,
+	.remove = eth_igc_pci_remove,
+};
+
+RTE_PMD_REGISTER_PCI(net_igc, rte_igc_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(net_igc, pci_id_igc_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_igc, "* igb_uio | uio_pci_generic | vfio-pci");
diff --git a/drivers/net/igc/igc_ethdev.h b/drivers/net/igc/igc_ethdev.h
new file mode 100644
index 0000000..d696b6e
--- /dev/null
+++ b/drivers/net/igc/igc_ethdev.h
@@ -0,0 +1,18 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Intel Corporation
+ */
+
+#ifndef _IGC_ETHDEV_H_
+#define _IGC_ETHDEV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IGC_QUEUE_PAIRS_NUM		4
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IGC_ETHDEV_H_ */
diff --git a/drivers/net/igc/igc_logs.c b/drivers/net/igc/igc_logs.c
new file mode 100644
index 0000000..eff7640
--- /dev/null
+++ b/drivers/net/igc/igc_logs.c
@@ -0,0 +1,22 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Intel Corporation
+ */
+
+#include <rte_common.h>
+
+#include "igc_logs.h"
+
+/* declared as extern in igc_logs.h */
+int igc_logtype_init;
+int igc_logtype_driver;
+
+RTE_INIT(igc_init_log)
+{
+	igc_logtype_init = rte_log_register("pmd.net.igc.init");
+	if (igc_logtype_init >= 0)
+		rte_log_set_level(igc_logtype_init, RTE_LOG_INFO);
+
+	igc_logtype_driver = rte_log_register("pmd.net.igc.driver");
+	if (igc_logtype_driver >= 0)
+		rte_log_set_level(igc_logtype_driver, RTE_LOG_INFO);
+}
diff --git a/drivers/net/igc/igc_logs.h b/drivers/net/igc/igc_logs.h
new file mode 100644
index 0000000..67b1699
--- /dev/null
+++ b/drivers/net/igc/igc_logs.h
@@ -0,0 +1,34 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019-2020 Intel Corporation
+ */
+
+#ifndef _IGC_LOGS_H_
+#define _IGC_LOGS_H_
+
+#include <rte_log.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int igc_logtype_init;
+extern int igc_logtype_driver;
+
+#define PMD_INIT_LOG(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, igc_logtype_init, \
+		"%s(): " fmt "\n", __func__, ##args)
+
+#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
+
+#define PMD_DRV_LOG_RAW(level, fmt, args...) \
+	rte_log(RTE_LOG_ ## level, igc_logtype_driver, "%s(): " fmt, \
+		__func__, ## args)
+
+#define PMD_DRV_LOG(level, fmt, args...) \
+	PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IGC_LOGS_H_ */
diff --git a/drivers/net/igc/meson.build b/drivers/net/igc/meson.build
new file mode 100644
index 0000000..22dd1cf
--- /dev/null
+++ b/drivers/net/igc/meson.build
@@ -0,0 +1,7 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019-2020 Intel Corporation
+
+sources = files(
+	'igc_logs.c',
+	'igc_ethdev.c'
+)
diff --git a/drivers/net/igc/rte_pmd_igc_version.map b/drivers/net/igc/rte_pmd_igc_version.map
new file mode 100644
index 0000000..0a58b9d
--- /dev/null
+++ b/drivers/net/igc/rte_pmd_igc_version.map
@@ -0,0 +1,3 @@ 
+DPDK_20.0.2 {
+	local: *;
+};
diff --git a/drivers/net/meson.build b/drivers/net/meson.build
index b0ea8fe..266448f 100644
--- a/drivers/net/meson.build
+++ b/drivers/net/meson.build
@@ -21,6 +21,7 @@  drivers = ['af_packet',
 	'hns3',
 	'iavf',
 	'ice',
+	'igc',
 	'ipn3ke',
 	'ixgbe',
 	'kni',
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index f3798a0..8f139fd 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -189,6 +189,7 @@  IAVF-y += $(CONFIG_RTE_LIBRTE_ICE_PMD)
 ifeq ($(findstring y,$(IAVF-y)),y)
 _LDLIBS-y += -lrte_common_iavf
 endif
+_LDLIBS-$(CONFIG_RTE_LIBRTE_IGC_PMD)        += -lrte_pmd_igc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IONIC_PMD)      += -lrte_pmd_ionic
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)      += -lrte_pmd_ixgbe
 ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)