--- /home/luigi/ksrc/linux-2.6.36.1/drivers/net/ixgbe/ixgbe_main.c	2010-11-22 20:03:49.000000000 +0100
+++ net/ixgbe/ixgbe_main.c	2012-07-31 13:52:18.000000000 +0200
@@ -214,6 +214,22 @@ static const struct ixgbe_reg_info ixgbe
 	{}
 };
 
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+/*
+ * The #ifdef DEV_NETMAP / #endif blocks in this file are meant to
+ * be a reference on how to implement netmap support in a driver.
+ * Additional comments are in ixgbe_netmap_linux.h .
+ *
+ * The code is originally developed on FreeBSD and in the interest
+ * of maintainability we try to limit differences between the two systems.
+ *
+ * <ixgbe_netmap_linux.h> contains functions for netmap support
+ * that extend the standard driver.
+ * It also defines DEV_NETMAP so further conditional sections use
+ * that instead of CONFIG_NETMAP
+ */
+#include <ixgbe_netmap_linux.h>
+#endif
 
 /*
  * ixgbe_regdump - register printout routine
@@ -741,6 +757,16 @@ static bool ixgbe_clean_tx_irq(struct ix
 	unsigned int i, eop, count = 0;
 	unsigned int total_bytes = 0, total_packets = 0;
 
+#ifdef DEV_NETMAP
+	/*
+	 * In netmap mode, all the work is done in the context
+	 * of the client thread. Interrupt handlers only wake up
+	 * clients, which may be sleeping on individual rings
+	 * or on a global resource for all rings.
+	 */
+	if (netmap_tx_irq(adapter->netdev, tx_ring->queue_index))
+		return 1; /* seems to be ignored */
+#endif /* DEV_NETMAP */
 	i = tx_ring->next_to_clean;
 	eop = tx_ring->tx_buffer_info[i].next_to_watch;
 	eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
@@ -1187,6 +1213,13 @@ static bool ixgbe_clean_rx_irq(struct ix
 	int ddp_bytes = 0;
 #endif /* IXGBE_FCOE */
 
+#ifdef DEV_NETMAP
+	/*
+	 * Same as the txeof routine: only wakeup clients on intr.
+	 */
+	if (netmap_rx_irq(adapter->netdev, rx_ring->queue_index, work_done))
+		return;
+#endif /* DEV_NETMAP */
 	i = rx_ring->next_to_clean;
 	rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
 	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
@@ -3217,6 +3250,12 @@ static void ixgbe_configure(struct ixgbe
 
 	ixgbe_configure_tx(adapter);
 	ixgbe_configure_rx(adapter);
+#ifdef DEV_NETMAP
+	for (i = 0; i < adapter->num_rx_queues; i++)
+		ixgbe_netmap_configure_tx_ring(adapter,
+			adapter->rx_ring[i].reg_idx);
+	return;
+#endif /* DEV_NETMAP */
 	for (i = 0; i < adapter->num_rx_queues; i++)
 		ixgbe_alloc_rx_buffers(adapter, adapter->rx_ring[i],
 		                       (adapter->rx_ring[i]->count - 1));
@@ -3447,6 +3486,10 @@ static int ixgbe_up_complete(struct ixgb
 			if (!wait_loop)
 				e_err(drv, "Could not enable Tx Queue %d\n", j);
 		}
+#ifdef DEV_NETMAP // XXX i and j are the same ?
+		ixgbe_netmap_configure_tx_ring(adapter, j);
+#endif /* DEV_NETMAP */
+
 	}
 
 	for (i = 0; i < num_rx_rings; i++) {
@@ -5139,6 +5182,9 @@ static int ixgbe_open(struct net_device
 		goto err_up;
 
 	netif_tx_start_all_queues(netdev);
+#ifdef DEV_NETMAP
+	ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
 
 	return 0;
 
