- add netmap-libpcap

- add netmap (FreeBSD header files need to be updated with this)
- move prototype perl scripts to prototype/ folder
- create basic structure for sipcap app (no code yet)
This commit is contained in:
farrokhi
2014-07-10 17:04:13 +04:30
parent 19fc3fb80f
commit ccdba9490b
334 changed files with 121141 additions and 0 deletions

View File

@ -0,0 +1,104 @@
diff --git a/e1000/e1000_main.c b/e1000/e1000_main.c
index bcd192c..5de7009 100644
--- a/e1000/e1000_main.c
+++ b/e1000/e1000_main.c
@@ -213,6 +213,10 @@ static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
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_e1000_netmap.h>
+#endif
+
/**
* e1000_init_module - Driver Registration Routine
*
@@ -375,6 +379,10 @@ static void e1000_configure(struct e1000_adapter *adapter)
e1000_configure_tx(adapter);
e1000_setup_rctl(adapter);
e1000_configure_rx(adapter);
+#ifdef DEV_NETMAP
+ if (e1000_netmap_init_buffers(adapter))
+ return;
+#endif /* DEV_NETMAP */
/* call E1000_DESC_UNUSED which always leaves
* at least 1 descriptor unused to make sure
* next_to_use != next_to_clean */
@@ -402,6 +410,10 @@ int e1000_up(struct e1000_adapter *adapter)
netif_wake_queue(adapter->netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(adapter->netdev);
+#endif /* DEV_NETMAP */
+
/* fire a link change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
return 0;
@@ -485,6 +497,10 @@ void e1000_down(struct e1000_adapter *adapter)
ew32(RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
netif_tx_disable(netdev);
/* disable transmits in the hardware */
@@ -1035,6 +1051,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
adapter->wol = adapter->eeprom_wol;
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+#ifdef DEV_NETMAP
+ e1000_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
/* print bus type/speed/width info */
DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
@@ -1113,6 +1133,10 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
+
+#ifdef DEV_NETMAP
+ netmap_detach(netdev);
+#endif /* DEV_NETMAP */
iounmap(hw->hw_addr);
if (hw->flash_address)
@@ -1291,6 +1315,10 @@ static int e1000_open(struct net_device *netdev)
netif_start_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(netdev);
+#endif
+
/* fire a link status change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
@@ -3429,6 +3457,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
unsigned int count = 0;
unsigned int total_tx_bytes=0, total_tx_packets=0;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(netdev, 0))
+ return 1; /* cleaned ok */
+#endif /* DEV_NETMAP */
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
@@ -3795,6 +3827,11 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
bool cleaned = false;
unsigned int total_rx_bytes=0, total_rx_packets=0;
+#ifdef DEV_NETMAP
+ ND("calling netmap_rx_irq");
+ if (netmap_rx_irq(netdev, 0, work_done))
+ return 1; /* seems to be ignored */
+#endif /* DEV_NETMAP */
i = rx_ring->next_to_clean;
rx_desc = E1000_RX_DESC(*rx_ring, i);
buffer_info = &rx_ring->buffer_info[i];

View File

@ -0,0 +1,91 @@
diff --git a/e1000e/netdev.c b/e1000e/netdev.c
index fad8f9e..50f74e2 100644
--- a/e1000e/netdev.c
+++ b/e1000e/netdev.c
@@ -87,6 +87,10 @@ static int e1000_desc_unused(struct e1000_ring *ring)
return ring->count + ring->next_to_clean - ring->next_to_use - 1;
}
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_e1000e_netmap.h>
+#endif
+
/**
* e1000_receive_skb - helper function to handle Rx indications
* @adapter: board private structure
@@ -446,6 +450,10 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
bool cleaned = 0;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(netdev, 0, work_done))
+ return 1; /* seems to be ignored */
+#endif /* DEV_NETMAP */
i = rx_ring->next_to_clean;
rx_desc = E1000_RX_DESC(*rx_ring, i);
buffer_info = &rx_ring->buffer_info[i];
@@ -624,6 +632,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
unsigned int count = 0;
unsigned int total_tx_bytes = 0, total_tx_packets = 0;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(netdev, 0))
+ return 1; /* cleaned ok */
+#endif /* DEV_NETMAP */
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
@@ -2632,6 +2644,10 @@ static void e1000_configure(struct e1000_adapter *adapter)
e1000_configure_tx(adapter);
e1000_setup_rctl(adapter);
e1000_configure_rx(adapter);
+#ifdef DEV_NETMAP
+ if (e1000e_netmap_init_buffers(adapter))
+ return;
+#endif /* DEV_NETMAP */
adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring));
}
@@ -2892,6 +2908,10 @@ void e1000e_down(struct e1000_adapter *adapter)
netif_stop_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
/* disable transmits in the hardware */
tctl = er32(TCTL);
tctl &= ~E1000_TCTL_EN;
@@ -3174,6 +3194,10 @@ static int e1000_open(struct net_device *netdev)
netif_start_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
/* fire a link status change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
@@ -5227,6 +5251,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (err)
goto err_register;
+#ifdef DEV_NETMAP
+ e1000_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
/* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
@@ -5300,6 +5327,10 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
+#ifdef DEV_NETMAP
+ netmap_detach(netdev);
+#endif /* DEV_NETMAP */
+
iounmap(adapter->hw.hw_addr);
if (adapter->hw.flash_address)
iounmap(adapter->hw.flash_address);

View File

@ -0,0 +1,91 @@
diff --git a/e1000e/netdev.c b/e1000e/netdev.c
index 57a7e41..d8bc988 100644
--- a/e1000e/netdev.c
+++ b/e1000e/netdev.c
@@ -435,6 +435,10 @@ static int e1000_desc_unused(struct e1000_ring *ring)
return ring->count + ring->next_to_clean - ring->next_to_use - 1;
}
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_e1000e_netmap.h>
+#endif
+
/**
* e1000_receive_skb - helper function to handle Rx indications
* @adapter: board private structure
@@ -763,6 +767,10 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
bool cleaned = 0;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(netdev, 0, work_done))
+ return 1; /* seems to be ignored */
+#endif /* DEV_NETMAP */
i = rx_ring->next_to_clean;
rx_desc = E1000_RX_DESC(*rx_ring, i);
buffer_info = &rx_ring->buffer_info[i];
@@ -977,6 +985,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
unsigned int count = 0;
unsigned int total_tx_bytes = 0, total_tx_packets = 0;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(netdev, 0))
+ return 1; /* cleaned ok */
+#endif /* DEV_NETMAP */
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
@@ -3001,6 +3013,10 @@ static void e1000_configure(struct e1000_adapter *adapter)
e1000_configure_tx(adapter);
e1000_setup_rctl(adapter);
e1000_configure_rx(adapter);
+#ifdef DEV_NETMAP
+ if (e1000e_netmap_init_buffers(adapter))
+ return;
+#endif /* DEV_NETMAP */
adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring));
}
@@ -3240,6 +3256,10 @@ void e1000e_down(struct e1000_adapter *adapter)
netif_stop_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
/* disable transmits in the hardware */
tctl = er32(TCTL);
tctl &= ~E1000_TCTL_EN;
@@ -3532,6 +3552,10 @@ static int e1000_open(struct net_device *netdev)
netif_start_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
adapter->idle_check = true;
pm_runtime_put(&pdev->dev);
@@ -5716,6 +5740,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (err)
goto err_register;
+#ifdef DEV_NETMAP
+ e1000_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
/* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
@@ -5813,6 +5840,10 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
+#ifdef DEV_NETMAP
+ netmap_detach(netdev);
+#endif /* DEV_NETMAP */
+
iounmap(adapter->hw.hw_addr);
if (adapter->hw.flash_address)
iounmap(adapter->hw.flash_address);

View File

@ -0,0 +1,91 @@
diff --git a/e1000e/netdev.c b/e1000e/netdev.c
index 2198e61..caf2767 100644
--- a/e1000e/netdev.c
+++ b/e1000e/netdev.c
@@ -452,6 +452,10 @@ static int e1000_desc_unused(struct e1000_ring *ring)
return ring->count + ring->next_to_clean - ring->next_to_use - 1;
}
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_e1000e_netmap.h>
+#endif
+
/**
* e1000_receive_skb - helper function to handle Rx indications
* @adapter: board private structure
@@ -849,6 +853,10 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
bool cleaned = 0;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(netdev, 0, work_done))
+ return 1; /* seems to be ignored */
+#endif /* DEV_NETMAP */
i = rx_ring->next_to_clean;
rx_desc = E1000_RX_DESC(*rx_ring, i);
buffer_info = &rx_ring->buffer_info[i];
@@ -1066,6 +1074,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
unsigned int count = 0;
unsigned int total_tx_bytes = 0, total_tx_packets = 0;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(netdev, 0))
+ return 1; /* cleaned ok */
+#endif /* DEV_NETMAP */
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
@@ -3177,6 +3189,10 @@ static void e1000_configure(struct e1000_adapter *adapter)
e1000_configure_tx(adapter);
e1000_setup_rctl(adapter);
e1000_configure_rx(adapter);
+#ifdef DEV_NETMAP
+ if (e1000e_netmap_init_buffers(adapter))
+ return;
+#endif /* DEV_NETMAP */
adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring),
GFP_KERNEL);
}
@@ -3468,6 +3484,10 @@ void e1000e_down(struct e1000_adapter *adapter)
netif_stop_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
/* disable transmits in the hardware */
tctl = er32(TCTL);
tctl &= ~E1000_TCTL_EN;
@@ -3755,6 +3775,10 @@ static int e1000_open(struct net_device *netdev)
netif_start_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
adapter->idle_check = true;
pm_runtime_put(&pdev->dev);
@@ -6147,6 +6171,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (err)
goto err_register;
+#ifdef DEV_NETMAP
+ e1000_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
/* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
@@ -6234,6 +6261,10 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
+#ifdef DEV_NETMAP
+ netmap_detach(netdev);
+#endif /* DEV_NETMAP */
+
iounmap(adapter->hw.hw_addr);
if (adapter->hw.flash_address)
iounmap(adapter->hw.flash_address);

View File

@ -0,0 +1,91 @@
diff --git a/e1000e/netdev.c b/e1000e/netdev.c
index 9520a6a..f6f2df6 100644
--- a/e1000e/netdev.c
+++ b/e1000e/netdev.c
@@ -467,6 +467,10 @@ static int e1000_desc_unused(struct e1000_ring *ring)
return ring->count + ring->next_to_clean - ring->next_to_use - 1;
}
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_e1000e_netmap.h>
+#endif
+
/**
* e1000_receive_skb - helper function to handle Rx indications
* @adapter: board private structure
@@ -875,6 +879,10 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
bool cleaned = false;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(netdev, 0, work_done))
+ return 1; /* seems to be ignored */
+#endif /* DEV_NETMAP */
i = rx_ring->next_to_clean;
rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
@@ -1129,6 +1137,10 @@ static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
unsigned int total_tx_bytes = 0, total_tx_packets = 0;
unsigned int bytes_compl = 0, pkts_compl = 0;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(netdev, 0))
+ return 1; /* cleaned ok */
+#endif /* DEV_NETMAP */
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
@@ -3358,6 +3370,10 @@ static void e1000_configure(struct e1000_adapter *adapter)
e1000e_setup_rss_hash(adapter);
e1000_setup_rctl(adapter);
e1000_configure_rx(adapter);
+#ifdef DEV_NETMAP
+ if (e1000e_netmap_init_buffers(adapter))
+ return;
+#endif /* DEV_NETMAP */
adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), GFP_KERNEL);
}
@@ -3657,6 +3673,10 @@ void e1000e_down(struct e1000_adapter *adapter)
netif_stop_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
/* disable transmits in the hardware */
tctl = er32(TCTL);
tctl &= ~E1000_TCTL_EN;
@@ -3946,6 +3966,10 @@ static int e1000_open(struct net_device *netdev)
adapter->tx_hang_recheck = false;
netif_start_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
adapter->idle_check = true;
pm_runtime_put(&pdev->dev);
@@ -6417,6 +6441,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (err)
goto err_register;
+#ifdef DEV_NETMAP
+ e1000_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
/* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
@@ -6504,6 +6531,10 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
+#ifdef DEV_NETMAP
+ netmap_detach(netdev);
+#endif /* DEV_NETMAP */
+
iounmap(adapter->hw.hw_addr);
if (adapter->hw.flash_address)
iounmap(adapter->hw.flash_address);

View File

@ -0,0 +1,91 @@
diff --git a/e1000e/netdev.c b/e1000e/netdev.c
index 7e615e2..f9d8a88 100644
--- a/e1000e/netdev.c
+++ b/e1000e/netdev.c
@@ -473,6 +473,10 @@ static int e1000_desc_unused(struct e1000_ring *ring)
return ring->count + ring->next_to_clean - ring->next_to_use - 1;
}
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_e1000e_netmap.h>
+#endif
+
/**
* e1000e_systim_to_hwtstamp - convert system time value to hw time stamp
* @adapter: board private structure
@@ -914,6 +918,10 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
bool cleaned = false;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(netdev, 0, work_done))
+ return 1; /* seems to be ignored */
+#endif /* DEV_NETMAP */
i = rx_ring->next_to_clean;
rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
@@ -1203,6 +1211,10 @@ static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
unsigned int total_tx_bytes = 0, total_tx_packets = 0;
unsigned int bytes_compl = 0, pkts_compl = 0;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(netdev, 0))
+ return 1; /* cleaned ok */
+#endif /* DEV_NETMAP */
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
@@ -3685,6 +3697,10 @@ static void e1000_configure(struct e1000_adapter *adapter)
e1000e_setup_rss_hash(adapter);
e1000_setup_rctl(adapter);
e1000_configure_rx(adapter);
+#ifdef DEV_NETMAP
+ if (e1000e_netmap_init_buffers(adapter))
+ return;
+#endif /* DEV_NETMAP */
adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), GFP_KERNEL);
}
@@ -3988,6 +4004,10 @@ void e1000e_down(struct e1000_adapter *adapter)
netif_stop_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
/* disable transmits in the hardware */
tctl = er32(TCTL);
tctl &= ~E1000_TCTL_EN;
@@ -4307,6 +4327,10 @@ static int e1000_open(struct net_device *netdev)
adapter->tx_hang_recheck = false;
netif_start_queue(netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
adapter->idle_check = true;
hw->mac.get_link_status = true;
pm_runtime_put(&pdev->dev);
@@ -6768,6 +6792,9 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto err_register;
+#ifdef DEV_NETMAP
+ e1000_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
/* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
@@ -6866,6 +6893,10 @@ static void e1000_remove(struct pci_dev *pdev)
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
+#ifdef DEV_NETMAP
+ netmap_detach(netdev);
+#endif /* DEV_NETMAP */
+
iounmap(adapter->hw.hw_addr);
if (adapter->hw.flash_address)
iounmap(adapter->hw.flash_address);

View File

@ -0,0 +1,76 @@
diff --git a/forcedeth.c b/forcedeth.c
index 9c0b1ba..b081d6b 100644
--- a/forcedeth.c
+++ b/forcedeth.c
@@ -1865,12 +1865,25 @@ static void nv_init_tx(struct net_device *dev)
}
}
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+/* we need a few forward declarations */
+static void nv_drain_rxtx(struct net_device *dev);
+static int nv_init_ring(struct net_device *dev);
+#include <forcedeth_netmap.h>
+#endif
+
static int nv_init_ring(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
nv_init_tx(dev);
nv_init_rx(dev);
+#ifdef DEV_NETMAP
+ forcedeth_netmap_tx_init(np);
+ if (forcedeth_netmap_rx_init(np))
+ return 0; /* success */
+#endif /* DEV_NETMAP */
+
if (!nv_optimized(np))
return nv_alloc_rx(dev);
@@ -3386,6 +3399,11 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
int i;
unsigned long flags;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(dev, 0))
+ return IRQ_HANDLED;
+#endif /* DEV_NETMAP */
+
for (i = 0;; i++) {
events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL;
writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus);
@@ -3497,6 +3515,11 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
int i;
unsigned long flags;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(dev, 0, &i))
+ return IRQ_HANDLED;
+#endif /* DEV_NETMAP */
+
for (i = 0;; i++) {
events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL;
writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus);
@@ -5645,6 +5668,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
goto out_error;
}
+#ifdef DEV_NETMAP
+ forcedeth_netmap_attach(np);
+#endif /* DEV_NETMAP */
+
netif_carrier_off(dev);
dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n",
@@ -5728,6 +5755,10 @@ static void __devexit nv_remove(struct pci_dev *pci_dev)
unregister_netdev(dev);
+#ifdef DEV_NETMAP
+ netmap_detach(dev);
+#endif /* DEV_NETMAP */
+
nv_restore_mac_addr(pci_dev);
/* restore any phy related changes */

View File

@ -0,0 +1,37 @@
diff --git a/igb/igb_main.c b/igb/igb_main.c
index c881347..77b3fda 100644
--- a/igb/igb_main.c
+++ b/igb/igb_main.c
@@ -1144,6 +1144,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);
@@ -1167,6 +1171,10 @@ void igb_down(struct igb_adapter *adapter)
wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
netif_tx_stop_all_queues(netdev);
/* disable transmits in the hardware */
@@ -2018,6 +2026,10 @@ static int igb_open(struct net_device *netdev)
netif_tx_start_all_queues(netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
/* start the watchdog. */
hw->mac.get_link_status = 1;
schedule_work(&adapter->watchdog_task);

View File

@ -0,0 +1,115 @@
diff --git a/igb/igb_main.c b/igb/igb_main.c
index cea37e0..70777e4 100644
--- a/igb/igb_main.c
+++ b/igb/igb_main.c
@@ -201,6 +201,10 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_igb_netmap.h>
+#endif
+
struct igb_reg_info {
u32 ofs;
char *name;
@@ -1478,6 +1482,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);
@@ -1501,6 +1509,10 @@ void igb_down(struct igb_adapter *adapter)
wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
netif_tx_stop_all_queues(netdev);
/* disable transmits in the hardware */
@@ -1963,6 +1975,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
/* 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;
@@ -2072,6 +2088,10 @@ static void __devexit igb_remove(struct pci_dev *pdev)
dev_info(&pdev->dev, "IOV Disabled\n");
}
#endif
+#ifdef DEV_NETMAP
+ netmap_detach(netdev);
+#endif /* DEV_NETMAP */
+
iounmap(hw->hw_addr);
if (hw->flash_address)
@@ -2366,6 +2386,10 @@ static int igb_open(struct net_device *netdev)
netif_tx_start_all_queues(netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
/* start the watchdog. */
hw->mac.get_link_status = 1;
schedule_work(&adapter->watchdog_task);
@@ -2545,6 +2569,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 */
}
/**
@@ -5338,6 +5365,11 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
unsigned int i, eop, count = 0;
bool cleaned = false;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(netdev, tx_ring->queue_index))
+ return 1; /* cleaned ok */
+#endif /* DEV_NETMAP */
+
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC_ADV(*tx_ring, eop);
@@ -5540,6 +5572,11 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector,
u16 length;
u16 vlan_tag;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(netdev, rx_ring->queue_index, work_done))
+ return 1;
+#endif /* DEV_NETMAP */
+
i = rx_ring->next_to_clean;
buffer_info = &rx_ring->buffer_info[i];
rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
@@ -5668,6 +5705,10 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count)
unsigned int i;
int bufsz;
+#ifdef DEV_NETMAP
+ if (igb_netmap_configure_rx_ring(rx_ring))
+ return;
+#endif /* DEV_NETMAP */
i = rx_ring->next_to_use;
buffer_info = &rx_ring->buffer_info[i];

View File

@ -0,0 +1,136 @@
diff --git a/igb/igb_main.c b/igb/igb_main.c
index ced5444..fb7c766 100644
--- a/igb/igb_main.c
+++ b/igb/igb_main.c
@@ -225,6 +225,10 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_igb_netmap.h>
+#endif
+
struct igb_reg_info {
u32 ofs;
char *name;
@@ -1551,6 +1555,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);
@@ -1584,6 +1592,10 @@ void igb_down(struct igb_adapter *adapter)
wrfl();
msleep(10);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
for (i = 0; i < adapter->num_q_vectors; i++)
napi_disable(&(adapter->q_vector[i]->napi));
@@ -2073,6 +2085,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
/* 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;
@@ -2199,6 +2215,10 @@ static void __devexit igb_remove(struct pci_dev *pdev)
dev_info(&pdev->dev, "IOV Disabled\n");
}
#endif
+#ifdef DEV_NETMAP
+ netmap_detach(netdev);
+#endif /* DEV_NETMAP */
+
iounmap(hw->hw_addr);
if (hw->flash_address)
@@ -2529,6 +2549,10 @@ static int igb_open(struct net_device *netdev)
netif_tx_start_all_queues(netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
/* start the watchdog. */
hw->mac.get_link_status = 1;
schedule_work(&adapter->watchdog_task);
@@ -2711,6 +2735,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 */
}
/**
@@ -3088,6 +3115,19 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
/* Only set Drop Enable if we are supporting multiple queues */
if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1)
srrctl |= E1000_SRRCTL_DROP_EN;
+#ifdef DEV_NETMAP
+ {
+ /* The driver uses split buffers, which are not
+ * supported in netmap mode */
+ struct ifnet *ifp = adapter->netdev;
+ struct netmap_adapter *na = NA(ifp);
+ if (na && ifp->if_capenable & IFCAP_NETMAP) {
+ srrctl &= ~(7 << 25); /* clear descriptor type */
+ srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
+ /* XXX we should set tail here */
+ }
+ }
+#endif
wr32(E1000_SRRCTL(reg_idx), srrctl);
@@ -5705,6 +5745,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);
@@ -5980,6 +6024,12 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget)
u16 cleaned_count = igb_desc_unused(rx_ring);
u16 i = rx_ring->next_to_clean;
+#ifdef DEV_NETMAP
+ int dummy = 1; // select rx irq handling
+ if (netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy))
+ return 1;
+#endif /* DEV_NETMAP */
+
rx_desc = IGB_RX_DESC(rx_ring, i);
while (igb_test_staterr(rx_desc, E1000_RXD_STAT_DD)) {
@@ -6170,6 +6220,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 */
+
rx_desc = IGB_RX_DESC(rx_ring, i);
bi = &rx_ring->rx_buffer_info[i];
i -= rx_ring->count;

View File

@ -0,0 +1,136 @@
diff --git a/igb/igb_main.c b/igb/igb_main.c
index 94be6c3..294051b 100644
--- a/igb/igb_main.c
+++ b/igb/igb_main.c
@@ -236,6 +236,10 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_igb_netmap.h>
+#endif
+
struct igb_reg_info {
u32 ofs;
char *name;
@@ -1557,6 +1561,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);
@@ -1590,6 +1598,10 @@ void igb_down(struct igb_adapter *adapter)
wrfl();
msleep(10);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
for (i = 0; i < adapter->num_q_vectors; i++)
napi_disable(&(adapter->q_vector[i]->napi));
@@ -2081,6 +2093,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
/* 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;
@@ -2211,6 +2227,10 @@ static void __devexit igb_remove(struct pci_dev *pdev)
dev_info(&pdev->dev, "IOV Disabled\n");
}
#endif
+#ifdef DEV_NETMAP
+ netmap_detach(netdev);
+#endif /* DEV_NETMAP */
+
iounmap(hw->hw_addr);
if (hw->flash_address)
@@ -2547,6 +2567,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);
@@ -2750,6 +2774,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 */
}
/**
@@ -3127,6 +3154,19 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
/* Only set Drop Enable if we are supporting multiple queues */
if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1)
srrctl |= E1000_SRRCTL_DROP_EN;
+#ifdef DEV_NETMAP
+ {
+ /* The driver uses split buffers, which are not
+ * supported in netmap mode */
+ struct ifnet *ifp = adapter->netdev;
+ struct netmap_adapter *na = NA(ifp);
+ if (na && ifp->if_capenable & IFCAP_NETMAP) {
+ srrctl &= ~(7 << 25); /* clear descriptor type */
+ srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
+ /* XXX we should set tail here */
+ }
+ }
+#endif
wr32(E1000_SRRCTL(reg_idx), srrctl);
@@ -5753,6 +5793,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);
@@ -6030,6 +6074,12 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget)
u16 cleaned_count = igb_desc_unused(rx_ring);
u16 i = rx_ring->next_to_clean;
+#ifdef DEV_NETMAP
+ int dummy = 1; // select rx irq handling
+ if (netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy))
+ return 1;
+#endif /* DEV_NETMAP */
+
rx_desc = IGB_RX_DESC(rx_ring, i);
while (igb_test_staterr(rx_desc, E1000_RXD_STAT_DD)) {
@@ -6220,6 +6270,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 */
+
rx_desc = IGB_RX_DESC(rx_ring, i);
bi = &rx_ring->rx_buffer_info[i];
i -= rx_ring->count;

View File

@ -0,0 +1,114 @@
diff --git a/igb/igb_main.c b/igb/igb_main.c
index 31cfe2e..8439bc6 100644
--- a/igb/igb_main.c
+++ b/igb/igb_main.c
@@ -247,6 +247,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;
@@ -1520,6 +1524,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);
@@ -1553,6 +1561,10 @@ void igb_down(struct igb_adapter *adapter)
wrfl();
msleep(10);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif /* DEV_NETMAP */
+
for (i = 0; i < adapter->num_q_vectors; i++)
napi_disable(&(adapter->q_vector[i]->napi));
@@ -2127,6 +2139,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;
@@ -2233,6 +2249,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. */
@@ -2553,6 +2573,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);
@@ -2746,6 +2770,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 */
}
/**
@@ -5690,6 +5717,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);
@@ -6349,6 +6380,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 */
do {
union e1000_adv_rx_desc *rx_desc;
@@ -6461,6 +6496,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;

View File

@ -0,0 +1,113 @@
diff --git a/igb/igb_main.c b/igb/igb_main.c
index c1d72c0..9815796 100644
--- a/igb/igb_main.c
+++ b/igb/igb_main.c
@@ -255,6 +255,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;
@@ -1633,6 +1637,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);
@@ -1674,6 +1682,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);
@@ -2295,6 +2306,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;
@@ -2536,6 +2551,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.
@@ -2814,6 +2833,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);
@@ -3007,6 +3030,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 */
}
/**
@@ -5991,6 +6017,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);
@@ -6650,6 +6680,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 */
do {
union e1000_adv_rx_desc *rx_desc;
@@ -6767,6 +6801,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;

View File

@ -0,0 +1,113 @@
diff --git a/ixgbe/ixgbe_main.c b/ixgbe/ixgbe_main.c
index eee0b29..70581eb 100644
--- a/ixgbe/ixgbe_main.c
+++ b/ixgbe/ixgbe_main.c
@@ -214,6 +214,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = {
{}
};
+#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
@@ -740,6 +756,16 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
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);
@@ -1185,6 +1211,13 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
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);
@@ -2519,6 +2552,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+#ifdef DEV_NETMAP
+ ixgbe_netmap_configure_tx_ring(adapter, reg_idx);
+#endif /* DEV_NETMAP */
}
static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
@@ -2833,6 +2869,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
+#ifdef DEV_NETMAP
+ if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx))
+ return;
+#endif /* DEV_NETMAP */
ixgbe_alloc_rx_buffers(adapter, ring, IXGBE_DESC_UNUSED(ring));
}
@@ -3614,6 +3654,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(adapter->netdev);
+#endif
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -3863,6 +3907,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
/* Cleanup the affinity_hint CPU mask memory and callback */
for (i = 0; i < num_q_vectors; i++) {
struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
@@ -7048,6 +7096,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
e_dev_info("Intel(R) 10 Gigabit Network Connection\n");
cards_found++;
+
+#ifdef DEV_NETMAP
+ ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
return 0;
err_register:

View File

@ -0,0 +1,113 @@
diff --git a/ixgbe/ixgbe_main.c b/ixgbe/ixgbe_main.c
index 30f9ccf..60c0252 100644
--- a/ixgbe/ixgbe_main.c
+++ b/ixgbe/ixgbe_main.c
@@ -221,6 +221,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = {
{}
};
+#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
@@ -826,6 +842,16 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
unsigned int total_bytes = 0, total_packets = 0;
u16 i, eop, count = 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);
@@ -1308,6 +1334,13 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
u16 cleaned_count = 0;
bool pkt_is_rsc = false;
+#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);
@@ -2730,6 +2763,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+#ifdef DEV_NETMAP
+ ixgbe_netmap_configure_tx_ring(adapter, reg_idx);
+#endif /* DEV_NETMAP */
}
static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
@@ -3094,6 +3130,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
+#ifdef DEV_NETMAP
+ if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx))
+ return;
+#endif /* DEV_NETMAP */
ixgbe_alloc_rx_buffers(ring, IXGBE_DESC_UNUSED(ring));
}
@@ -3882,6 +3922,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(adapter->netdev);
+#endif
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4121,6 +4165,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
/* Cleanup the affinity_hint CPU mask memory and callback */
for (i = 0; i < num_q_vectors; i++) {
struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
@@ -7450,6 +7498,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
e_dev_info("Intel(R) 10 Gigabit Network Connection\n");
cards_found++;
+
+#ifdef DEV_NETMAP
+ ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
return 0;
err_register:

View File

@ -0,0 +1,113 @@
diff --git a/ixgbe/ixgbe_main.c b/ixgbe/ixgbe_main.c
index 08e8e25..8070930 100644
--- a/ixgbe/ixgbe_main.c
+++ b/ixgbe/ixgbe_main.c
@@ -247,6 +247,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = {
{}
};
+#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
@@ -864,6 +880,16 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
unsigned int total_bytes = 0, total_packets = 0;
u16 i, eop, count = 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);
@@ -1348,6 +1374,13 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
u16 cleaned_count = 0;
bool pkt_is_rsc = false;
+#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);
@@ -2808,6 +2841,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+#ifdef DEV_NETMAP
+ ixgbe_netmap_configure_tx_ring(adapter, reg_idx);
+#endif /* DEV_NETMAP */
}
static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
@@ -3183,6 +3219,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
+#ifdef DEV_NETMAP
+ if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx))
+ return;
+#endif /* DEV_NETMAP */
ixgbe_alloc_rx_buffers(ring, IXGBE_DESC_UNUSED(ring));
}
@@ -3976,6 +4016,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(adapter->netdev);
+#endif
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4212,6 +4256,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
IXGBE_FLAG2_RESET_REQUESTED);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -7683,6 +7731,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
e_dev_info("Intel(R) 10 Gigabit Network Connection\n");
cards_found++;
+
+#ifdef DEV_NETMAP
+ ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
return 0;
err_register:

View File

@ -0,0 +1,114 @@
diff --git a/ixgbe/ixgbe_main.c b/ixgbe/ixgbe_main.c
index e1fcc95..1aab0df 100644
--- a/ixgbe/ixgbe_main.c
+++ b/ixgbe/ixgbe_main.c
@@ -249,6 +249,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = {
{}
};
+#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
@@ -801,6 +817,17 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
unsigned int total_bytes = 0, total_packets = 0;
u16 i, eop, count = 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);
@@ -1303,6 +1330,13 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
u16 cleaned_count = 0;
bool pkt_is_rsc = false;
+#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);
@@ -2676,6 +2710,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+#ifdef DEV_NETMAP
+ ixgbe_netmap_configure_tx_ring(adapter, reg_idx);
+#endif /* DEV_NETMAP */
}
static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
@@ -3039,6 +3076,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
+#ifdef DEV_NETMAP
+ if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx))
+ return;
+#endif /* DEV_NETMAP */
ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring));
}
@@ -3873,6 +3914,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(adapter->netdev);
+#endif
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4126,6 +4171,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
IXGBE_FLAG2_RESET_REQUESTED);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -7696,6 +7745,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
e_dev_info("Intel(R) 10 Gigabit Network Connection\n");
cards_found++;
+
+#ifdef DEV_NETMAP
+ ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
return 0;
err_register:

View File

@ -0,0 +1,115 @@
diff --git a/ixgbe/ixgbe_main.c b/ixgbe/ixgbe_main.c
index 8ef92d1..6a37803 100644
--- a/ixgbe/ixgbe_main.c
+++ b/ixgbe/ixgbe_main.c
@@ -188,6 +188,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = {
{}
};
+#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
@@ -745,6 +761,17 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
unsigned int budget = q_vector->tx.work_limit;
u16 i = tx_ring->next_to_clean;
+#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 true; /* seems to be ignored */
+#endif /* DEV_NETMAP */
+
tx_buffer = &tx_ring->tx_buffer_info[i];
tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
@@ -1253,6 +1280,14 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
u16 cleaned_count = 0;
bool pkt_is_rsc = false;
+#ifdef DEV_NETMAP
+ /*
+ * Same as the txeof routine: only wakeup clients on intr.
+ */
+ int dummy;
+ if (netmap_rx_irq(adapter->netdev, rx_ring->queue_index, &dummy))
+ return true;
+#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);
@@ -2420,6 +2455,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+#ifdef DEV_NETMAP
+ ixgbe_netmap_configure_tx_ring(adapter, reg_idx);
+#endif /* DEV_NETMAP */
}
static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
@@ -2783,6 +2821,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
+#ifdef DEV_NETMAP
+ if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx))
+ return;
+#endif /* DEV_NETMAP */
ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring));
}
@@ -3757,6 +3799,10 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(adapter->netdev);
+#endif
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4007,6 +4053,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
IXGBE_FLAG2_RESET_REQUESTED);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -7710,6 +7760,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
e_dev_info("Intel(R) 10 Gigabit Network Connection\n");
cards_found++;
+
+#ifdef DEV_NETMAP
+ ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
return 0;
err_register:

View File

@ -0,0 +1,124 @@
diff --git a/ixgbe/ixgbe_main.c b/ixgbe/ixgbe_main.c
index 467948e..0aa1511 100644
--- a/ixgbe/ixgbe_main.c
+++ b/ixgbe/ixgbe_main.c
@@ -204,6 +204,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = {
{}
};
+#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
@@ -749,6 +765,17 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
if (test_bit(__IXGBE_DOWN, &adapter->state))
return true;
+#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 */
+
tx_buffer = &tx_ring->tx_buffer_info[i];
tx_desc = IXGBE_TX_DESC(tx_ring, i);
i -= tx_ring->count;
@@ -1629,6 +1656,15 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
#endif /* IXGBE_FCOE */
u16 cleaned_count = ixgbe_desc_unused(rx_ring);
+#ifdef DEV_NETMAP
+ /*
+ * Same as the txeof routine: only wakeup clients on intr.
+ */
+ int dummy;
+ if (netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy))
+ return true; /* no more interrupts */
+#endif /* DEV_NETMAP */
+
do {
struct ixgbe_rx_buffer *rx_buffer;
union ixgbe_adv_rx_desc *rx_desc;
@@ -2683,6 +2719,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+#ifdef DEV_NETMAP
+ ixgbe_netmap_configure_tx_ring(adapter, reg_idx);
+#endif /* DEV_NETMAP */
}
static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
@@ -3032,6 +3071,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
+#ifdef DEV_NETMAP
+ if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx))
+ return;
+#endif /* DEV_NETMAP */
ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring));
}
@@ -3986,6 +4029,10 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(adapter->netdev);
+#endif
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4249,6 +4296,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
IXGBE_FLAG2_RESET_REQUESTED);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4764,6 +4815,7 @@ static int ixgbe_open(struct net_device *netdev)
ixgbe_up_complete(adapter);
+
return 0;
err_req_irq:
@@ -7152,6 +7204,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
e_dev_info("%s\n", ixgbe_default_device_descr);
cards_found++;
+
+#ifdef DEV_NETMAP
+ ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
return 0;
err_register:

View File

@ -0,0 +1,123 @@
diff --git a/ixgbe/ixgbe_main.c b/ixgbe/ixgbe_main.c
index e242104..02e1544 100644
--- a/ixgbe/ixgbe_main.c
+++ b/ixgbe/ixgbe_main.c
@@ -204,6 +204,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = {
{}
};
+#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
@@ -764,6 +780,17 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
if (test_bit(__IXGBE_DOWN, &adapter->state))
return true;
+#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 */
+
tx_buffer = &tx_ring->tx_buffer_info[i];
tx_desc = IXGBE_TX_DESC(tx_ring, i);
i -= tx_ring->count;
@@ -1665,6 +1692,15 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
#endif /* IXGBE_FCOE */
u16 cleaned_count = ixgbe_desc_unused(rx_ring);
+#ifdef DEV_NETMAP
+ /*
+ * Same as the txeof routine: only wakeup clients on intr.
+ */
+ int dummy;
+ if (netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy))
+ return true; /* no more interrupts */
+#endif /* DEV_NETMAP */
+
do {
struct ixgbe_rx_buffer *rx_buffer;
union ixgbe_adv_rx_desc *rx_desc;
@@ -2725,6 +2761,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+#ifdef DEV_NETMAP
+ ixgbe_netmap_configure_tx_ring(adapter, reg_idx);
+#endif /* DEV_NETMAP */
}
static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
@@ -3102,6 +3141,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
+#ifdef DEV_NETMAP
+ if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx))
+ return;
+#endif /* DEV_NETMAP */
ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring));
}
@@ -4051,6 +4094,10 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(adapter->netdev);
+#endif
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4315,6 +4362,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
IXGBE_FLAG2_RESET_REQUESTED);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4827,6 +4878,7 @@ static int ixgbe_open(struct net_device *netdev)
ixgbe_up_complete(adapter);
+
return 0;
err_req_irq:
@@ -7358,6 +7410,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
e_err(probe, "failed to allocate sysfs resources\n");
#endif /* CONFIG_IXGBE_HWMON */
+#ifdef DEV_NETMAP
+ ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
return 0;
err_register:

View File

@ -0,0 +1,134 @@
diff --git a/ixgbe/ixgbe_main.c b/ixgbe/ixgbe_main.c
index 79f4a26..4b8a25b 100644
--- a/ixgbe/ixgbe_main.c
+++ b/ixgbe/ixgbe_main.c
@@ -202,6 +202,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = {
{}
};
+#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
@@ -826,6 +842,17 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
if (test_bit(__IXGBE_DOWN, &adapter->state))
return true;
+#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 */
+
tx_buffer = &tx_ring->tx_buffer_info[i];
tx_desc = IXGBE_TX_DESC(tx_ring, i);
i -= tx_ring->count;
@@ -1860,6 +1887,15 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
#endif /* IXGBE_FCOE */
u16 cleaned_count = ixgbe_desc_unused(rx_ring);
+#ifdef DEV_NETMAP
+ /*
+ * Same as the txeof routine: only wakeup clients on intr.
+ */
+ int dummy;
+ if (netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy))
+ return true; /* no more interrupts */
+#endif /* DEV_NETMAP */
+
do {
union ixgbe_adv_rx_desc *rx_desc;
struct sk_buff *skb;
@@ -2846,6 +2882,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+#ifdef DEV_NETMAP
+ ixgbe_netmap_configure_tx_ring(adapter, reg_idx);
+#endif /* DEV_NETMAP */
}
static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
@@ -3207,6 +3246,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
+#ifdef DEV_NETMAP
+ if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx))
+ return;
+#endif /* DEV_NETMAP */
ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring));
}
@@ -4155,6 +4198,10 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(adapter->netdev);
+#endif
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4402,6 +4449,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
IXGBE_FLAG2_RESET_REQUESTED);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4976,6 +5027,7 @@ static int ixgbe_open(struct net_device *netdev)
ixgbe_up_complete(adapter);
+
return 0;
err_set_queues:
@@ -7619,6 +7671,10 @@ skip_sriov:
ixgbe_dbg_adapter_init(adapter);
#endif /* CONFIG_DEBUG_FS */
+#ifdef DEV_NETMAP
+ ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
return 0;
err_register:
@@ -7653,6 +7709,10 @@ static void ixgbe_remove(struct pci_dev *pdev)
struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
struct net_device *netdev = adapter->netdev;
+#ifdef DEV_NETMAP
+ netmap_detach(netdev);
+#endif /* DEV_NETMAP */
+
#ifdef CONFIG_DEBUG_FS
ixgbe_dbg_adapter_exit(adapter);
#endif /*CONFIG_DEBUG_FS */

View File

@ -0,0 +1,123 @@
diff --git a/ixgbe/ixgbe_main.c b/ixgbe/ixgbe_main.c
index d30fbdd..7418c57 100644
--- a/ixgbe/ixgbe_main.c
+++ b/ixgbe/ixgbe_main.c
@@ -248,6 +248,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = {
{}
};
+#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
@@ -872,6 +888,17 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
if (test_bit(__IXGBE_DOWN, &adapter->state))
return true;
+#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 */
+
tx_buffer = &tx_ring->tx_buffer_info[i];
tx_desc = IXGBE_TX_DESC(tx_ring, i);
i -= tx_ring->count;
@@ -1906,6 +1933,15 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
#endif /* IXGBE_FCOE */
u16 cleaned_count = ixgbe_desc_unused(rx_ring);
+#ifdef DEV_NETMAP
+ /*
+ * Same as the txeof routine: only wakeup clients on intr.
+ */
+ int dummy;
+ if (netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy))
+ return true; /* no more interrupts */
+#endif /* DEV_NETMAP */
+
do {
union ixgbe_adv_rx_desc *rx_desc;
struct sk_buff *skb;
@@ -2905,6 +2941,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
if (!wait_loop)
e_err(drv, "Could not enable Tx Queue %d\n", reg_idx);
+#ifdef DEV_NETMAP
+ ixgbe_netmap_configure_tx_ring(adapter, reg_idx);
+#endif /* DEV_NETMAP */
}
static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter)
@@ -3266,6 +3305,10 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
ixgbe_rx_desc_queue_enable(adapter, ring);
+#ifdef DEV_NETMAP
+ if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx))
+ return;
+#endif /* DEV_NETMAP */
ixgbe_alloc_rx_buffers(ring, ixgbe_desc_unused(ring));
}
@@ -4216,6 +4259,10 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(adapter->netdev);
+#endif
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -4463,6 +4510,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(netdev);
+#endif
+
adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
IXGBE_FLAG2_RESET_REQUESTED);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -5037,6 +5088,7 @@ static int ixgbe_open(struct net_device *netdev)
ixgbe_up_complete(adapter);
+
return 0;
err_set_queues:
@@ -7658,6 +7710,10 @@ skip_sriov:
IXGBE_LINK_SPEED_10GB_FULL | IXGBE_LINK_SPEED_1GB_FULL,
true);
+#ifdef DEV_NETMAP
+ ixgbe_netmap_attach(adapter);
+#endif /* DEV_NETMAP */
+
return 0;
err_register:

View File

@ -0,0 +1,117 @@
diff --git a/r8169.c b/r8169.c
index 0fe2fc9..efee0a4 100644
--- a/r8169.c
+++ b/r8169.c
@@ -537,6 +537,10 @@ static int rtl8169_poll(struct napi_struct *napi, int budget);
static const unsigned int rtl8169_rx_config =
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_re_netmap_linux.h>
+#endif
+
static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
{
int i;
@@ -3210,6 +3214,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);
+#ifdef DEV_NETMAP
+ re_netmap_attach(tp);
+#endif /* DEV_NETMAP */
+
out:
return rc;
@@ -3236,6 +3244,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
unregister_netdev(dev);
+#ifdef DEV_NETMAP
+ netmap_detach(dev);
+#endif /* DEV_NETMAP */
+
/* restore original MAC address */
rtl_rar_set(tp, dev->perm_addr);
@@ -3291,6 +3303,10 @@ static int rtl8169_open(struct net_device *dev)
napi_enable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
rtl_hw_start(dev);
rtl8169_request_timer(dev);
@@ -3993,6 +4009,11 @@ err_out:
static void rtl8169_rx_clear(struct rtl8169_private *tp)
{
unsigned int i;
+#ifdef DEV_NETMAP
+ re_netmap_tx_init(tp);
+ if (re_netmap_rx_init(tp))
+ return 0; // success
+#endif /* DEV_NETMAP */
for (i = 0; i < NUM_RX_DESC; i++) {
if (tp->Rx_skbuff[i]) {
@@ -4112,11 +4133,19 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)
/* Wait for any pending NAPI task to complete */
napi_disable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
rtl8169_irq_mask_and_ack(ioaddr);
tp->intr_mask = 0xffff;
RTL_W16(IntrMask, tp->intr_event);
napi_enable(&tp->napi);
+
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(dev);
+#endif /* DEV_NETMAP */
}
static void rtl8169_reinit_task(struct work_struct *work)
@@ -4372,6 +4401,11 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
{
unsigned int dirty_tx, tx_left;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(dev, 0))
+ return;
+#endif /* DEV_NETMAP */
+
dirty_tx = tp->dirty_tx;
smp_rmb();
tx_left = tp->cur_tx - dirty_tx;
@@ -4468,6 +4502,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
unsigned int cur_rx, rx_left;
unsigned int delta, count;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(dev, 0, &count))
+ return count;
+#endif /* DEV_NETMAP */
+
cur_rx = tp->cur_rx;
rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
rx_left = min(rx_left, budget);
@@ -4687,7 +4726,12 @@ static void rtl8169_down(struct net_device *dev)
napi_disable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
core_down:
+
spin_lock_irq(&tp->lock);
rtl8169_asic_down(ioaddr);

View File

@ -0,0 +1,115 @@
diff --git a/r8169.c b/r8169.c
index 53b13de..745a59d 100644
--- a/r8169.c
+++ b/r8169.c
@@ -535,6 +535,10 @@ static int rtl8169_poll(struct napi_struct *napi, int budget);
static const unsigned int rtl8169_rx_config =
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_re_netmap_linux.h>
+#endif
+
static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
{
int i;
@@ -3229,6 +3233,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_dev_run_wake(pdev))
pm_runtime_put_noidle(&pdev->dev);
+#ifdef DEV_NETMAP
+ re_netmap_attach(tp);
+#endif /* DEV_NETMAP */
+
out:
return rc;
@@ -3257,6 +3265,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
if (pci_dev_run_wake(pdev))
pm_runtime_get_noresume(&pdev->dev);
+#ifdef DEV_NETMAP
+ netmap_detach(dev);
+#endif /* DEV_NETMAP */
+
/* restore original MAC address */
rtl_rar_set(tp, dev->perm_addr);
@@ -3303,6 +3315,10 @@ static int rtl8169_open(struct net_device *dev)
napi_enable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
rtl_hw_start(dev);
rtl8169_request_timer(dev);
@@ -4018,6 +4034,11 @@ static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
static int rtl8169_rx_fill(struct rtl8169_private *tp)
{
unsigned int i;
+#ifdef DEV_NETMAP
+ re_netmap_tx_init(tp);
+ if (re_netmap_rx_init(tp))
+ return 0; // success
+#endif /* DEV_NETMAP */
for (i = 0; i < NUM_RX_DESC; i++) {
void *data;
@@ -4119,11 +4140,19 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)
/* Wait for any pending NAPI task to complete */
napi_disable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
rtl8169_irq_mask_and_ack(ioaddr);
tp->intr_mask = 0xffff;
RTL_W16(IntrMask, tp->intr_event);
napi_enable(&tp->napi);
+
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(dev);
+#endif /* DEV_NETMAP */
}
static void rtl8169_reinit_task(struct work_struct *work)
@@ -4395,6 +4424,11 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
{
unsigned int dirty_tx, tx_left;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(dev, 0))
+ return;
+#endif /* DEV_NETMAP */
+
dirty_tx = tp->dirty_tx;
smp_rmb();
tx_left = tp->cur_tx - dirty_tx;
@@ -4490,6 +4524,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
unsigned int count;
int polling = (budget != ~(u32)0) ? 1 : 0;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(dev, 0, &count))
+ return count;
+#endif /* DEV_NETMAP */
+
cur_rx = tp->cur_rx;
rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
rx_left = min(rx_left, budget);
@@ -4691,6 +4730,10 @@ static void rtl8169_down(struct net_device *dev)
napi_disable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
spin_lock_irq(&tp->lock);
rtl8169_asic_down(ioaddr);

View File

@ -0,0 +1,114 @@
diff --git a/r8169.c b/r8169.c
index 7ffdb80..6bae7e6 100644
--- a/r8169.c
+++ b/r8169.c
@@ -590,6 +590,10 @@ static int rtl8169_poll(struct napi_struct *napi, int budget);
static const unsigned int rtl8169_rx_config =
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_re_netmap_linux.h>
+#endif
+
static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
{
void __iomem *ioaddr = tp->mmio_addr;
@@ -3207,6 +3211,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_dev_run_wake(pdev))
pm_runtime_put_noidle(&pdev->dev);
+#ifdef DEV_NETMAP
+ re_netmap_attach(tp);
+#endif /* DEV_NETMAP */
+
netif_carrier_off(dev);
out:
@@ -3238,6 +3246,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
cancel_delayed_work_sync(&tp->task);
rtl_release_firmware(tp);
+#ifdef DEV_NETMAP
+ netmap_detach(dev);
+#endif /* DEV_NETMAP */
unregister_netdev(dev);
@@ -3291,6 +3302,10 @@ static int rtl8169_open(struct net_device *dev)
napi_enable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
rtl8169_init_phy(dev, tp);
/*
@@ -4074,6 +4089,11 @@ static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
static int rtl8169_rx_fill(struct rtl8169_private *tp)
{
unsigned int i;
+#ifdef DEV_NETMAP
+ re_netmap_tx_init(tp);
+ if (re_netmap_rx_init(tp))
+ return 0; // success
+#endif /* DEV_NETMAP */
for (i = 0; i < NUM_RX_DESC; i++) {
void *data;
@@ -4175,11 +4195,19 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)
/* Wait for any pending NAPI task to complete */
napi_disable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
rtl8169_irq_mask_and_ack(ioaddr);
tp->intr_mask = 0xffff;
RTL_W16(IntrMask, tp->intr_event);
napi_enable(&tp->napi);
+
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(dev);
+#endif /* DEV_NETMAP */
}
static void rtl8169_reinit_task(struct work_struct *work)
@@ -4452,6 +4480,11 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
{
unsigned int dirty_tx, tx_left;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(dev, 0))
+ return;
+#endif /* DEV_NETMAP */
+
dirty_tx = tp->dirty_tx;
smp_rmb();
tx_left = tp->cur_tx - dirty_tx;
@@ -4547,6 +4580,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
unsigned int count;
int polling = (budget != ~(u32)0) ? 1 : 0;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(dev, 0, &count))
+ return count;
+#endif /* DEV_NETMAP */
+
cur_rx = tp->cur_rx;
rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
rx_left = min(rx_left, budget);
@@ -4769,6 +4807,10 @@ static void rtl8169_down(struct net_device *dev)
napi_disable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
spin_lock_irq(&tp->lock);
rtl8169_asic_down(ioaddr);

View File

@ -0,0 +1,114 @@
diff --git a/r8169.c b/r8169.c
index c8f47f1..a41e878 100644
--- a/r8169.c
+++ b/r8169.c
@@ -787,6 +787,10 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
}
}
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <if_re_netmap_linux.h>
+#endif
+
static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
{
void __iomem *ioaddr = tp->mmio_addr;
@@ -4167,6 +4171,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_dev_run_wake(pdev))
pm_runtime_put_noidle(&pdev->dev);
+#ifdef DEV_NETMAP
+ re_netmap_attach(tp);
+#endif /* DEV_NETMAP */
+
netif_carrier_off(dev);
out:
@@ -4201,6 +4209,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
unregister_netdev(dev);
rtl_release_firmware(tp);
+#ifdef DEV_NETMAP
+ netmap_detach(dev);
+#endif /* DEV_NETMAP */
if (pci_dev_run_wake(pdev))
pm_runtime_get_noresume(&pdev->dev);
@@ -4298,6 +4309,10 @@ static int rtl8169_open(struct net_device *dev)
napi_enable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
rtl8169_init_phy(dev, tp);
rtl8169_set_features(dev, dev->features);
@@ -5252,6 +5267,11 @@ static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
static int rtl8169_rx_fill(struct rtl8169_private *tp)
{
unsigned int i;
+#ifdef DEV_NETMAP
+ re_netmap_tx_init(tp);
+ if (re_netmap_rx_init(tp))
+ return 0; // success
+#endif /* DEV_NETMAP */
for (i = 0; i < NUM_RX_DESC; i++) {
void *data;
@@ -5348,11 +5368,19 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)
/* Wait for any pending NAPI task to complete */
napi_disable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
rtl8169_irq_mask_and_ack(tp);
tp->intr_mask = 0xffff;
RTL_W16(IntrMask, tp->intr_event);
napi_enable(&tp->napi);
+
+#ifdef DEV_NETMAP
+ netmap_enable_all_rings(dev);
+#endif /* DEV_NETMAP */
}
static void rtl8169_reinit_task(struct work_struct *work)
@@ -5627,6 +5655,11 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
{
unsigned int dirty_tx, tx_left;
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(dev, 0))
+ return;
+#endif /* DEV_NETMAP */
+
dirty_tx = tp->dirty_tx;
smp_rmb();
tx_left = tp->cur_tx - dirty_tx;
@@ -5714,6 +5747,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
unsigned int cur_rx, rx_left;
unsigned int count;
+#ifdef DEV_NETMAP
+ if (netmap_rx_irq(dev, 0, &count))
+ return count;
+#endif /* DEV_NETMAP */
+
cur_rx = tp->cur_rx;
rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
rx_left = min(rx_left, budget);
@@ -5920,6 +5958,10 @@ static void rtl8169_down(struct net_device *dev)
napi_disable(&tp->napi);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif /* DEV_NETMAP */
+
spin_lock_irq(&tp->lock);
rtl8169_hw_reset(tp);

View File

@ -0,0 +1,85 @@
diff --git a/virtio_net.c b/virtio_net.c
index b0577dd..6516934 100644
--- a/virtio_net.c
+++ b/virtio_net.c
@@ -64,6 +64,10 @@ struct virtnet_info
struct page *pages;
};
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <virtio_netmap.h>
+#endif
+
struct skb_vnet_hdr {
union {
struct virtio_net_hdr hdr;
@@ -121,6 +125,10 @@ static void skb_xmit_done(struct virtqueue *svq)
/* Suppress further interrupts. */
svq->vq_ops->disable_cb(svq);
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(vi->dev, 0))
+ return;
+#endif
/* We were probably waiting for more output buffers. */
netif_wake_queue(vi->dev);
}
@@ -470,7 +478,16 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
void *buf;
unsigned int len, received = 0;
+#ifdef DEV_NETMAP
+ int work_done = 0;
+ if (netmap_rx_irq(vi->dev, 0, &work_done)) {
+ napi_complete(napi);
+ ND("called netmap_rx_irq");
+
+ return 1;
+ }
+#endif
again:
while (received < budget &&
(buf = vi->rvq->vq_ops->get_buf(vi->rvq, &len)) != NULL) {
@@ -638,6 +655,10 @@ static int virtnet_open(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+#ifdef DEV_NETMAP
+ virtio_netmap_init_buffers(vi);
+ netmap_enable_all_rings(dev);
+#endif
napi_enable(&vi->napi);
/* If all buffers were filled by other side before we napi_enabled, we
@@ -700,6 +721,9 @@ static int virtnet_close(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif
napi_disable(&vi->napi);
return 0;
@@ -985,6 +1009,10 @@ static int virtnet_probe(struct virtio_device *vdev)
goto unregister;
}
+#ifdef DEV_NETMAP
+ virtio_netmap_attach(vi);
+#endif
+
vi->status = VIRTIO_NET_S_LINK_UP;
virtnet_update_status(vi);
netif_carrier_on(dev);
@@ -1028,6 +1056,9 @@ static void __devexit virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
+#ifdef DEV_NETMAP
+ netmap_detach(vi->dev);
+#endif
/* Stop all the virtqueues. */
vdev->config->reset(vdev);

View File

@ -0,0 +1,85 @@
diff --git a/virtio_net.c b/virtio_net.c
index b6d4028..a9be38d 100644
--- a/virtio_net.c
+++ b/virtio_net.c
@@ -67,6 +67,10 @@ struct virtnet_info {
struct scatterlist tx_sg[MAX_SKB_FRAGS + 2];
};
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <virtio_netmap.h>
+#endif
+
struct skb_vnet_hdr {
union {
struct virtio_net_hdr hdr;
@@ -124,6 +128,10 @@ static void skb_xmit_done(struct virtqueue *svq)
/* Suppress further interrupts. */
virtqueue_disable_cb(svq);
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(vi->dev, 0))
+ return;
+#endif
/* We were probably waiting for more output buffers. */
netif_wake_queue(vi->dev);
}
@@ -467,7 +475,16 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
void *buf;
unsigned int len, received = 0;
+#ifdef DEV_NETMAP
+ int work_done = 0;
+ if (netmap_rx_irq(vi->dev, 0, &work_done)) {
+ napi_complete(napi);
+ ND("called netmap_rx_irq");
+
+ return 1;
+ }
+#endif
again:
while (received < budget &&
(buf = virtqueue_get_buf(vi->rvq, &len)) != NULL) {
@@ -638,6 +655,10 @@ static int virtnet_open(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+#ifdef DEV_NETMAP
+ virtio_netmap_init_buffers(vi);
+ netmap_enable_all_rings(dev);
+#endif
napi_enable(&vi->napi);
/* If all buffers were filled by other side before we napi_enabled, we
@@ -700,6 +721,9 @@ static int virtnet_close(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif
napi_disable(&vi->napi);
return 0;
@@ -986,6 +1010,10 @@ static int virtnet_probe(struct virtio_device *vdev)
goto unregister;
}
+#ifdef DEV_NETMAP
+ virtio_netmap_attach(vi);
+#endif
+
/* Assume link up if device can't report link status,
otherwise get link status from config. */
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1035,6 +1063,9 @@ static void __devexit virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
+#ifdef DEV_NETMAP
+ netmap_detach(vi->dev);
+#endif
/* Stop all the virtqueues. */
vdev->config->reset(vdev);

View File

@ -0,0 +1,85 @@
diff --git a/virtio_net.c b/virtio_net.c
index 82dba5a..f217797 100644
--- a/virtio_net.c
+++ b/virtio_net.c
@@ -67,6 +67,10 @@ struct virtnet_info {
struct scatterlist tx_sg[MAX_SKB_FRAGS + 2];
};
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <virtio_netmap.h>
+#endif
+
struct skb_vnet_hdr {
union {
struct virtio_net_hdr hdr;
@@ -124,6 +128,10 @@ static void skb_xmit_done(struct virtqueue *svq)
/* Suppress further interrupts. */
virtqueue_disable_cb(svq);
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(vi->dev, 0))
+ return;
+#endif
/* We were probably waiting for more output buffers. */
netif_wake_queue(vi->dev);
}
@@ -481,7 +489,16 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
void *buf;
unsigned int len, received = 0;
+#ifdef DEV_NETMAP
+ int work_done = 0;
+ if (netmap_rx_irq(vi->dev, 0, &work_done)) {
+ napi_complete(napi);
+ ND("called netmap_rx_irq");
+
+ return 1;
+ }
+#endif
again:
while (received < budget &&
(buf = virtqueue_get_buf(vi->rvq, &len)) != NULL) {
@@ -652,6 +669,10 @@ static int virtnet_open(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+#ifdef DEV_NETMAP
+ virtio_netmap_init_buffers(vi);
+ netmap_enable_all_rings(dev);
+#endif
virtnet_napi_enable(vi);
return 0;
}
@@ -705,6 +726,9 @@ static int virtnet_close(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif
napi_disable(&vi->napi);
return 0;
@@ -991,6 +1015,10 @@ static int virtnet_probe(struct virtio_device *vdev)
goto unregister;
}
+#ifdef DEV_NETMAP
+ virtio_netmap_attach(vi);
+#endif
+
/* Assume link up if device can't report link status,
otherwise get link status from config. */
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1040,6 +1068,9 @@ static void __devexit virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
+#ifdef DEV_NETMAP
+ netmap_detach(vi->dev);
+#endif
/* Stop all the virtqueues. */
vdev->config->reset(vdev);

View File

@ -0,0 +1,90 @@
diff --git a/virtio_net.c b/virtio_net.c
index 4880aa8..6329c3a 100644
--- a/virtio_net.c
+++ b/virtio_net.c
@@ -80,6 +80,10 @@ struct virtnet_info {
struct scatterlist tx_sg[MAX_SKB_FRAGS + 2];
};
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <virtio_netmap.h>
+#endif
+
struct skb_vnet_hdr {
union {
struct virtio_net_hdr hdr;
@@ -137,6 +141,10 @@ static void skb_xmit_done(struct virtqueue *svq)
/* Suppress further interrupts. */
virtqueue_disable_cb(svq);
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(vi->dev, 0))
+ return;
+#endif
/* We were probably waiting for more output buffers. */
netif_wake_queue(vi->dev);
}
@@ -517,7 +525,16 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
void *buf;
unsigned int len, received = 0;
+#ifdef DEV_NETMAP
+ int work_done = 0;
+ if (netmap_rx_irq(vi->dev, 0, &work_done)) {
+ napi_complete(napi);
+ ND("called netmap_rx_irq");
+
+ return 1;
+ }
+#endif
again:
while (received < budget &&
(buf = virtqueue_get_buf(vi->rvq, &len)) != NULL) {
@@ -727,7 +744,15 @@ static void virtnet_netpoll(struct net_device *dev)
static int virtnet_open(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+#ifdef DEV_NETMAP
+ int ok = virtio_netmap_init_buffers(vi);
+ netmap_enable_all_rings(dev);
+ if (ok) {
+ virtnet_napi_enable(vi);
+ return 0;
+ }
+#endif
/* Make sure we have some buffers: if oom use wq. */
if (!try_fill_recv(vi, GFP_KERNEL))
queue_delayed_work(system_nrt_wq, &vi->refill, 0);
@@ -785,6 +810,9 @@ static int virtnet_close(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif
/* Make sure refill_work doesn't re-enable napi! */
cancel_delayed_work_sync(&vi->refill);
napi_disable(&vi->napi);
@@ -1107,6 +1135,10 @@ static int virtnet_probe(struct virtio_device *vdev)
goto unregister;
}
+#ifdef DEV_NETMAP
+ virtio_netmap_attach(vi);
+#endif
+
/* Assume link up if device can't report link status,
otherwise get link status from config. */
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1170,6 +1202,9 @@ static void __devexit virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
+#ifdef DEV_NETMAP
+ netmap_detach(vi->dev);
+#endif
unregister_netdev(vi->dev);
remove_vq_common(vi);

View File

@ -0,0 +1,90 @@
diff --git a/virtio_net.c b/virtio_net.c
index f18149a..95e1580 100644
--- a/virtio_net.c
+++ b/virtio_net.c
@@ -90,6 +90,10 @@ struct virtnet_info {
struct scatterlist tx_sg[MAX_SKB_FRAGS + 2];
};
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <virtio_netmap.h>
+#endif
+
struct skb_vnet_hdr {
union {
struct virtio_net_hdr hdr;
@@ -147,6 +151,10 @@ static void skb_xmit_done(struct virtqueue *svq)
/* Suppress further interrupts. */
virtqueue_disable_cb(svq);
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(vi->dev, 0))
+ return;
+#endif
/* We were probably waiting for more output buffers. */
netif_wake_queue(vi->dev);
}
@@ -529,7 +537,16 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
void *buf;
unsigned int len, received = 0;
+#ifdef DEV_NETMAP
+ int work_done = 0;
+ if (netmap_rx_irq(vi->dev, 0, &work_done)) {
+ napi_complete(napi);
+ ND("called netmap_rx_irq");
+
+ return 1;
+ }
+#endif
again:
while (received < budget &&
(buf = virtqueue_get_buf(vi->rvq, &len)) != NULL) {
@@ -742,6 +759,15 @@ static void virtnet_netpoll(struct net_device *dev)
static int virtnet_open(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+#ifdef DEV_NETMAP
+ int ok = virtio_netmap_init_buffers(vi);
+
+ netmap_enable_all_rings(dev);
+ if (ok) {
+ virtnet_napi_enable(vi);
+ return 0;
+ }
+#endif
/* Make sure we have some buffers: if oom use wq. */
if (!try_fill_recv(vi, GFP_KERNEL))
@@ -810,6 +836,9 @@ static int virtnet_close(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif
/* Make sure refill_work doesn't re-enable napi! */
cancel_delayed_work_sync(&vi->refill);
napi_disable(&vi->napi);
@@ -1148,6 +1177,10 @@ static int virtnet_probe(struct virtio_device *vdev)
goto unregister;
}
+#ifdef DEV_NETMAP
+ virtio_netmap_attach(vi);
+#endif
+
/* Assume link up if device can't report link status,
otherwise get link status from config. */
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1211,6 +1244,9 @@ static void __devexit virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
+#ifdef DEV_NETMAP
+ netmap_detach(vi->dev);
+#endif
/* Prevent config work handler from accessing the device. */
mutex_lock(&vi->config_lock);
vi->config_enable = false;

View File

@ -0,0 +1,91 @@
diff --git a/virtio_net.c b/virtio_net.c
index 35c00c5..8aaaa7e 100644
--- a/virtio_net.c
+++ b/virtio_net.c
@@ -132,6 +132,10 @@ struct virtnet_info {
struct notifier_block nb;
};
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <virtio_netmap.h>
+#endif
+
struct skb_vnet_hdr {
union {
struct virtio_net_hdr hdr;
@@ -211,6 +215,10 @@ static void skb_xmit_done(struct virtqueue *vq)
/* Suppress further interrupts. */
virtqueue_disable_cb(vq);
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(vi->dev, vq2txq(vq)))
+ return;
+#endif
/* We were probably waiting for more output buffers. */
netif_wake_subqueue(vi->dev, vq2txq(vq));
}
@@ -603,7 +611,16 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
struct virtnet_info *vi = rq->vq->vdev->priv;
void *buf;
unsigned int len, received = 0;
+#ifdef DEV_NETMAP
+ int work_done = 0;
+ if (netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done)) {
+ napi_complete(napi);
+ ND("called netmap_rx_irq");
+
+ return 1;
+ }
+#endif
again:
while (received < budget &&
(buf = virtqueue_get_buf(rq->vq, &len)) != NULL) {
@@ -635,6 +652,16 @@ static int virtnet_open(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
int i;
+#ifdef DEV_NETMAP
+ int ok = virtio_netmap_init_buffers(vi);
+
+ netmap_enable_all_rings(dev);
+ if (ok) {
+ for (i = 0; i < vi->max_queue_pairs; i++)
+ virtnet_napi_enable(&vi->rq[i]);
+ return 0;
+ }
+#endif
for (i = 0; i < vi->max_queue_pairs; i++) {
/* Make sure we have some buffers: if oom use wq. */
@@ -909,6 +936,9 @@ static int virtnet_close(struct net_device *dev)
struct virtnet_info *vi = netdev_priv(dev);
int i;
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif
/* Make sure refill_work doesn't re-enable napi! */
cancel_delayed_work_sync(&vi->refill);
@@ -1572,6 +1602,10 @@ static int virtnet_probe(struct virtio_device *vdev)
goto free_recv_bufs;
}
+#ifdef DEV_NETMAP
+ virtio_netmap_attach(vi);
+#endif
+
/* Assume link up if device can't report link status,
otherwise get link status from config. */
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1618,6 +1652,9 @@ static void virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
+#ifdef DEV_NETMAP
+ netmap_detach(vi->dev);
+#endif
unregister_hotcpu_notifier(&vi->nb);
/* Prevent config work handler from accessing the device. */

View File

@ -0,0 +1,91 @@
diff --git a/virtio_net.c b/virtio_net.c
index 3d2a90a..ae899a4 100644
--- a/virtio_net.c
+++ b/virtio_net.c
@@ -131,6 +131,10 @@ struct virtnet_info {
struct notifier_block nb;
};
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <virtio_netmap.h>
+#endif
+
struct skb_vnet_hdr {
union {
struct virtio_net_hdr hdr;
@@ -210,6 +214,10 @@ static void skb_xmit_done(struct virtqueue *vq)
/* Suppress further interrupts. */
virtqueue_disable_cb(vq);
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(vi->dev, vq2txq(vq)))
+ return;
+#endif
/* We were probably waiting for more output buffers. */
netif_wake_subqueue(vi->dev, vq2txq(vq));
}
@@ -603,7 +611,16 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
struct virtnet_info *vi = rq->vq->vdev->priv;
void *buf;
unsigned int r, len, received = 0;
+#ifdef DEV_NETMAP
+ int work_done = 0;
+ if (netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done)) {
+ napi_complete(napi);
+ ND("called netmap_rx_irq");
+
+ return 1;
+ }
+#endif
again:
while (received < budget &&
(buf = virtqueue_get_buf(rq->vq, &len)) != NULL) {
@@ -636,6 +653,16 @@ static int virtnet_open(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
int i;
+#ifdef DEV_NETMAP
+ int ok = virtio_netmap_init_buffers(vi);
+
+ netmap_enable_all_rings(dev);
+ if (ok) {
+ for (i = 0; i < vi->max_queue_pairs; i++)
+ virtnet_napi_enable(&vi->rq[i]);
+ return 0;
+ }
+#endif
for (i = 0; i < vi->max_queue_pairs; i++) {
if (i < vi->curr_queue_pairs)
@@ -927,6 +954,9 @@ static int virtnet_close(struct net_device *dev)
struct virtnet_info *vi = netdev_priv(dev);
int i;
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif
/* Make sure refill_work doesn't re-enable napi! */
cancel_delayed_work_sync(&vi->refill);
@@ -1592,6 +1622,10 @@ static int virtnet_probe(struct virtio_device *vdev)
goto free_recv_bufs;
}
+#ifdef DEV_NETMAP
+ virtio_netmap_attach(vi);
+#endif
+
/* Assume link up if device can't report link status,
otherwise get link status from config. */
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
@@ -1638,6 +1672,9 @@ static void virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
+#ifdef DEV_NETMAP
+ netmap_detach(vi->dev);
+#endif
unregister_hotcpu_notifier(&vi->nb);
/* Prevent config work handler from accessing the device. */