diff --git a/igb/igb_main.c b/igb/igb_main.c
index 16430a8..8d0c29d 100644
--- a/igb/igb_main.c
+++ b/igb/igb_main.c
@@ -257,6 +257,10 @@ static int debug = -1;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_igb_netmap.h>
+#endif
+
 struct igb_reg_info {
 	u32 ofs;
 	char *name;
@@ -1751,6 +1755,10 @@ int igb_up(struct igb_adapter *adapter)
 
 	netif_tx_start_all_queues(adapter->netdev);
 
+#ifdef DEV_NETMAP
+	netmap_enable_all_rings(adapter->netdev);
+#endif /* DEV_NETMAP */
+
 	/* start the watchdog. */
 	hw->mac.get_link_status = 1;
 	schedule_work(&adapter->watchdog_task);
@@ -1798,6 +1806,9 @@ void igb_down(struct igb_adapter *adapter)
 		napi_disable(&(adapter->q_vector[i]->napi));
 	}
 
+#ifdef DEV_NETMAP
+	netmap_disable_all_rings(netdev);
+#endif /* DEV_NETMAP */
 
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_info_timer);
@@ -2540,6 +2551,10 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	/* carrier off reporting is important to ethtool even BEFORE open */
 	netif_carrier_off(netdev);
 
+#ifdef DEV_NETMAP
+	igb_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
 #ifdef CONFIG_IGB_DCA
 	if (dca_add_requester(&pdev->dev) == 0) {
 		adapter->flags |= IGB_FLAG_DCA_ENABLED;
@@ -2805,6 +2820,10 @@ static void igb_remove(struct pci_dev *pdev)
 		wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_DISABLE);
 	}
 #endif
+#ifdef DEV_NETMAP
+	netmap_detach(netdev);
+#endif /* DEV_NETMAP */
+
 
 	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
 	 * would have already happened in close and is redundant.
@@ -3083,6 +3102,10 @@ static int __igb_open(struct net_device *netdev, bool resuming)
 
 	netif_tx_start_all_queues(netdev);
 
+#ifdef DEV_NETMAP
+	netmap_enable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
 	if (!resuming)
 		pm_runtime_put(&pdev->dev);
 
@@ -3276,6 +3299,9 @@ void igb_configure_tx_ring(struct igb_adapter *adapter,
 
 	txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
 	wr32(E1000_TXDCTL(reg_idx), txdctl);
+#ifdef DEV_NETMAP
+	igb_netmap_configure_tx_ring(adapter, reg_idx);
+#endif /* DEV_NETMAP */
 }
 
 /**
@@ -6321,6 +6347,10 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
 
 	if (test_bit(__IGB_DOWN, &adapter->state))
 		return true;
+#ifdef DEV_NETMAP
+        if (netmap_tx_irq(tx_ring->netdev, tx_ring->queue_index))
+                return 1; /* cleaned ok */
+#endif /* DEV_NETMAP */
 
 	tx_buffer = &tx_ring->tx_buffer_info[i];
 	tx_desc = IGB_TX_DESC(tx_ring, i);
@@ -6984,6 +7014,10 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
 	unsigned int total_bytes = 0, total_packets = 0;
 	u16 cleaned_count = igb_desc_unused(rx_ring);
 
+#ifdef DEV_NETMAP
+	if (netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &total_packets))
+		return true;
+#endif /* DEV_NETMAP */
 	while (likely(total_packets < budget)) {
 		union e1000_adv_rx_desc *rx_desc;
 
@@ -7101,6 +7135,11 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count)
 	struct igb_rx_buffer *bi;
 	u16 i = rx_ring->next_to_use;
 
+#ifdef DEV_NETMAP
+	if (igb_netmap_configure_rx_ring(rx_ring))
+		return;
+#endif /* DEV_NETMAP */
+
 	/* nothing to do */
 	if (!cleaned_count)
 		return;
