From 0c35d6ab7414b00539dbce93679226c435fd6b74 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Sat, 14 Sep 2013 14:24:59 +0200 Subject: [PATCH 01/41] original netmap drivers Conflicts: drivers/net/ethernet/intel/ixgbe/ixgbe_main.c --- drivers/net/ethernet/intel/e1000/e1000_main.c | 25 ++++++++++ drivers/net/ethernet/intel/e1000e/netdev.c | 23 +++++++++ drivers/net/ethernet/intel/igb/igb_main.c | 28 +++++++++++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 47 +++++++++++++++++++ drivers/net/ethernet/nvidia/forcedeth.c | 31 ++++++++++++ 5 files changed, 154 insertions(+) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index f42129d09e2c23..8cb40a85ca1d9d 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -229,6 +229,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 +#endif + /** * e1000_get_hw_dev - return device * used by hardware layer to print debugging information @@ -400,6 +404,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 @@ -1218,6 +1226,10 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) e1000_vlan_filter_on_off(adapter, false); +#ifdef DEV_NETMAP + e1000_netmap_attach(adapter); +#endif /* DEV_NETMAP */ + /* print bus type/speed/width info */ e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n", ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""), @@ -1282,6 +1294,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 */ if (hw->mac_type == e1000_ce4100) iounmap(hw->ce4100_gbe_mdio_base_virt); @@ -3866,6 +3882,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, 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); @@ -4388,6 +4408,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]; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 7017281ba2dc63..211f61c9618b1f 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -494,6 +494,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 +#endif + /** * e1000e_systim_to_hwtstamp - convert system time value to hw time stamp * @adapter: board private structure @@ -936,6 +940,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); @@ -1224,6 +1232,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); @@ -3740,6 +3752,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); } @@ -7314,6 +7330,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); @@ -7405,6 +7424,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) && (adapter->hw.mac.type < e1000_pch_spt)) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 9affd7c198bd23..28fec4c7cd3aa0 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -256,6 +256,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 +#endif + struct igb_reg_info { u32 ofs; char *name; @@ -2646,6 +2650,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; @@ -2914,6 +2922,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. @@ -3400,6 +3412,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 */ } /** @@ -6645,6 +6660,10 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget) 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); @@ -7153,6 +7172,10 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) unsigned int total_bytes = 0, total_packets = 0; u16 cleaned_count = igb_desc_unused(rx_ring); +#ifdef DEV_NETMAP + if (netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &total_packets)) + return true; +#endif /* DEV_NETMAP */ while (likely(total_packets < budget)) { union e1000_adv_rx_desc *rx_desc; @@ -7270,6 +7293,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; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index fee1f2918eadc1..a1f19ed0356335 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -497,6 +497,22 @@ static const struct ixgbe_reg_info ixgbe_reg_info_tbl[] = { { .name = NULL } }; +#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. + * + * 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 +#endif /* * ixgbe_regdump - register printout routine @@ -1159,6 +1175,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; @@ -2112,6 +2139,15 @@ static int 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 */ + while (likely(total_rx_packets < budget)) { union ixgbe_adv_rx_desc *rx_desc; struct sk_buff *skb; @@ -3225,6 +3261,9 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, } while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE)); if (!wait_loop) hw_dbg(hw, "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) @@ -3720,6 +3759,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)); } @@ -6142,6 +6185,10 @@ int ixgbe_open(struct net_device *netdev) ixgbe_clear_udp_tunnel_port(adapter, IXGBE_VXLANCTRL_ALL_UDPPORT_MASK); udp_tunnel_get_rx_info(netdev); +#ifdef DEV_NETMAP + ixgbe_netmap_attach(adapter); +#endif /* DEV_NETMAP */ + return 0; err_set_queues: diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 9b0d7f463ff3a0..a49643d7654a8d 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -1962,12 +1962,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 +#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); @@ -3660,6 +3673,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(events, base + NvRegMSIXIrqStatus); @@ -3772,6 +3790,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(events, base + NvRegMSIXIrqStatus); @@ -5982,6 +6005,10 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) goto out_error; } +#ifdef DEV_NETMAP + forcedeth_netmap_attach(np); +#endif /* DEV_NETMAP */ + netif_carrier_off(dev); /* Some NICs freeze when TX pause is enabled while NIC is @@ -6078,6 +6105,10 @@ static void 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 */ From a060073ccd039718218d5af6b1dab6c93dd8cf4b Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Sun, 15 Sep 2013 10:07:39 +0200 Subject: [PATCH 02/41] enable/disable netmap on up/down --- drivers/net/ethernet/intel/e1000/e1000_main.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 8cb40a85ca1d9d..f4f64034ba9c54 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -434,6 +434,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; @@ -536,6 +540,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 */ @@ -1426,6 +1434,10 @@ 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); From ef94f83c710498a8b071ad32a7035516ace504f9 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Thu, 19 Sep 2013 16:23:49 +0200 Subject: [PATCH 03/41] [ixgbe] netmap attach moved to probe Conflicts: drivers/net/ethernet/intel/ixgbe/ixgbe_main.c --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index a1f19ed0356335..9f7673cf258a2c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -6185,10 +6185,6 @@ int ixgbe_open(struct net_device *netdev) ixgbe_clear_udp_tunnel_port(adapter, IXGBE_VXLANCTRL_ALL_UDPPORT_MASK); udp_tunnel_get_rx_info(netdev); -#ifdef DEV_NETMAP - ixgbe_netmap_attach(adapter); -#endif /* DEV_NETMAP */ - return 0; err_set_queues: @@ -9846,6 +9842,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 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: From 4167ad81111012b9436e19a869d992f9d8cf9f33 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Thu, 19 Sep 2013 17:50:34 +0200 Subject: [PATCH 04/41] [ixgbe] enable/disable netmap on ifconfig up/down Conflicts: drivers/net/ethernet/intel/ixgbe/ixgbe_main.c --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 9f7673cf258a2c..4bdec7d03cccb1 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -5314,6 +5314,10 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter) e_crit(drv, "Fan has stopped, replace the adapter\n"); } +#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; @@ -5538,6 +5542,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter) clear_bit(__IXGBE_RESET_REQUESTED, &adapter->state); adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT; +#ifdef DEV_NETMAP + netmap_disable_all_rings(netdev); +#endif + adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; del_timer_sync(&adapter->service_timer); From b7cba1e5f1c0186e27166b6da5a47f5b0c4908d3 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Thu, 26 Sep 2013 12:54:17 +0200 Subject: [PATCH 05/41] [e1000e] enable/disable netmap on if up/down Conflicts: drivers/net/ethernet/intel/e1000e/netdev.c --- drivers/net/ethernet/intel/e1000e/netdev.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 211f61c9618b1f..205d9c5698da4a 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -4267,6 +4267,10 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset) 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; @@ -4648,6 +4652,10 @@ int e1000e_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 */ + hw->mac.get_link_status = true; pm_runtime_put(&pdev->dev); From c2aa830e022e5676944d01cedac0d0de4852c570 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Tue, 1 Oct 2013 11:58:55 +0200 Subject: [PATCH 06/41] [igb] enable/disable netmap on if up/down Conflicts: drivers/net/ethernet/intel/igb/igb_main.c --- drivers/net/ethernet/intel/igb/igb_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 28fec4c7cd3aa0..4aae1f811ea075 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1764,6 +1764,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); @@ -1814,6 +1818,10 @@ void igb_down(struct igb_adapter *adapter) } } +#ifdef DEV_NETMAP + netmap_disable_all_rings(netdev); +#endif /* DEV_NETMAP */ + del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); From dfb22bdd9c1be29a25628ac02c415f65bd218082 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Tue, 1 Oct 2013 16:15:52 +0200 Subject: [PATCH 07/41] [igb] added missing netmap enable --- drivers/net/ethernet/intel/igb/igb_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 4aae1f811ea075..60795a689a9b5a 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -3225,6 +3225,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); From 7f5b020df066431209e21a76f018cafcf6a0d979 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Wed, 11 Dec 2013 12:12:01 +0100 Subject: [PATCH 08/41] netmap adapter for virtio Conflicts: drivers/net/virtio_net.c --- drivers/net/virtio_net.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index cbf1c613c67aef..eff94ab2c9f5b6 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -155,6 +155,10 @@ struct virtnet_info { u32 speed; }; +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) +#include +#endif + struct padded_vnet_hdr { struct virtio_net_hdr_mrg_rxbuf hdr; /* @@ -227,6 +231,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, 0)) + return; +#endif /* We were probably waiting for more output buffers. */ netif_wake_subqueue(vi->dev, vq2txq(vq)); } @@ -710,6 +718,16 @@ static int virtnet_receive(struct receive_queue *rq, int budget) unsigned int len, received = 0; void *buf; +#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 while (received < budget && (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) { receive_buf(vi, rq, buf, len); @@ -787,6 +805,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) @@ -1098,6 +1126,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); @@ -1928,6 +1959,10 @@ static int virtnet_probe(struct virtio_device *vdev) goto free_unregister_netdev; } +#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)) { @@ -1976,6 +2011,9 @@ static void virtnet_remove(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv; +#ifdef DEV_NETMAP + netmap_detach(vi->dev); +#endif virtnet_cpu_notif_remove(vi); /* Make sure no work handler is accessing the device. */ From 838b171111a3b4e301550ededa2641c4c6750cae Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Thu, 19 Dec 2013 11:48:31 +0100 Subject: [PATCH 09/41] [virtio-patch] use right multiqueue indexes --- drivers/net/virtio_net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index eff94ab2c9f5b6..a18314df94e853 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -232,7 +232,7 @@ static void skb_xmit_done(struct virtqueue *vq) virtqueue_disable_cb(vq); #ifdef DEV_NETMAP - if (netmap_tx_irq(vi->dev, 0)) + if (netmap_tx_irq(vi->dev, vq2txq(vq))) return; #endif /* We were probably waiting for more output buffers. */ @@ -721,7 +721,7 @@ static int virtnet_receive(struct receive_queue *rq, int budget) #ifdef DEV_NETMAP int work_done = 0; - if (netmap_rx_irq(vi->dev, 0, &work_done)) { + if (netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done)) { napi_complete(napi); ND("called netmap_rx_irq"); From 9cd4a5e013029c8fd7fb4f668410ca180a7dedd4 Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Sat, 13 Sep 2014 02:29:44 +0200 Subject: [PATCH 10/41] netfront: patched xen-netfront driver for netmap Conflicts: drivers/net/xen-netfront.c --- drivers/net/xen-netfront.c | 48 +++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index bf2744e1e3db94..e91c2d98443a37 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -141,6 +141,10 @@ struct netfront_queue { struct sk_buff *rx_skbs[NET_RX_RING_SIZE]; grant_ref_t gref_rx_head; grant_ref_t grant_rx_ref[NET_RX_RING_SIZE]; +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) + int netmap_rx_handoff; +#endif /* DEV_NETMAP */ + }; struct netfront_info { @@ -159,6 +163,10 @@ struct netfront_info { atomic_t rx_gso_checksum_fixup; }; +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) +#include +#endif + struct netfront_rx_info { struct xen_netif_rx_response rx; struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1]; @@ -282,6 +290,11 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue) RING_IDX req_prod = queue->rx.req_prod_pvt; int notify; +#ifdef DEV_NETMAP + if (unlikely(netfront_netmap_alloc_rx_buffers(queue))) + return; +#endif /* DEV_NETMAP */ + if (unlikely(!netif_carrier_ok(queue->info->netdev))) return; @@ -339,6 +352,20 @@ static int xennet_open(struct net_device *dev) unsigned int num_queues = dev->real_num_tx_queues; unsigned int i = 0; struct netfront_queue *queue = NULL; +#ifdef DEV_NETMAP + + netmap_enable_all_rings(dev); + if (nm_native_on(NA(dev))) { + for (i = 0; i < num_queues; ++i) { + queue = &np->queues[i]; + napi_enable(&queue->napi); + } + + netif_tx_start_all_queues(dev); + + return 0; + } +#endif /* DEV_NETMAP */ for (i = 0; i < num_queues; ++i) { queue = &np->queues[i]; @@ -701,6 +728,9 @@ static int xennet_close(struct net_device *dev) unsigned int num_queues = dev->real_num_tx_queues; unsigned int i; struct netfront_queue *queue; +#ifdef DEV_NETMAP + netmap_disable_all_rings(dev); +#endif /* DEV_NETMAP */ netif_tx_stop_all_queues(np->netdev); for (i = 0; i < num_queues; ++i) { queue = &np->queues[i]; @@ -983,6 +1013,11 @@ static int xennet_poll(struct napi_struct *napi, int budget) spin_lock(&queue->rx_lock); +#ifdef DEV_NETMAP + if (netfront_netmap_poll(napi, &work_done)) + return work_done; +#endif /* DEV_NETMAP */ + skb_queue_head_init(&rxq); skb_queue_head_init(&errq); skb_queue_head_init(&tmpq); @@ -1226,6 +1261,10 @@ static irqreturn_t xennet_tx_interrupt(int irq, void *dev_id) struct netfront_queue *queue = dev_id; unsigned long flags; +#ifdef DEV_NETMAP + if (netmap_tx_irq(queue->info->netdev, queue->id)) + return IRQ_HANDLED; +#endif /* DEV_NETMAP */ spin_lock_irqsave(&queue->tx_lock, flags); xennet_tx_buf_gc(queue); spin_unlock_irqrestore(&queue->tx_lock, flags); @@ -1237,7 +1276,6 @@ static irqreturn_t xennet_rx_interrupt(int irq, void *dev_id) { struct netfront_queue *queue = dev_id; struct net_device *dev = queue->info->netdev; - if (likely(netif_carrier_ok(dev) && RING_HAS_UNCONSUMED_RESPONSES(&queue->rx))) napi_schedule(&queue->napi); @@ -1372,6 +1410,10 @@ static int netfront_probe(struct xenbus_device *dev, goto fail; } +#ifdef DEV_NETMAP + netfront_netmap_attach(info); +#endif /* DEV_NETMAP */ + return 0; fail: @@ -2161,6 +2203,10 @@ static int xennet_remove(struct xenbus_device *dev) xennet_disconnect_backend(info); +#ifdef DEV_NETMAP + netmap_detach(info->netdev); +#endif /* DEV_NETMAP */ + unregister_netdev(info->netdev); if (info->queues) From d39e1d5b9b93941ab6c45b7226865b46c49edc51 Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Thu, 18 Sep 2014 01:43:16 +0200 Subject: [PATCH 11/41] netfront-netmap: add support for tx handoff --- drivers/net/xen-netfront.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index e91c2d98443a37..7b43d35aff554d 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -143,6 +143,7 @@ struct netfront_queue { grant_ref_t grant_rx_ref[NET_RX_RING_SIZE]; #if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) int netmap_rx_handoff; + int netmap_tx_handoff; #endif /* DEV_NETMAP */ }; @@ -381,7 +382,15 @@ static int xennet_open(struct net_device *dev) spin_unlock_bh(&queue->rx_lock); } +#ifdef DEV_NETMAP + for (i = 0; i < num_queues; ++i) { + queue = &np->queues[i]; + if (!queue->netmap_tx_handoff) + netif_tx_start_queue(netdev_get_tx_queue(dev, i)); + } +#else /* ! DEV_NETMAP */ netif_tx_start_all_queues(dev); +#endif /* DEV_NETMAP */ return 0; } @@ -1260,9 +1269,8 @@ static irqreturn_t xennet_tx_interrupt(int irq, void *dev_id) { struct netfront_queue *queue = dev_id; unsigned long flags; - #ifdef DEV_NETMAP - if (netmap_tx_irq(queue->info->netdev, queue->id)) + if (netfront_netmap_tx_irq(queue)) return IRQ_HANDLED; #endif /* DEV_NETMAP */ spin_lock_irqsave(&queue->tx_lock, flags); From c728993b00113d2a7870718fdb519c97aed88249 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Tue, 7 Oct 2014 16:40:18 +0200 Subject: [PATCH 12/41] virtio: fix compilation Conflicts: drivers/net/virtio_net.c --- drivers/net/virtio_net.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index a18314df94e853..16cb1ab076bfba 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -718,16 +718,6 @@ static int virtnet_receive(struct receive_queue *rq, int budget) unsigned int len, received = 0; void *buf; -#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 while (received < budget && (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) { receive_buf(vi, rq, buf, len); @@ -748,6 +738,18 @@ static int virtnet_poll(struct napi_struct *napi, int budget) container_of(napi, struct receive_queue, napi); unsigned int r, received; +#ifdef DEV_NETMAP + int work_done = 0; + struct virtnet_info *vi = rq->vq->vdev->priv; + + if (netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done)) { + napi_complete(napi); + ND("called netmap_rx_irq"); + + return 1; + } +#endif + received = virtnet_receive(rq, budget); /* Out of packets? */ From 1867f26f6297ae19a5177cfc1b155d42b17f4da9 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Fri, 20 Sep 2013 15:00:50 +0200 Subject: [PATCH 13/41] [ixgbe] detach from netmap on removal Conflicts: drivers/net/ethernet/intel/ixgbe/ixgbe_main.c --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 4bdec7d03cccb1..1722a1ceda5b84 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -9898,6 +9898,11 @@ static void ixgbe_remove(struct pci_dev *pdev) return; netdev = adapter->netdev; + +#ifdef DEV_NETMAP + netmap_detach(netdev); +#endif /* DEV_NETMAP */ + ixgbe_dbg_adapter_exit(adapter); set_bit(__IXGBE_REMOVING, &adapter->state); From d435888f74cda6aa8a65ad0b1b29db34b41d956e Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Sun, 11 Jan 2015 15:55:56 +0100 Subject: [PATCH 14/41] veth: add netmap support --- drivers/net/veth.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/veth.c b/drivers/net/veth.c index fbc853e6453185..09a0d22138c84c 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -38,6 +38,10 @@ struct veth_priv { unsigned requested_headroom; }; +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) +#include +#endif + /* * ethtool interface */ @@ -201,6 +205,9 @@ static int veth_open(struct net_device *dev) netif_carrier_on(dev); netif_carrier_on(peer); } +#ifdef DEV_NETMAP + netmap_enable_all_rings(dev); +#endif /* DEV_NETMAP */ return 0; } @@ -209,6 +216,9 @@ static int veth_close(struct net_device *dev) struct veth_priv *priv = netdev_priv(dev); struct net_device *peer = rtnl_dereference(priv->peer); +#ifdef DEV_NETMAP + netmap_disable_all_rings(dev); +#endif /* DEV_NETMAP */ netif_carrier_off(dev); if (peer) netif_carrier_off(peer); @@ -234,11 +244,17 @@ static int veth_dev_init(struct net_device *dev) dev->vstats = netdev_alloc_pcpu_stats(struct pcpu_vstats); if (!dev->vstats) return -ENOMEM; +#ifdef DEV_NETMAP + veth_netmap_attach(dev); +#endif /* DEV_NETMAP */ return 0; } static void veth_dev_free(struct net_device *dev) { +#ifdef DEV_NETMAP + netmap_detach(dev); +#endif /* DEV_NETMAP */ free_percpu(dev->vstats); free_netdev(dev); } From 6e7ae27438a5c10dd5d5e0a29859ee4da27bbb76 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Mon, 2 Mar 2015 15:55:47 +0100 Subject: [PATCH 15/41] i40e: attach/detach Conflicts: drivers/net/ethernet/intel/i40e/i40e_main.c --- drivers/net/ethernet/intel/i40e/i40e_main.c | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 31c97e3937a423..9dc1edeb79d20b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -102,6 +102,22 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); static struct workqueue_struct *i40e_wq; +#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. + * + * 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 +#endif /** * i40e_allocate_dma_mem_d - OS specific memory alloc for shared code @@ -9519,6 +9535,11 @@ int i40e_vsi_release(struct i40e_vsi *vsi) return -ENODEV; } +#ifdef DEV_NETMAP + if (vsi->netdev_registered) + netmap_detach(vsi->netdev); +#endif + uplink_seid = vsi->uplink_seid; if (vsi->type != I40E_VSI_SRIOV) { if (vsi->netdev_registered) { @@ -9883,6 +9904,12 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type, (vsi->type == I40E_VSI_VMDQ2)) { ret = i40e_vsi_config_rss(vsi); } + +#ifdef DEV_NETMAP + if (vsi->netdev_registered) + i40e_netmap_attach(vsi); +#endif + return vsi; err_rings: From c32154d589e4763554748f60ae4b9c100349f524 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Tue, 3 Mar 2015 17:04:28 +0100 Subject: [PATCH 16/41] i40e: configure rings Conflicts: drivers/net/ethernet/intel/i40e/i40e_main.c --- drivers/net/ethernet/intel/i40e/i40e_main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 9dc1edeb79d20b..9998c098ddd15e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2912,6 +2912,10 @@ static int i40e_configure_tx_ring(struct i40e_ring *ring) /* cache tail off for easier writes later */ ring->tail = hw->hw_addr + I40E_QTX_TAIL(pf_q); +#ifdef DEV_NETMAP + i40e_netmap_configure_tx_ring(ring); +#endif /* DEV_NETMAP */ + return 0; } @@ -2987,6 +2991,11 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) ring->tail = hw->hw_addr + I40E_QRX_TAIL(pf_q); writel(0, ring->tail); +#ifdef DEV_NETMAP + if (i40e_netmap_configure_rx_ring(ring)) + return 0; +#endif /* DEV_NETMAP */ + i40e_alloc_rx_buffers(ring, I40E_DESC_UNUSED(ring)); return 0; From 90ac3f804e4db6d2f6e44d5bb905c82f62b2a576 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Tue, 3 Mar 2015 17:52:20 +0100 Subject: [PATCH 17/41] i40e: proper include of netmap header --- drivers/net/ethernet/intel/i40e/i40e_main.c | 14 +------------- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 4 ++++ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 9998c098ddd15e..70bbb1d7f796fa 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -103,19 +103,7 @@ MODULE_VERSION(DRV_VERSION); static struct workqueue_struct *i40e_wq; #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. - * - * 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 - */ +#define NETMAP_I40E_MAIN #include #endif diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 6287bf63c43cae..6db10df090a86a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -29,6 +29,10 @@ #include "i40e.h" #include "i40e_prototype.h" +#if defined(CONFIG_NETMAP) || defined (CONFIG_NETMAP_MODULE) +#include +#endif /* DEV_NETMAP */ + static inline __le64 build_ctob(u32 td_cmd, u32 td_offset, unsigned int size, u32 td_tag) { From b2edeb35b2a2f710ad4d85c3b8b106cee463379e Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Tue, 3 Mar 2015 18:03:10 +0100 Subject: [PATCH 18/41] i40e: enable/disable rings --- drivers/net/ethernet/intel/i40e/i40e_main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 70bbb1d7f796fa..fb2c0b59ff62d7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5211,6 +5211,11 @@ static int i40e_up_complete(struct i40e_vsi *vsi) i40e_napi_enable_all(vsi); i40e_vsi_enable_irq(vsi); +#ifdef DEV_NETMAP + if (vsi->netdev) + netmap_enable_all_rings(vsi->netdev); +#endif /* DEV_NETMAP */ + if ((pf->hw.phy.link_info.link_info & I40E_AQ_LINK_UP) && (vsi->netdev)) { i40e_print_link_message(vsi, true); @@ -5303,6 +5308,11 @@ void i40e_down(struct i40e_vsi *vsi) i40e_vsi_control_rings(vsi, false); i40e_napi_disable_all(vsi); +#ifdef DEV_NETMAP + if (vsi->netdev) + netmap_disable_all_rings(vsi->netdev); +#endif /* DEV_NETMAP */ + for (i = 0; i < vsi->num_queue_pairs; i++) { i40e_clean_tx_ring(vsi->tx_rings[i]); i40e_clean_rx_ring(vsi->rx_rings[i]); From fbfbc59dff21dc2e5aa0c68c90f9ac84f2861fd0 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Tue, 3 Mar 2015 18:08:37 +0100 Subject: [PATCH 19/41] i40e: irqs Conflicts: drivers/net/ethernet/intel/i40e/i40e_txrx.c --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 6db10df090a86a..acd38ca5df1bc9 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -669,6 +669,11 @@ static bool i40e_clean_tx_irq(struct i40e_vsi *vsi, unsigned int total_bytes = 0, total_packets = 0; unsigned int budget = vsi->work_limit; +#ifdef DEV_NETMAP + if (tx_ring->netdev && netmap_tx_irq(tx_ring->netdev, tx_ring->queue_index)) + return true; +#endif /* DEV_NETMAP */ + tx_buf = &tx_ring->tx_bi[i]; tx_desc = I40E_TX_DESC(tx_ring, i); i -= tx_ring->count; @@ -1768,6 +1773,13 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) u16 cleaned_count = I40E_DESC_UNUSED(rx_ring); bool failure = false; +#ifdef DEV_NETMAP + int dummy; + if (rx_ring->netdev && + netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy)) + return 1; +#endif /* DEV_NETMAP */ + while (likely(total_rx_packets < budget)) { union i40e_rx_desc *rx_desc; struct sk_buff *skb; From 081dd6d08e3d9974ef9d46f7ce67f6ca96ae40b3 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Mon, 7 Sep 2015 16:44:11 +0200 Subject: [PATCH 20/41] removed all enable/disable rings Conflicts: drivers/net/ethernet/intel/e1000e/netdev.c drivers/net/ethernet/intel/ixgbe/ixgbe_main.c --- drivers/net/ethernet/intel/e1000/e1000_main.c | 12 ------------ drivers/net/ethernet/intel/e1000e/netdev.c | 8 -------- drivers/net/ethernet/intel/i40e/i40e_main.c | 10 ---------- drivers/net/ethernet/intel/igb/igb_main.c | 12 ------------ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 9 ++------- drivers/net/veth.c | 6 ------ drivers/net/virtio_net.c | 4 ---- drivers/net/xen-netfront.c | 4 ---- 8 files changed, 2 insertions(+), 63 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index f4f64034ba9c54..8cb40a85ca1d9d 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -434,10 +434,6 @@ 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; @@ -540,10 +536,6 @@ 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 */ @@ -1434,10 +1426,6 @@ 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); diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 205d9c5698da4a..211f61c9618b1f 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -4267,10 +4267,6 @@ void e1000e_down(struct e1000_adapter *adapter, bool reset) 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; @@ -4652,10 +4648,6 @@ int e1000e_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 */ - hw->mac.get_link_status = true; pm_runtime_put(&pdev->dev); diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index fb2c0b59ff62d7..70bbb1d7f796fa 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5211,11 +5211,6 @@ static int i40e_up_complete(struct i40e_vsi *vsi) i40e_napi_enable_all(vsi); i40e_vsi_enable_irq(vsi); -#ifdef DEV_NETMAP - if (vsi->netdev) - netmap_enable_all_rings(vsi->netdev); -#endif /* DEV_NETMAP */ - if ((pf->hw.phy.link_info.link_info & I40E_AQ_LINK_UP) && (vsi->netdev)) { i40e_print_link_message(vsi, true); @@ -5308,11 +5303,6 @@ void i40e_down(struct i40e_vsi *vsi) i40e_vsi_control_rings(vsi, false); i40e_napi_disable_all(vsi); -#ifdef DEV_NETMAP - if (vsi->netdev) - netmap_disable_all_rings(vsi->netdev); -#endif /* DEV_NETMAP */ - for (i = 0; i < vsi->num_queue_pairs; i++) { i40e_clean_tx_ring(vsi->tx_rings[i]); i40e_clean_rx_ring(vsi->rx_rings[i]); diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 60795a689a9b5a..28fec4c7cd3aa0 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1764,10 +1764,6 @@ 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); @@ -1818,10 +1814,6 @@ void igb_down(struct igb_adapter *adapter) } } -#ifdef DEV_NETMAP - netmap_disable_all_rings(netdev); -#endif /* DEV_NETMAP */ - del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); @@ -3225,10 +3217,6 @@ 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); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 1722a1ceda5b84..b23b07ef4a2e4b 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -5314,9 +5314,8 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter) e_crit(drv, "Fan has stopped, replace the adapter\n"); } -#ifdef DEV_NETMAP - netmap_enable_all_rings(adapter->netdev); -#endif + /* enable transmits */ + netif_tx_start_all_queues(adapter->netdev); /* bring the link up in the watchdog, this could race with our first * link up interrupt but shouldn't be a problem */ @@ -5542,10 +5541,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter) clear_bit(__IXGBE_RESET_REQUESTED, &adapter->state); adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT; -#ifdef DEV_NETMAP - netmap_disable_all_rings(netdev); -#endif - adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; del_timer_sync(&adapter->service_timer); diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 09a0d22138c84c..abc6be75e44f6d 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -205,9 +205,6 @@ static int veth_open(struct net_device *dev) netif_carrier_on(dev); netif_carrier_on(peer); } -#ifdef DEV_NETMAP - netmap_enable_all_rings(dev); -#endif /* DEV_NETMAP */ return 0; } @@ -216,9 +213,6 @@ static int veth_close(struct net_device *dev) struct veth_priv *priv = netdev_priv(dev); struct net_device *peer = rtnl_dereference(priv->peer); -#ifdef DEV_NETMAP - netmap_disable_all_rings(dev); -#endif /* DEV_NETMAP */ netif_carrier_off(dev); if (peer) netif_carrier_off(peer); diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 16cb1ab076bfba..74c5e6d2fe082b 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -810,7 +810,6 @@ static int virtnet_open(struct net_device *dev) #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]); @@ -1128,9 +1127,6 @@ 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); diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 7b43d35aff554d..b26ff2a60d3f91 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -355,7 +355,6 @@ static int xennet_open(struct net_device *dev) struct netfront_queue *queue = NULL; #ifdef DEV_NETMAP - netmap_enable_all_rings(dev); if (nm_native_on(NA(dev))) { for (i = 0; i < num_queues; ++i) { queue = &np->queues[i]; @@ -737,9 +736,6 @@ static int xennet_close(struct net_device *dev) unsigned int num_queues = dev->real_num_tx_queues; unsigned int i; struct netfront_queue *queue; -#ifdef DEV_NETMAP - netmap_disable_all_rings(dev); -#endif /* DEV_NETMAP */ netif_tx_stop_all_queues(np->netdev); for (i = 0; i < num_queues; ++i) { queue = &np->queues[i]; From ddf2cfb5548eacd9352dd885dbf0111c9fcda1ff Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Wed, 16 Sep 2015 14:53:41 +0200 Subject: [PATCH 21/41] [ptnetmap/virtio] enable ptnetmap feature Conflicts: drivers/net/virtio_net.c --- drivers/net/virtio_net.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 74c5e6d2fe082b..d041df61d15432 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2108,6 +2108,9 @@ static unsigned int features_legacy[] = { VIRTNET_FEATURES, VIRTIO_NET_F_GSO, VIRTIO_F_ANY_LAYOUT, +#ifdef VIRTIO_NET_F_PTNETMAP + VIRTIO_NET_F_PTNETMAP, +#endif }; static struct virtio_driver virtio_net_driver = { From c2bc1dda4621de31281da35ba8c94cfb7a034c05 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Wed, 18 Nov 2015 11:23:47 +0100 Subject: [PATCH 22/41] i40e: remove useless check --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index acd38ca5df1bc9..1d04b4121bca79 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -670,7 +670,7 @@ static bool i40e_clean_tx_irq(struct i40e_vsi *vsi, unsigned int budget = vsi->work_limit; #ifdef DEV_NETMAP - if (tx_ring->netdev && netmap_tx_irq(tx_ring->netdev, tx_ring->queue_index)) + if (netmap_tx_irq(tx_ring->netdev, tx_ring->queue_index)) return true; #endif /* DEV_NETMAP */ From f23fd7d8e2a439211a8dc081b3be87cc9398a5e0 Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Thu, 19 Nov 2015 12:46:47 +0100 Subject: [PATCH 23/41] virtio-net: perform cleanup after netmap_detach() --- drivers/net/virtio_net.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index d041df61d15432..f5cb91a7e01643 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2008,9 +2008,13 @@ static void remove_vq_common(struct virtnet_info *vi) static void virtnet_remove(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv; - #ifdef DEV_NETMAP - netmap_detach(vi->dev); + /* Save the pointer, will go away after netmap_detach(). */ + struct netmap_adapter *token = NA(vi->dev); + + netmap_detach(vi->dev); + virtio_netmap_clean_used_rings(vi, token); + virtio_netmap_reclaim_unused(vi); #endif virtnet_cpu_notif_remove(vi); From 53cc59a0a7d1e6d95afd3641a25701a13b338024 Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Tue, 16 Feb 2016 12:20:03 +0100 Subject: [PATCH 24/41] netmap: virtio-net: use NM_IRQ_* return codes --- drivers/net/virtio_net.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index f5cb91a7e01643..be4daabbc51b7a 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -741,13 +741,14 @@ static int virtnet_poll(struct napi_struct *napi, int budget) #ifdef DEV_NETMAP int work_done = 0; struct virtnet_info *vi = rq->vq->vdev->priv; + int nm_irq = netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done); - if (netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done)) { + if (nm_irq == NM_IRQ_COMPLETED) { napi_complete(napi); - ND("called netmap_rx_irq"); - return 1; - } + } else if (nm_irq == NM_IRQ_RESCHED) { + return budget; + } #endif received = virtnet_receive(rq, budget); From ff303b6b0ff8d2fbc533cafdf815c78f3b835334 Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Tue, 16 Feb 2016 17:35:58 +0100 Subject: [PATCH 25/41] netmap: ixgbe: use NM_IRQ_* return codes --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index b23b07ef4a2e4b..2a71eac4a9560c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1182,7 +1182,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, * 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)) + if (netmap_tx_irq(adapter->netdev, tx_ring->queue_index) != NM_IRQ_PASS) return 1; /* seems to be ignored */ #endif /* DEV_NETMAP */ @@ -2143,9 +2143,10 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, /* * 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 */ + int dummy, nm_irq; + nm_irq = netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy); + if (nm_irq != NM_IRQ_PASS) + return (nm_irq == NM_IRQ_RESCHED) ? budget : 1; #endif /* DEV_NETMAP */ while (likely(total_rx_packets < budget)) { From 48e0c6464a03e230ff14154d1f6707fc378dd50c Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Tue, 16 Feb 2016 18:38:09 +0100 Subject: [PATCH 26/41] netmap: i40e: use NM_IRQ_* return codes --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 1d04b4121bca79..47c6af27f5e40b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -670,7 +670,7 @@ static bool i40e_clean_tx_irq(struct i40e_vsi *vsi, unsigned int budget = vsi->work_limit; #ifdef DEV_NETMAP - if (netmap_tx_irq(tx_ring->netdev, tx_ring->queue_index)) + if (netmap_tx_irq(tx_ring->netdev, tx_ring->queue_index) != NM_IRQ_PASS) return true; #endif /* DEV_NETMAP */ @@ -1776,7 +1776,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) #ifdef DEV_NETMAP int dummy; if (rx_ring->netdev && - netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy)) + netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy) != NM_IRQ_PASS) return 1; #endif /* DEV_NETMAP */ From 06ae0359b82b8d94e448640eb1710db31a09dd1b Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Wed, 17 Feb 2016 17:23:52 +0100 Subject: [PATCH 27/41] netmap: e1000: use NM_IRQ_* return codes --- drivers/net/ethernet/intel/e1000/e1000_main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 8cb40a85ca1d9d..656fc4d8c9dfed 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -3883,7 +3883,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, unsigned int bytes_compl = 0, pkts_compl = 0; #ifdef DEV_NETMAP - if (netmap_tx_irq(netdev, 0)) + if (netmap_tx_irq(netdev, 0) != NM_IRQ_PASS) return 1; /* cleaned ok */ #endif /* DEV_NETMAP */ i = tx_ring->next_to_clean; @@ -4409,9 +4409,13 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, 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 */ + int nm_irq = netmap_rx_irq(netdev, 0, work_done); + if (nm_irq != NM_IRQ_PASS) { + if (nm_irq == NM_IRQ_RESCHED) { + *work_done = work_to_do; + } + return 1; + } #endif /* DEV_NETMAP */ i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC(*rx_ring, i); From eb98324cf09a9a293aec9befb1563d5cc28fd477 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Fri, 4 Nov 2016 09:32:19 +0100 Subject: [PATCH 28/41] e1000: move name override before driver declaration --- drivers/net/ethernet/intel/e1000/e1000_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 656fc4d8c9dfed..ca5150cd1f4ed6 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -205,6 +205,10 @@ static const struct pci_error_handlers e1000_err_handler = { .resume = e1000_io_resume, }; +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) +#include +#endif + static struct pci_driver e1000_driver = { .name = e1000_driver_name, .id_table = e1000_pci_tbl, @@ -229,10 +233,6 @@ 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 -#endif - /** * e1000_get_hw_dev - return device * used by hardware layer to print debugging information From 8150fc21434c446d95c4e7c29dcae16f71cfbebf Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Wed, 12 Apr 2017 11:53:28 +0200 Subject: [PATCH 29/41] ixgbevf: initial patch --- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index cbf70fe4028a81..1212ce60010feb 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -294,6 +294,24 @@ static void ixgbevf_tx_timeout(struct net_device *netdev) ixgbevf_tx_timeout_reset(adapter); } +#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. + * + * 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 + */ +#define NM_IXGBEVF +#include +#endif + /** * ixgbevf_clean_tx_irq - Reclaim resources after transmit completes * @q_vector: board private structure @@ -313,6 +331,18 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector, if (test_bit(__IXGBEVF_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) != NM_IRQ_PASS) + return true; +#endif /* DEV_NETMAP */ + + tx_buffer = &tx_ring->tx_buffer_info[i]; tx_desc = IXGBEVF_TX_DESC(tx_ring, i); i -= tx_ring->count; @@ -929,6 +959,16 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, u16 cleaned_count = ixgbevf_desc_unused(rx_ring); struct sk_buff *skb = rx_ring->skb; +#ifdef DEV_NETMAP + /* + * Same as the txeof routine: only wakeup clients on intr. + */ + int dummy, nm_irq; + nm_irq = netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &dummy); + if (nm_irq != NM_IRQ_PASS) + return (nm_irq == NM_IRQ_RESCHED) ? budget : 1; +#endif /* DEV_NETMAP */ + while (likely(total_rx_packets < budget)) { union ixgbe_adv_rx_desc *rx_desc; @@ -1613,6 +1653,9 @@ static void ixgbevf_configure_tx_ring(struct ixgbevf_adapter *adapter, } while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE)); if (!wait_loop) hw_dbg(hw, "Could not enable Tx Queue %d\n", reg_idx); +#ifdef DEV_NETMAP + ixgbe_netmap_configure_tx_ring(adapter, reg_idx); +#endif /* DEV_NETMAP */ } /** @@ -1791,6 +1834,10 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter, IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(reg_idx), rxdctl); ixgbevf_rx_desc_queue_enable(adapter, ring); +#ifdef DEV_NETMAP + if (ixgbe_netmap_configure_rx_ring(adapter, reg_idx)) + return; +#endif /* DEV_NETMAP */ ixgbevf_alloc_rx_buffers(ring, ixgbevf_desc_unused(ring)); } @@ -4152,6 +4199,10 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } +#ifdef DEV_NETMAP + ixgbe_netmap_attach(adapter); +#endif /* DEV_NETMAP */ + return 0; err_register: @@ -4189,6 +4240,10 @@ static void ixgbevf_remove(struct pci_dev *pdev) if (!netdev) return; +#ifdef DEV_NETMAP + netmap_detach(netdev); +#endif /* DEV_NETMAP */ + adapter = netdev_priv(netdev); set_bit(__IXGBEVF_REMOVING, &adapter->state); From c51e6febbe2d83c10416dd893a23dcee2eee5a20 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Wed, 26 Apr 2017 12:22:48 +0200 Subject: [PATCH 30/41] igb: updated netmap_?x_irq() usages --- drivers/net/ethernet/intel/igb/igb_main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 28fec4c7cd3aa0..0b7e575d5f2706 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -6661,8 +6661,8 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector, int napi_budget) 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 */ + if (netmap_tx_irq(tx_ring->netdev, tx_ring->queue_index) != NM_IRQ_PASS) + return true; /* cleaned ok */ #endif /* DEV_NETMAP */ tx_buffer = &tx_ring->tx_buffer_info[i]; @@ -7173,8 +7173,13 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) 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; + /* + * Same as the txeof routine: only wakeup clients on intr. + */ + int nm_irq; + nm_irq = netmap_rx_irq(rx_ring->netdev, rx_ring->queue_index, &total_packets); + if (nm_irq != NM_IRQ_PASS) + return (nm_irq == NM_IRQ_RESCHED) ? budget : 1; #endif /* DEV_NETMAP */ while (likely(total_packets < budget)) { union e1000_adv_rx_desc *rx_desc; From 520b303fa631bf235eb81098affb49267938dbaf Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Fri, 4 Aug 2017 18:32:52 +0200 Subject: [PATCH 31/41] ixgbe: move tx ring init to support tx head wb --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 2a71eac4a9560c..dcf36a33f3c7a4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3247,6 +3247,10 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, clear_bit(__IXGBE_HANG_CHECK_ARMED, &ring->state); +#ifdef DEV_NETMAP + txdctl = ixgbe_netmap_configure_tx_ring(adapter, reg_idx, txdctl); +#endif /* DEV_NETMAP */ + /* enable queue */ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl); @@ -3261,10 +3265,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); } while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE)); if (!wait_loop) - hw_dbg(hw, "Could not enable Tx Queue %d\n", reg_idx); -#ifdef DEV_NETMAP - ixgbe_netmap_configure_tx_ring(adapter, reg_idx); -#endif /* DEV_NETMAP */ + e_err(drv, "Could not enable Tx Queue %d\n", reg_idx); } static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) From fcbf778fa9ca2f22f915a1191318cf9614caaa29 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Tue, 8 Aug 2017 11:41:54 +0200 Subject: [PATCH 32/41] ixgbevf: move tx init to support Tx head wb --- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 1212ce60010feb..1a006e1c8a5df6 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -1644,6 +1644,10 @@ static void ixgbevf_configure_tx_ring(struct ixgbevf_adapter *adapter, clear_bit(__IXGBEVF_HANG_CHECK_ARMED, &ring->state); +#ifdef DEV_NETMAP + txdctl = ixgbe_netmap_configure_tx_ring(adapter, reg_idx, txdctl); +#endif /* DEV_NETMAP */ + IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(reg_idx), txdctl); /* poll to verify queue is enabled */ @@ -1652,10 +1656,7 @@ static void ixgbevf_configure_tx_ring(struct ixgbevf_adapter *adapter, txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(reg_idx)); } while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE)); if (!wait_loop) - hw_dbg(hw, "Could not enable Tx Queue %d\n", reg_idx); -#ifdef DEV_NETMAP - ixgbe_netmap_configure_tx_ring(adapter, reg_idx); -#endif /* DEV_NETMAP */ + pr_err("Could not enable Tx Queue %d\n", reg_idx); } /** From cfcbdd402d9df4ff631ab8ec9642069a454a048e Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Thu, 2 Nov 2017 17:36:25 +0100 Subject: [PATCH 33/41] ixgbe: call an ixgbe-specific detach function --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index dcf36a33f3c7a4..7b86ce44333ac2 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -9897,7 +9897,7 @@ static void ixgbe_remove(struct pci_dev *pdev) netdev = adapter->netdev; #ifdef DEV_NETMAP - netmap_detach(netdev); + ixgbe_netmap_detach(adapter); #endif /* DEV_NETMAP */ ixgbe_dbg_adapter_exit(adapter); From 56e05596bb2f1d1fcd29c449ab70016ecde70097 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Fri, 3 Nov 2017 10:06:00 +0100 Subject: [PATCH 34/41] ixgebf: call a driver specific version of netmap_detach --- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 1a006e1c8a5df6..724ea090a55767 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -4241,12 +4241,12 @@ static void ixgbevf_remove(struct pci_dev *pdev) if (!netdev) return; + adapter = netdev_priv(netdev); + #ifdef DEV_NETMAP - netmap_detach(netdev); + ixgbe_netmap_detach(adapter); #endif /* DEV_NETMAP */ - adapter = netdev_priv(netdev); - set_bit(__IXGBEVF_REMOVING, &adapter->state); cancel_work_sync(&adapter->service_task); From fcb0ea692dd60c5a4ddfb763b59236105e6c93e1 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Fri, 1 Dec 2017 18:16:40 +0100 Subject: [PATCH 35/41] i40e: hook for setting the rx buffer size --- drivers/net/ethernet/intel/i40e/i40e_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 70bbb1d7f796fa..399baf50a15211 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2957,6 +2957,10 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) /* set the prefena field to 1 because the manual says to */ rx_ctx.prefena = 1; +#ifdef DEV_NETMAP + i40e_netmap_preconfigure_rx_ring(ring, &rx_ctx); +#endif /* DEV_NETMAP */ + /* clear the context in the HMC */ err = i40e_clear_lan_rx_queue_context(hw, pf_q); if (err) { From 90fb7a17b4e1c7d253fd44eaf7356d22ce50adc2 Mon Sep 17 00:00:00 2001 From: Vitaly Date: Wed, 7 Feb 2018 08:55:19 +0300 Subject: [PATCH 36/41] vmxnet3: add netmap support --- drivers/net/vmxnet3/vmxnet3_drv.c | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) mode change 100644 => 100755 drivers/net/vmxnet3/vmxnet3_drv.c diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c old mode 100644 new mode 100755 index ef83ae3b0a44a4..c2916baee44a97 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -308,6 +308,11 @@ static u32 get_bitfield32(const __le32 *bitfield, u32 pos, u32 size) #endif /* __BIG_ENDIAN_BITFIELD */ +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) || defined(DEV_NETMAP) +#include "if_vmxnet3_netmap.h" +#endif + + static void vmxnet3_unmap_tx_buf(struct vmxnet3_tx_buf_info *tbi, struct pci_dev *pdev) @@ -367,6 +372,14 @@ vmxnet3_tq_tx_complete(struct vmxnet3_tx_queue *tq, int completed = 0; union Vmxnet3_GenericDesc *gdesc; +#ifdef DEV_NETMAP + struct net_device *netdev = adapter->netdev; + + if (netmap_tx_irq(netdev, 0) != NM_IRQ_PASS) + return 0; +#endif + + gdesc = tq->comp_ring.base + tq->comp_ring.next2proc; while (VMXNET3_TCD_GET_GEN(&gdesc->tcd) == tq->comp_ring.gen) { completed += vmxnet3_unmap_pkt(VMXNET3_TCD_GET_TXIDX( @@ -1269,6 +1282,15 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, struct Vmxnet3_RxDesc rxCmdDesc; struct Vmxnet3_RxCompDesc rxComp; #endif + +#ifdef DEV_NETMAP + u_int total_packets = 0; + struct net_device *netdev = adapter->netdev; + + if (netmap_rx_irq(netdev, 0, &total_packets) != NM_IRQ_PASS) + return 1; +#endif /* DEV_NETMAP */ + vmxnet3_getRxComp(rcd, &rq->comp_ring.base[rq->comp_ring.next2proc].rcd, &rxComp); while (rcd->gen == rq->comp_ring.gen) { @@ -2537,6 +2559,10 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) adapter->rx_queue[0].rx_ring[0].size, adapter->rx_queue[0].rx_ring[1].size); +#ifdef DEV_NETMAP + vmxnet3_netmap_init_buffers(adapter); +#endif /* DEV_NETMAP */ + vmxnet3_tq_init_all(adapter); err = vmxnet3_rq_init_all(adapter); if (err) { @@ -3457,6 +3483,11 @@ vmxnet3_probe_device(struct pci_dev *pdev, goto err_register; } + +#ifdef DEV_NETMAP + vmxnet3_netmap_attach(adapter); +#endif /* DEV_NETMAP */ + vmxnet3_check_link(adapter, false); return 0; @@ -3514,6 +3545,10 @@ vmxnet3_remove_device(struct pci_dev *pdev) unregister_netdev(netdev); +#ifdef DEV_NETMAP + vmxnet3_netmap_detach(netdev); +#endif /* DEV_NETMAP */ + vmxnet3_free_intr_resources(adapter); vmxnet3_free_pci_resources(adapter); if (VMXNET3_VERSION_GE_3(adapter)) { From 0a84e4c674cba8e3ecd88efb4a3aeeec2cbaa7e1 Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Wed, 21 Feb 2018 19:03:05 +0100 Subject: [PATCH 37/41] e1000e: intercept jumbo RX frames --- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 211f61c9618b1f..dfba00dbcbdc75 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1537,6 +1537,10 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, unsigned int total_rx_bytes = 0, total_rx_packets = 0; struct skb_shared_info *shinfo; +#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); From edfef1ad5a6283ba3db163d9a9b2e25ec7970bc9 Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Thu, 22 Feb 2018 17:58:14 +0100 Subject: [PATCH 38/41] e1000e: keep packet-split disabled with netmap --- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index dfba00dbcbdc75..81a7da84548ffb 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3142,6 +3142,10 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) adapter->rx_ps_pages = pages; else adapter->rx_ps_pages = 0; +#ifdef DEV_NETMAP + /* Keep packet-split disabled with netmap. */ + adapter->rx_ps_pages = 0; +#endif /* DEV_NETMAP */ if (adapter->rx_ps_pages) { u32 psrctl = 0; From 3a7299cd1b01ee01a13d5e3833d2f14c7375162a Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Mon, 26 Feb 2018 19:19:30 +0100 Subject: [PATCH 39/41] e1000: intercept jumbo RX frames --- drivers/net/ethernet/intel/e1000/e1000_main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index ca5150cd1f4ed6..d35d785aabbab5 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -4186,6 +4186,15 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, bool cleaned = false; unsigned int total_rx_bytes = 0, total_rx_packets = 0; +#ifdef DEV_NETMAP + int nm_irq = netmap_rx_irq(netdev, 0, work_done); + if (nm_irq != NM_IRQ_PASS) { + if (nm_irq == NM_IRQ_RESCHED) { + *work_done = work_to_do; + } + return 1; + } +#endif /* DEV_NETMAP */ i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC(*rx_ring, i); buffer_info = &rx_ring->buffer_info[i]; From 7c9d8e84716c447a7a3500ca2d1045953db14f50 Mon Sep 17 00:00:00 2001 From: Giuseppe Lettieri Date: Thu, 17 Dec 2020 18:56:01 +0100 Subject: [PATCH 40/41] virtio: play well with xdp and napi_tx --- drivers/net/virtio_net.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index be4daabbc51b7a..4b9be7350412e1 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -810,15 +810,12 @@ static int virtnet_open(struct net_device *dev) int i; #ifdef DEV_NETMAP int ok = virtio_netmap_init_buffers(vi); - - 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++) { +#ifdef DEV_NETMAP + if (!ok) +#endif if (i < vi->curr_queue_pairs) /* Make sure we have some buffers: if oom use wq. */ if (!try_fill_recv(vi, &vi->rq[i], GFP_KERNEL)) From 48a8c71ca125ad53caa4958f5e9193825ce3c273 Mon Sep 17 00:00:00 2001 From: Firas Ashkar Date: Wed, 17 Feb 2021 11:12:33 -0500 Subject: [PATCH 41/41] stmmac: add netmap entry point functions 1. add netmap call back functions, these function are defined in a header based implementation 'netmap/LINUX/if_stmmac_netmap_linux.h', and 2. fix compiler warning when cross building the driver with: arm-buildroot-linux-gnueabihf-gcc (Buildroot 2019.02.2-g0b3ebc6ca5-dirty) 8.3.0 --- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 51 ++++++++++++++++--- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index caf069a465f234..a880c2c5c0e018 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -121,6 +121,9 @@ static void stmmac_exit_fs(struct net_device *dev); #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x)) +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) +#include +#endif /** * stmmac_verify_args - verify the driver parameters. * Description: it checks the driver parameters and set a default in case of @@ -472,7 +475,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) /* PTP v1, UDP, any kind of event packet */ config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; /* take time stamp for all event messages */ - snap_type_sel = PTP_TCR_SNAPTYPSEL_1; + snap_type_sel = 0xFFFFFFFF & PTP_TCR_SNAPTYPSEL_1; ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; @@ -504,7 +507,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; ptp_v2 = PTP_TCR_TSVER2ENA; /* take time stamp for all event messages */ - snap_type_sel = PTP_TCR_SNAPTYPSEL_1; + snap_type_sel = 0xFFFFFFFF & PTP_TCR_SNAPTYPSEL_1; ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; @@ -538,7 +541,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; ptp_v2 = PTP_TCR_TSVER2ENA; /* take time stamp for all event messages */ - snap_type_sel = PTP_TCR_SNAPTYPSEL_1; + snap_type_sel = 0xFFFFFFFF & PTP_TCR_SNAPTYPSEL_1; ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; @@ -1038,6 +1041,23 @@ static int init_dma_desc_rings(struct net_device *dev, gfp_t flags) /* RX INITIALIZATION */ pr_debug("\tSKB addresses:\nskb\t\tskb data\tdma data\n"); } + +#ifdef DEV_NETMAP + if (stmmac_netmap_rx_init(priv)) { + priv->cur_rx = 0; + priv->dirty_rx = 1; + buf_sz = bfsize; + + if (stmmac_netmap_tx_init(priv)) { + priv->dirty_tx = 0; + priv->cur_tx = 0; + netdev_reset_queue(priv->dev); + return 0; + } + } + +#endif /* DEV_NETMAP */ + for (i = 0; i < DMA_RX_SIZE; i++) { struct dma_desc *p; if (priv->extend_desc) @@ -1307,6 +1327,11 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) unsigned int bytes_compl = 0, pkts_compl = 0; unsigned int entry = priv->dirty_tx; +#ifdef DEV_NETMAP + if (netmap_tx_irq(priv->dev, 0)) + return; +#endif /* DEV_NETMAP */ + spin_lock(&priv->tx_lock); priv->xstats.tx_clean++; @@ -1745,7 +1770,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) } if (priv->hw->pcs && priv->hw->mac->pcs_ctrl_ane) - priv->hw->mac->pcs_ctrl_ane(priv->hw, 1, priv->hw->ps, 0); + priv->hw->mac->pcs_ctrl_ane((void __iomem *)priv->hw, 1, priv->hw->ps, 0); /* set TX ring length */ if (priv->hw->dma->set_tx_ring_len) @@ -2481,6 +2506,11 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) unsigned int count = 0; int coe = priv->hw->rx_csum; +#ifdef DEV_NETMAP + if (netmap_rx_irq(priv->dev, 0, &count)) + return count; +#endif /* DEV_NETMAP */ + if (netif_msg_rx_status(priv)) { void *rx_head; @@ -3380,6 +3410,10 @@ int stmmac_dvr_probe(struct device *device, } } +#ifdef DEV_NETMAP + stmmac_netmap_attach(priv); +#endif /* DEV_NETMAP */ + return 0; error_mdio_register: @@ -3424,6 +3458,11 @@ int stmmac_dvr_remove(struct device *dev) priv->hw->pcs != STMMAC_PCS_TBI && priv->hw->pcs != STMMAC_PCS_RTBI) stmmac_mdio_unregister(ndev); + +#ifdef DEV_NETMAP + netmap_detach(ndev); +#endif /* DEV_NETMAP */ + free_netdev(ndev); return 0; @@ -3621,8 +3660,8 @@ static void __exit stmmac_exit(void) #endif } -module_init(stmmac_init) -module_exit(stmmac_exit) +module_init(stmmac_init); +module_exit(stmmac_exit); MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver"); MODULE_AUTHOR("Giuseppe Cavallaro ");