[v1,01/15] net/igc: add igc PMD

Message ID 1583742247-370386-1-git-send-email-alvinx.zhang@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series [v1,01/15] net/igc: add igc PMD |

Checks

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

Commit Message

Alvin Zhang March 9, 2020, 8:23 a.m. UTC
  From: Alvin Zhang <alvinx.zhang@intel.com>

Implement device detection and loading.

Signed-off-by: Alvin Zhang <alvinx.zhang@intel.com>
---
 MAINTAINERS                             |   7 +
 config/common_base                      |   7 +
 doc/guides/nics/features/igc.ini        |   8 +
 doc/guides/nics/igc.rst                 |  39 +++++
 doc/guides/nics/index.rst               |   1 +
 drivers/net/Makefile                    |   1 +
 drivers/net/igc/Makefile                |  25 ++++
 drivers/net/igc/igc_ethdev.c            | 249 ++++++++++++++++++++++++++++++++
 drivers/net/igc/igc_ethdev.h            |  18 +++
 drivers/net/igc/igc_logs.c              |  21 +++
 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 +
 15 files changed, 422 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

Xiaolong Ye March 9, 2020, 8:35 a.m. UTC | #1
Hi, Alvin

Thanks for the patch, before going through the whole series, one comment is
that for such big patch set, better to send it with cover letter which can give
some background, simple intro about the patch structure and changlog as well
for later version.

Thanks,
Xiaolong

On 03/09, alvinx.zhang@intel.com wrote:
>From: Alvin Zhang <alvinx.zhang@intel.com>
>
>Implement device detection and loading.
>
>Signed-off-by: Alvin Zhang <alvinx.zhang@intel.com>
>---
> MAINTAINERS                             |   7 +
> config/common_base                      |   7 +
> doc/guides/nics/features/igc.ini        |   8 +
> doc/guides/nics/igc.rst                 |  39 +++++
> doc/guides/nics/index.rst               |   1 +
> drivers/net/Makefile                    |   1 +
> drivers/net/igc/Makefile                |  25 ++++
> drivers/net/igc/igc_ethdev.c            | 249 ++++++++++++++++++++++++++++++++
> drivers/net/igc/igc_ethdev.h            |  18 +++
> drivers/net/igc/igc_logs.c              |  21 +++
> 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 +
> 15 files changed, 422 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
>
>diff --git a/MAINTAINERS b/MAINTAINERS
>index c378555..68a92b4 100644
>--- a/MAINTAINERS
>+++ b/MAINTAINERS
>@@ -704,6 +704,13 @@ F: drivers/net/ipn3ke/
> F: doc/guides/nics/ipn3ke.rst
> F: doc/guides/nics/features/ipn3ke.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
>+
> Marvell mvpp2
> M: Tomasz Duszynski <tdu@semihalf.com>
> M: Liron Himi <lironh@marvell.com>
>diff --git a/config/common_base b/config/common_base
>index c31175f..ebc7323 100644
>--- a/config/common_base
>+++ b/config/common_base
>@@ -283,6 +283,13 @@ CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
> CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=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 HINIC PMD driver
> #
> CONFIG_RTE_LIBRTE_HINIC_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..4c7176a
>--- /dev/null
>+++ b/doc/guides/nics/igc.rst
>@@ -0,0 +1,39 @@
>+..  SPDX-License-Identifier: BSD-3-Clause
>+    Copyright(c) 2016 Intel Corporation.
>+
>+IGC Poll Mode Driver
>+======================
>+
>+The IGC PMD (librte_pmd_igc) provides poll mode driver support for
>+Foxville and Greenvile I225 Series Network Adapters.
>+
>+
>+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
>+Greenville (I220 V): Client 1G LAN Consumer
>+Foxville V (I225 V): Client 2.5G LAN Consumer
>+Foxville I (I225 I): Client 2.5G Industrial Temp
>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/drivers/net/Makefile b/drivers/net/Makefile
>index 4a7f155..b57841d 100644
>--- a/drivers/net/Makefile
>+++ b/drivers/net/Makefile
>@@ -61,6 +61,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
> DIRS-$(CONFIG_RTE_LIBRTE_VDEV_NETVSC_PMD) += vdev_netvsc
> DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
> DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
>+DIRS-$(CONFIG_RTE_LIBRTE_IGC_PMD) += igc
> 
> ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_KNI) += kni
>diff --git a/drivers/net/igc/Makefile b/drivers/net/igc/Makefile
>new file mode 100644
>index 0000000..7b51daf
>--- /dev/null
>+++ b/drivers/net/igc/Makefile
>@@ -0,0 +1,25 @@
>+# SPDX-License-Identifier: BSD-3-Clause
>+# Copyright(c) 2010-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..2baba69
>--- /dev/null
>+++ b/drivers/net/igc/igc_ethdev.c
>@@ -0,0 +1,249 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2010-2020 Intel Corporation
>+ */
>+
>+#include <rte_pci.h>
>+#include <rte_bus_pci.h>
>+#include <rte_ethdev_driver.h>
>+#include <rte_ethdev_pci.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_V)  },
>+	{ 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;
>+
>+	rte_eth_copy_pci_info(dev, pci_dev);
>+
>+	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 -ENODEV;
>+	}
>+
>+	/* 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 -EPERM;
>+
>+	eth_igc_close(eth_dev);
>+	return 0;
>+}
>+
>+/*
>+ * Reset PF device.
>+ */
>+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 __rte_unused)
>+{
>+	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..a774413
>--- /dev/null
>+++ b/drivers/net/igc/igc_ethdev.h
>@@ -0,0 +1,18 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2010-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..c653783
>--- /dev/null
>+++ b/drivers/net/igc/igc_logs.c
>@@ -0,0 +1,21 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2020 Intel Corporation
>+ */
>+
>+#include "igc_logs.h"
>+#include "rte_common.h"
>+
>+/* declared as extern in igc_logs.h */
>+int igc_logtype_init = -1;
>+int igc_logtype_driver = -1;
>+
>+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..eed4f46
>--- /dev/null
>+++ b/drivers/net/igc/igc_logs.h
>@@ -0,0 +1,34 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2010-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..927938f
>--- /dev/null
>+++ b/drivers/net/igc/meson.build
>@@ -0,0 +1,7 @@
>+# SPDX-License-Identifier: BSD-3-Clause
>+# Copyright(c) 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..f9f17e4
>--- /dev/null
>+++ b/drivers/net/igc/rte_pmd_igc_version.map
>@@ -0,0 +1,3 @@
>+DPDK_20.0 {
>+	local: *;
>+};
>diff --git a/drivers/net/meson.build b/drivers/net/meson.build
>index b0ea8fe..7d0ae3b 100644
>--- a/drivers/net/meson.build
>+++ b/drivers/net/meson.build
>@@ -49,6 +49,7 @@ drivers = ['af_packet',
> 	'vhost',
> 	'virtio',
> 	'vmxnet3',
>+	'igc',
> ]
> std_deps = ['ethdev', 'kvargs'] # 'ethdev' also pulls in mbuf, net, eal etc
> std_deps += ['bus_pci']         # very many PMDs depend on PCI, so make std
>diff --git a/mk/rte.app.mk b/mk/rte.app.mk
>index d295ca0..afd570b 100644
>--- a/mk/rte.app.mk
>+++ b/mk/rte.app.mk
>@@ -184,6 +184,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_HNS3_PMD)       += -lrte_pmd_hns3
> _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
> _LDLIBS-$(CONFIG_RTE_LIBRTE_IAVF_PMD)       += -lrte_pmd_iavf
> _LDLIBS-$(CONFIG_RTE_LIBRTE_ICE_PMD)        += -lrte_pmd_ice
>+_LDLIBS-$(CONFIG_RTE_LIBRTE_IGC_PMD)        += -lrte_pmd_igc
> IAVF-y := $(CONFIG_RTE_LIBRTE_IAVF_PMD)
> ifeq ($(findstring y,$(IAVF-y)),y)
> _LDLIBS-y += -lrte_common_iavf
>-- 
>1.8.3.1
>
  
Xiaolong Ye March 12, 2020, 3:09 a.m. UTC | #2
On 03/09, alvinx.zhang@intel.com wrote:
>From: Alvin Zhang <alvinx.zhang@intel.com>
>
>Implement device detection and loading.
>
>Signed-off-by: Alvin Zhang <alvinx.zhang@intel.com>
>---
> MAINTAINERS                             |   7 +
> config/common_base                      |   7 +
> doc/guides/nics/features/igc.ini        |   8 +
> doc/guides/nics/igc.rst                 |  39 +++++
> doc/guides/nics/index.rst               |   1 +
> drivers/net/Makefile                    |   1 +
> drivers/net/igc/Makefile                |  25 ++++
> drivers/net/igc/igc_ethdev.c            | 249 ++++++++++++++++++++++++++++++++
> drivers/net/igc/igc_ethdev.h            |  18 +++
> drivers/net/igc/igc_logs.c              |  21 +++
> 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 +

Please update the release notes as well.

> 15 files changed, 422 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
>

[snip]

>+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;
>+
>+	rte_eth_copy_pci_info(dev, pci_dev);
>+
>+	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 -ENODEV;

-ENOMEM should be returned.

>+	}
>+
>+	/* 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 -EPERM;
>+
>+	eth_igc_close(eth_dev);
>+	return 0;
>+}
>+
>+/*
>+ * Reset PF device.
>+ */

This function name is straightforward enough, so this comment is unnecessary.

>+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 __rte_unused)

pci_dev is actually used in below function.

>+{
>+	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..a774413
>--- /dev/null
>+++ b/drivers/net/igc/igc_ethdev.h
>@@ -0,0 +1,18 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2010-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..c653783
>--- /dev/null
>+++ b/drivers/net/igc/igc_logs.c
>@@ -0,0 +1,21 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2020 Intel Corporation
>+ */
>+
>+#include "igc_logs.h"
>+#include "rte_common.h"
>+
>+/* declared as extern in igc_logs.h */
>+int igc_logtype_init = -1;
>+int igc_logtype_driver = -1;
>+
>+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..eed4f46
>--- /dev/null
>+++ b/drivers/net/igc/igc_logs.h
>@@ -0,0 +1,34 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2010-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..927938f
>--- /dev/null
>+++ b/drivers/net/igc/meson.build
>@@ -0,0 +1,7 @@
>+# SPDX-License-Identifier: BSD-3-Clause
>+# Copyright(c) 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..f9f17e4
>--- /dev/null
>+++ b/drivers/net/igc/rte_pmd_igc_version.map
>@@ -0,0 +1,3 @@
>+DPDK_20.0 {

Should be DPDK_20.0.1 for new symbols after 19.11.

>+	local: *;
>+};
>diff --git a/drivers/net/meson.build b/drivers/net/meson.build
>index b0ea8fe..7d0ae3b 100644
>--- a/drivers/net/meson.build
>+++ b/drivers/net/meson.build
>@@ -49,6 +49,7 @@ drivers = ['af_packet',
> 	'vhost',
> 	'virtio',
> 	'vmxnet3',
>+	'igc',
> ]
> std_deps = ['ethdev', 'kvargs'] # 'ethdev' also pulls in mbuf, net, eal etc
> std_deps += ['bus_pci']         # very many PMDs depend on PCI, so make std
>diff --git a/mk/rte.app.mk b/mk/rte.app.mk
>index d295ca0..afd570b 100644
>--- a/mk/rte.app.mk
>+++ b/mk/rte.app.mk
>@@ -184,6 +184,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_HNS3_PMD)       += -lrte_pmd_hns3
> _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
> _LDLIBS-$(CONFIG_RTE_LIBRTE_IAVF_PMD)       += -lrte_pmd_iavf
> _LDLIBS-$(CONFIG_RTE_LIBRTE_ICE_PMD)        += -lrte_pmd_ice
>+_LDLIBS-$(CONFIG_RTE_LIBRTE_IGC_PMD)        += -lrte_pmd_igc
> IAVF-y := $(CONFIG_RTE_LIBRTE_IAVF_PMD)
> ifeq ($(findstring y,$(IAVF-y)),y)
> _LDLIBS-y += -lrte_common_iavf
>-- 
>1.8.3.1
>
  

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index c378555..68a92b4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -704,6 +704,13 @@  F: drivers/net/ipn3ke/
 F: doc/guides/nics/ipn3ke.rst
 F: doc/guides/nics/features/ipn3ke.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
+
 Marvell mvpp2
 M: Tomasz Duszynski <tdu@semihalf.com>
 M: Liron Himi <lironh@marvell.com>
diff --git a/config/common_base b/config/common_base
index c31175f..ebc7323 100644
--- a/config/common_base
+++ b/config/common_base
@@ -283,6 +283,13 @@  CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
 CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=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 HINIC PMD driver
 #
 CONFIG_RTE_LIBRTE_HINIC_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..4c7176a
--- /dev/null
+++ b/doc/guides/nics/igc.rst
@@ -0,0 +1,39 @@ 
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2016 Intel Corporation.
+
+IGC Poll Mode Driver
+======================
+
+The IGC PMD (librte_pmd_igc) provides poll mode driver support for
+Foxville and Greenvile I225 Series Network Adapters.
+
+
+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
+Greenville (I220 V): Client 1G LAN Consumer
+Foxville V (I225 V): Client 2.5G LAN Consumer
+Foxville I (I225 I): Client 2.5G Industrial Temp
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/drivers/net/Makefile b/drivers/net/Makefile
index 4a7f155..b57841d 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -61,6 +61,7 @@  DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx
 DIRS-$(CONFIG_RTE_LIBRTE_VDEV_NETVSC_PMD) += vdev_netvsc
 DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
+DIRS-$(CONFIG_RTE_LIBRTE_IGC_PMD) += igc
 
 ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_KNI) += kni
diff --git a/drivers/net/igc/Makefile b/drivers/net/igc/Makefile
new file mode 100644
index 0000000..7b51daf
--- /dev/null
+++ b/drivers/net/igc/Makefile
@@ -0,0 +1,25 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2010-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..2baba69
--- /dev/null
+++ b/drivers/net/igc/igc_ethdev.c
@@ -0,0 +1,249 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2020 Intel Corporation
+ */
+
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_ethdev_driver.h>
+#include <rte_ethdev_pci.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_V)  },
+	{ 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;
+
+	rte_eth_copy_pci_info(dev, pci_dev);
+
+	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 -ENODEV;
+	}
+
+	/* 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 -EPERM;
+
+	eth_igc_close(eth_dev);
+	return 0;
+}
+
+/*
+ * Reset PF device.
+ */
+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 __rte_unused)
+{
+	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..a774413
--- /dev/null
+++ b/drivers/net/igc/igc_ethdev.h
@@ -0,0 +1,18 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-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..c653783
--- /dev/null
+++ b/drivers/net/igc/igc_logs.c
@@ -0,0 +1,21 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+
+#include "igc_logs.h"
+#include "rte_common.h"
+
+/* declared as extern in igc_logs.h */
+int igc_logtype_init = -1;
+int igc_logtype_driver = -1;
+
+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..eed4f46
--- /dev/null
+++ b/drivers/net/igc/igc_logs.h
@@ -0,0 +1,34 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-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..927938f
--- /dev/null
+++ b/drivers/net/igc/meson.build
@@ -0,0 +1,7 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 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..f9f17e4
--- /dev/null
+++ b/drivers/net/igc/rte_pmd_igc_version.map
@@ -0,0 +1,3 @@ 
+DPDK_20.0 {
+	local: *;
+};
diff --git a/drivers/net/meson.build b/drivers/net/meson.build
index b0ea8fe..7d0ae3b 100644
--- a/drivers/net/meson.build
+++ b/drivers/net/meson.build
@@ -49,6 +49,7 @@  drivers = ['af_packet',
 	'vhost',
 	'virtio',
 	'vmxnet3',
+	'igc',
 ]
 std_deps = ['ethdev', 'kvargs'] # 'ethdev' also pulls in mbuf, net, eal etc
 std_deps += ['bus_pci']         # very many PMDs depend on PCI, so make std
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d295ca0..afd570b 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -184,6 +184,7 @@  _LDLIBS-$(CONFIG_RTE_LIBRTE_HNS3_PMD)       += -lrte_pmd_hns3
 _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IAVF_PMD)       += -lrte_pmd_iavf
 _LDLIBS-$(CONFIG_RTE_LIBRTE_ICE_PMD)        += -lrte_pmd_ice
+_LDLIBS-$(CONFIG_RTE_LIBRTE_IGC_PMD)        += -lrte_pmd_igc
 IAVF-y := $(CONFIG_RTE_LIBRTE_IAVF_PMD)
 ifeq ($(findstring y,$(IAVF-y)),y)
 _LDLIBS-y += -lrte_common_iavf