sfc: Remove efx_channel::evqnum field
[pandora-kernel.git] / drivers / net / sfc / efx.c
index 7b2015f..22004a6 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/in.h>
 #include <linux/crc32.h>
 #include <linux/ethtool.h>
+#include <linux/topology.h>
 #include "net_driver.h"
 #include "gmii.h"
 #include "ethtool.h"
@@ -27,7 +28,6 @@
 #include "efx.h"
 #include "mdio_10g.h"
 #include "falcon.h"
-#include "workarounds.h"
 #include "mac.h"
 
 #define EFX_MAX_MTU (9 * 1024)
@@ -51,7 +51,7 @@ static struct workqueue_struct *refill_workqueue;
  * This sets the default for new devices.  It can be controlled later
  * using ethtool.
  */
-static int lro = 1;
+static int lro = true;
 module_param(lro, int, 0644);
 MODULE_PARM_DESC(lro, "Large receive offload acceleration");
 
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(lro, "Large receive offload acceleration");
  * This is forced to 0 for MSI interrupt mode as the interrupt vector
  * is not written
  */
-static unsigned int separate_tx_and_rx_channels = 1;
+static unsigned int separate_tx_and_rx_channels = true;
 
 /* This is the weight assigned to each of the (per-channel) virtual
  * NAPI devices.
@@ -80,7 +80,7 @@ unsigned int efx_monitor_interval = 1 * HZ;
 /* This controls whether or not the hardware monitor will trigger a
  * reset when it detects an error condition.
  */
-static unsigned int monitor_reset = 1;
+static unsigned int monitor_reset = true;
 
 /* This controls whether or not the driver will initialise devices
  * with invalid MAC addresses stored in the EEPROM or flash.  If true,
@@ -158,7 +158,7 @@ static void efx_fini_channels(struct efx_nic *efx);
  * never be concurrently called more than once on the same channel,
  * though different channels may be being processed concurrently.
  */
-static inline int efx_process_channel(struct efx_channel *channel, int rx_quota)
+static int efx_process_channel(struct efx_channel *channel, int rx_quota)
 {
        int rxdmaqs;
        struct efx_rx_queue *rx_queue;
@@ -202,7 +202,7 @@ static inline void efx_channel_processed(struct efx_channel *channel)
        /* The interrupt handler for this channel may set work_pending
         * as soon as we acknowledge the events we've seen.  Make sure
         * it's cleared before then. */
-       channel->work_pending = 0;
+       channel->work_pending = false;
        smp_wmb();
 
        falcon_eventq_read_ack(channel);
@@ -259,7 +259,7 @@ void efx_process_channel_now(struct efx_channel *channel)
        falcon_disable_interrupts(efx);
        if (efx->legacy_irq)
                synchronize_irq(efx->legacy_irq);
-       if (channel->has_interrupt && channel->irq)
+       if (channel->irq)
                synchronize_irq(channel->irq);
 
        /* Wait for any NAPI processing to complete */
@@ -431,8 +431,8 @@ static void efx_start_channel(struct efx_channel *channel)
        /* The interrupt handler for this channel may set work_pending
         * as soon as we enable it.  Make sure it's cleared before
         * then.  Similarly, make sure it sees the enabled flag set. */
-       channel->work_pending = 0;
-       channel->enabled = 1;
+       channel->work_pending = false;
+       channel->enabled = true;
        smp_wmb();
 
        napi_enable(&channel->napi_str);
@@ -455,7 +455,7 @@ static void efx_stop_channel(struct efx_channel *channel)
 
        EFX_LOG(channel->efx, "stop chan %d\n", channel->channel);
 
-       channel->enabled = 0;
+       channel->enabled = false;
        napi_disable(&channel->napi_str);
 
        /* Ensure that any worker threads have exited or will be no-ops */
@@ -525,8 +525,6 @@ void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue, int delay)
  */
 static void efx_link_status_changed(struct efx_nic *efx)
 {
-       int carrier_ok;
-
        /* SFC Bug 5356: A net_dev notifier is registered, so we must ensure
         * that no events are triggered between unregister_netdev() and the
         * driver unloading. A more general condition is that NETDEV_CHANGE
@@ -534,8 +532,7 @@ static void efx_link_status_changed(struct efx_nic *efx)
        if (!netif_running(efx->net_dev))
                return;
 
-       carrier_ok = netif_carrier_ok(efx->net_dev) ? 1 : 0;
-       if (efx->link_up != carrier_ok) {
+       if (efx->link_up != netif_carrier_ok(efx->net_dev)) {
                efx->n_link_state_changes++;
 
                if (efx->link_up)
@@ -660,7 +657,7 @@ static int efx_init_port(struct efx_nic *efx)
        if (rc)
                return rc;
 
-       efx->port_initialized = 1;
+       efx->port_initialized = true;
 
        /* Reconfigure port to program MAC registers */
        falcon_reconfigure_xmac(efx);
@@ -677,7 +674,7 @@ static void efx_start_port(struct efx_nic *efx)
        BUG_ON(efx->port_enabled);
 
        mutex_lock(&efx->mac_lock);
-       efx->port_enabled = 1;
+       efx->port_enabled = true;
        __efx_reconfigure_port(efx);
        mutex_unlock(&efx->mac_lock);
 }
@@ -691,7 +688,7 @@ static void efx_stop_port(struct efx_nic *efx)
        EFX_LOG(efx, "stop port\n");
 
        mutex_lock(&efx->mac_lock);
-       efx->port_enabled = 0;
+       efx->port_enabled = false;
        mutex_unlock(&efx->mac_lock);
 
        /* Serialise against efx_set_multicast_list() */
@@ -709,9 +706,9 @@ static void efx_fini_port(struct efx_nic *efx)
                return;
 
        falcon_fini_xmac(efx);
-       efx->port_initialized = 0;
+       efx->port_initialized = false;
 
-       efx->link_up = 0;
+       efx->link_up = false;
        efx_link_status_changed(efx);
 }
 
@@ -822,37 +819,61 @@ static void efx_fini_io(struct efx_nic *efx)
        pci_disable_device(efx->pci_dev);
 }
 
-/* Probe the number and type of interrupts we are able to obtain. */
+/* Get number of RX queues wanted.  Return number of online CPU
+ * packages in the expectation that an IRQ balancer will spread
+ * interrupts across them. */
+static int efx_wanted_rx_queues(void)
+{
+       cpumask_t core_mask;
+       int count;
+       int cpu;
+
+       cpus_clear(core_mask);
+       count = 0;
+       for_each_online_cpu(cpu) {
+               if (!cpu_isset(cpu, core_mask)) {
+                       ++count;
+                       cpus_or(core_mask, core_mask,
+                               topology_core_siblings(cpu));
+               }
+       }
+
+       return count;
+}
+
+/* Probe the number and type of interrupts we are able to obtain, and
+ * the resulting numbers of channels and RX queues.
+ */
 static void efx_probe_interrupts(struct efx_nic *efx)
 {
-       int max_channel = efx->type->phys_addr_channels - 1;
-       struct msix_entry xentries[EFX_MAX_CHANNELS];
+       int max_channels =
+               min_t(int, efx->type->phys_addr_channels, EFX_MAX_CHANNELS);
        int rc, i;
 
        if (efx->interrupt_mode == EFX_INT_MODE_MSIX) {
-               BUG_ON(!pci_find_capability(efx->pci_dev, PCI_CAP_ID_MSIX));
+               struct msix_entry xentries[EFX_MAX_CHANNELS];
+               int wanted_ints;
 
-               efx->rss_queues = rss_cpus ? rss_cpus : num_online_cpus();
-               efx->rss_queues = min(efx->rss_queues, max_channel + 1);
-               efx->rss_queues = min(efx->rss_queues, EFX_MAX_CHANNELS);
+               /* We want one RX queue and interrupt per CPU package
+                * (or as specified by the rss_cpus module parameter).
+                * We will need one channel per interrupt.
+                */
+               wanted_ints = rss_cpus ? rss_cpus : efx_wanted_rx_queues();
+               efx->n_rx_queues = min(wanted_ints, max_channels);
 
-               /* Request maximum number of MSI interrupts, and fill out
-                * the channel interrupt information the allowed allocation */
-               for (i = 0; i < efx->rss_queues; i++)
+               for (i = 0; i < efx->n_rx_queues; i++)
                        xentries[i].entry = i;
-               rc = pci_enable_msix(efx->pci_dev, xentries, efx->rss_queues);
+               rc = pci_enable_msix(efx->pci_dev, xentries, efx->n_rx_queues);
                if (rc > 0) {
-                       EFX_BUG_ON_PARANOID(rc >= efx->rss_queues);
-                       efx->rss_queues = rc;
+                       EFX_BUG_ON_PARANOID(rc >= efx->n_rx_queues);
+                       efx->n_rx_queues = rc;
                        rc = pci_enable_msix(efx->pci_dev, xentries,
-                                            efx->rss_queues);
+                                            efx->n_rx_queues);
                }
 
                if (rc == 0) {
-                       for (i = 0; i < efx->rss_queues; i++) {
-                               efx->channel[i].has_interrupt = 1;
+                       for (i = 0; i < efx->n_rx_queues; i++)
                                efx->channel[i].irq = xentries[i].vector;
-                       }
                } else {
                        /* Fall back to single channel MSI */
                        efx->interrupt_mode = EFX_INT_MODE_MSI;
@@ -862,11 +883,10 @@ static void efx_probe_interrupts(struct efx_nic *efx)
 
        /* Try single interrupt MSI */
        if (efx->interrupt_mode == EFX_INT_MODE_MSI) {
-               efx->rss_queues = 1;
+               efx->n_rx_queues = 1;
                rc = pci_enable_msi(efx->pci_dev);
                if (rc == 0) {
                        efx->channel[0].irq = efx->pci_dev->irq;
-                       efx->channel[0].has_interrupt = 1;
                } else {
                        EFX_ERR(efx, "could not enable MSI\n");
                        efx->interrupt_mode = EFX_INT_MODE_LEGACY;
@@ -875,10 +895,7 @@ static void efx_probe_interrupts(struct efx_nic *efx)
 
        /* Assume legacy interrupts */
        if (efx->interrupt_mode == EFX_INT_MODE_LEGACY) {
-               efx->rss_queues = 1;
-               /* Every channel is interruptible */
-               for (i = 0; i < EFX_MAX_CHANNELS; i++)
-                       efx->channel[i].has_interrupt = 1;
+               efx->n_rx_queues = 1;
                efx->legacy_irq = efx->pci_dev->irq;
        }
 }
@@ -888,7 +905,7 @@ static void efx_remove_interrupts(struct efx_nic *efx)
        struct efx_channel *channel;
 
        /* Remove MSI/MSI-X interrupts */
-       efx_for_each_channel_with_interrupt(channel, efx)
+       efx_for_each_channel(channel, efx)
                channel->irq = 0;
        pci_disable_msi(efx->pci_dev);
        pci_disable_msix(efx->pci_dev);
@@ -897,45 +914,22 @@ static void efx_remove_interrupts(struct efx_nic *efx)
        efx->legacy_irq = 0;
 }
 
-/* Select number of used resources
- * Should be called after probe_interrupts()
- */
-static void efx_select_used(struct efx_nic *efx)
+static void efx_set_channels(struct efx_nic *efx)
 {
        struct efx_tx_queue *tx_queue;
        struct efx_rx_queue *rx_queue;
-       int i;
-
-       /* TX queues.  One per port per channel with TX capability
-        * (more than one per port won't work on Linux, due to out
-        *  of order issues... but will be fine on Solaris)
-        */
-       tx_queue = &efx->tx_queue[0];
-
-       /* Perform this for each channel with TX capabilities.
-        * At the moment, we only support a single TX queue
-        */
-       tx_queue->used = 1;
-       if ((!EFX_INT_MODE_USE_MSI(efx)) && separate_tx_and_rx_channels)
-               tx_queue->channel = &efx->channel[1];
-       else
-               tx_queue->channel = &efx->channel[0];
-       tx_queue->channel->used_flags |= EFX_USED_BY_TX;
-       tx_queue++;
 
-       /* RX queues.  Each has a dedicated channel. */
-       for (i = 0; i < EFX_MAX_RX_QUEUES; i++) {
-               rx_queue = &efx->rx_queue[i];
+       efx_for_each_tx_queue(tx_queue, efx) {
+               if (!EFX_INT_MODE_USE_MSI(efx) && separate_tx_and_rx_channels)
+                       tx_queue->channel = &efx->channel[1];
+               else
+                       tx_queue->channel = &efx->channel[0];
+               tx_queue->channel->used_flags |= EFX_USED_BY_TX;
+       }
 
-               if (i < efx->rss_queues) {
-                       rx_queue->used = 1;
-                       /* If we allow multiple RX queues per channel
-                        * we need to decide that here
-                        */
-                       rx_queue->channel = &efx->channel[rx_queue->queue];
-                       rx_queue->channel->used_flags |= EFX_USED_BY_RX;
-                       rx_queue++;
-               }
+       efx_for_each_rx_queue(rx_queue, efx) {
+               rx_queue->channel = &efx->channel[rx_queue->queue];
+               rx_queue->channel->used_flags |= EFX_USED_BY_RX;
        }
 }
 
@@ -954,8 +948,7 @@ static int efx_probe_nic(struct efx_nic *efx)
         * in MSI-X interrupts. */
        efx_probe_interrupts(efx);
 
-       /* Determine number of RX queues and TX queues */
-       efx_select_used(efx);
+       efx_set_channels(efx);
 
        /* Initialise the interrupt moderation settings */
        efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec);
@@ -1092,7 +1085,7 @@ static void efx_stop_all(struct efx_nic *efx)
        falcon_disable_interrupts(efx);
        if (efx->legacy_irq)
                synchronize_irq(efx->legacy_irq);
-       efx_for_each_channel_with_interrupt(channel, efx) {
+       efx_for_each_channel(channel, efx) {
                if (channel->irq)
                        synchronize_irq(channel->irq);
        }
@@ -1232,7 +1225,7 @@ static void efx_monitor(struct work_struct *data)
  */
 static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
 
        EFX_ASSERT_RESET_SERIALISED(efx);
 
@@ -1286,10 +1279,10 @@ static void efx_fini_napi(struct efx_nic *efx)
  */
 static void efx_netpoll(struct net_device *net_dev)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
        struct efx_channel *channel;
 
-       efx_for_each_channel_with_interrupt(channel, efx)
+       efx_for_each_channel(channel, efx)
                efx_schedule_channel(channel);
 }
 
@@ -1304,7 +1297,7 @@ static void efx_netpoll(struct net_device *net_dev)
 /* Context: process, rtnl_lock() held. */
 static int efx_net_open(struct net_device *net_dev)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
        EFX_ASSERT_RESET_SERIALISED(efx);
 
        EFX_LOG(efx, "opening device %s on CPU %d\n", net_dev->name,
@@ -1320,7 +1313,7 @@ static int efx_net_open(struct net_device *net_dev)
  */
 static int efx_net_stop(struct net_device *net_dev)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
        int rc;
 
        EFX_LOG(efx, "closing %s on CPU %d\n", net_dev->name,
@@ -1339,7 +1332,7 @@ static int efx_net_stop(struct net_device *net_dev)
 /* Context: process, dev_base_lock or RTNL held, non-blocking. */
 static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
        struct efx_mac_stats *mac_stats = &efx->mac_stats;
        struct net_device_stats *stats = &net_dev->stats;
 
@@ -1386,7 +1379,7 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
 /* Context: netif_tx_lock held, BHs disabled. */
 static void efx_watchdog(struct net_device *net_dev)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
 
        EFX_ERR(efx, "TX stuck with stop_count=%d port_enabled=%d: %s\n",
                atomic_read(&efx->netif_stop_count), efx->port_enabled,
@@ -1400,7 +1393,7 @@ static void efx_watchdog(struct net_device *net_dev)
 /* Context: process, rtnl_lock() held. */
 static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
        int rc = 0;
 
        EFX_ASSERT_RESET_SERIALISED(efx);
@@ -1428,7 +1421,7 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
 
 static int efx_set_mac_address(struct net_device *net_dev, void *data)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
        struct sockaddr *addr = data;
        char *new_addr = addr->sa_data;
 
@@ -1452,16 +1445,16 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
 /* Context: netif_tx_lock held, BHs disabled. */
 static void efx_set_multicast_list(struct net_device *net_dev)
 {
-       struct efx_nic *efx = net_dev->priv;
+       struct efx_nic *efx = netdev_priv(net_dev);
        struct dev_mc_list *mc_list = net_dev->mc_list;
        union efx_multicast_hash *mc_hash = &efx->multicast_hash;
-       int promiscuous;
+       bool promiscuous;
        u32 crc;
        int bit;
        int i;
 
        /* Set per-MAC promiscuity flag and reconfigure MAC if necessary */
-       promiscuous = (net_dev->flags & IFF_PROMISC) ? 1 : 0;
+       promiscuous = !!(net_dev->flags & IFF_PROMISC);
        if (efx->promiscuous != promiscuous) {
                efx->promiscuous = promiscuous;
                /* Close the window between efx_stop_port() and efx_flush_all()
@@ -1493,7 +1486,7 @@ static int efx_netdev_event(struct notifier_block *this,
        struct net_device *net_dev = ptr;
 
        if (net_dev->open == efx_net_open && event == NETDEV_CHANGENAME) {
-               struct efx_nic *efx = net_dev->priv;
+               struct efx_nic *efx = netdev_priv(net_dev);
 
                strcpy(efx->name, net_dev->name);
        }
@@ -1551,7 +1544,7 @@ static void efx_unregister_netdev(struct efx_nic *efx)
        if (!efx->net_dev)
                return;
 
-       BUG_ON(efx->net_dev->priv != efx);
+       BUG_ON(netdev_priv(efx->net_dev) != efx);
 
        /* Free up any skbs still remaining. This has to happen before
         * we try to unregister the netdev as running their destructors
@@ -1762,7 +1755,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
 
        efx->reset_pending = method;
 
-       queue_work(efx->workqueue, &efx->reset_work);
+       queue_work(efx->reset_workqueue, &efx->reset_work);
 }
 
 /**************************************************************************
@@ -1794,7 +1787,7 @@ int efx_port_dummy_op_int(struct efx_nic *efx)
        return 0;
 }
 void efx_port_dummy_op_void(struct efx_nic *efx) {}
-void efx_port_dummy_op_blink(struct efx_nic *efx, int blink) {}
+void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {}
 
 static struct efx_phy_operations efx_dummy_phy_operations = {
        .init            = efx_port_dummy_op_int,
@@ -1848,7 +1841,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
        efx->board_info = efx_dummy_board_info;
 
        efx->net_dev = net_dev;
-       efx->rx_checksum_enabled = 1;
+       efx->rx_checksum_enabled = true;
        spin_lock_init(&efx->netif_stop_lock);
        spin_lock_init(&efx->stats_lock);
        mutex_init(&efx->mac_lock);
@@ -1861,10 +1854,9 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
                channel = &efx->channel[i];
                channel->efx = efx;
                channel->channel = i;
-               channel->evqnum = i;
-               channel->work_pending = 0;
+               channel->work_pending = false;
        }
-       for (i = 0; i < EFX_MAX_TX_QUEUES; i++) {
+       for (i = 0; i < EFX_TX_QUEUE_COUNT; i++) {
                tx_queue = &efx->tx_queue[i];
                tx_queue->efx = efx;
                tx_queue->queue = i;
@@ -1907,14 +1899,28 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
                goto fail1;
        }
 
+       efx->reset_workqueue = create_singlethread_workqueue("sfc_reset");
+       if (!efx->reset_workqueue) {
+               rc = -ENOMEM;
+               goto fail2;
+       }
+
        return 0;
 
+ fail2:
+       destroy_workqueue(efx->workqueue);
+       efx->workqueue = NULL;
+
  fail1:
        return rc;
 }
 
 static void efx_fini_struct(struct efx_nic *efx)
 {
+       if (efx->reset_workqueue) {
+               destroy_workqueue(efx->reset_workqueue);
+               efx->reset_workqueue = NULL;
+       }
        if (efx->workqueue) {
                destroy_workqueue(efx->workqueue);
                efx->workqueue = NULL;
@@ -1977,7 +1983,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
         * scheduled from this point because efx_stop_all() has been
         * called, we are no longer registered with driverlink, and
         * the net_device's have been removed. */
-       flush_workqueue(efx->workqueue);
+       flush_workqueue(efx->reset_workqueue);
 
        efx_pci_remove_main(efx);
 
@@ -2074,7 +2080,10 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
                              NETIF_F_HIGHDMA | NETIF_F_TSO);
        if (lro)
                net_dev->features |= NETIF_F_LRO;
-       efx = net_dev->priv;
+       /* Mask for features that also apply to VLAN devices */
+       net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
+                                  NETIF_F_HIGHDMA);
+       efx = netdev_priv(net_dev);
        pci_set_drvdata(pci_dev, efx);
        rc = efx_init_struct(efx, type, pci_dev, net_dev);
        if (rc)
@@ -2098,7 +2107,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
                 * scheduled since efx_stop_all() has been called, and we
                 * have not and never have been registered with either
                 * the rtnetlink or driverlink layers. */
-               cancel_work_sync(&efx->reset_work);
+               flush_workqueue(efx->reset_workqueue);
 
                /* Retry if a recoverably reset event has been scheduled */
                if ((efx->reset_pending != RESET_TYPE_INVISIBLE) &&