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 +#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];