aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/efx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/efx.c')
-rw-r--r--drivers/net/sfc/efx.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7b2015f9e469..45c72eebb3a7 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -19,6 +19,7 @@
19#include <linux/in.h> 19#include <linux/in.h>
20#include <linux/crc32.h> 20#include <linux/crc32.h>
21#include <linux/ethtool.h> 21#include <linux/ethtool.h>
22#include <linux/topology.h>
22#include "net_driver.h" 23#include "net_driver.h"
23#include "gmii.h" 24#include "gmii.h"
24#include "ethtool.h" 25#include "ethtool.h"
@@ -832,7 +833,23 @@ static void efx_probe_interrupts(struct efx_nic *efx)
832 if (efx->interrupt_mode == EFX_INT_MODE_MSIX) { 833 if (efx->interrupt_mode == EFX_INT_MODE_MSIX) {
833 BUG_ON(!pci_find_capability(efx->pci_dev, PCI_CAP_ID_MSIX)); 834 BUG_ON(!pci_find_capability(efx->pci_dev, PCI_CAP_ID_MSIX));
834 835
835 efx->rss_queues = rss_cpus ? rss_cpus : num_online_cpus(); 836 if (rss_cpus == 0) {
837 cpumask_t core_mask;
838 int cpu;
839
840 cpus_clear(core_mask);
841 efx->rss_queues = 0;
842 for_each_online_cpu(cpu) {
843 if (!cpu_isset(cpu, core_mask)) {
844 ++efx->rss_queues;
845 cpus_or(core_mask, core_mask,
846 topology_core_siblings(cpu));
847 }
848 }
849 } else {
850 efx->rss_queues = rss_cpus;
851 }
852
836 efx->rss_queues = min(efx->rss_queues, max_channel + 1); 853 efx->rss_queues = min(efx->rss_queues, max_channel + 1);
837 efx->rss_queues = min(efx->rss_queues, EFX_MAX_CHANNELS); 854 efx->rss_queues = min(efx->rss_queues, EFX_MAX_CHANNELS);
838 855
@@ -1762,7 +1779,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
1762 1779
1763 efx->reset_pending = method; 1780 efx->reset_pending = method;
1764 1781
1765 queue_work(efx->workqueue, &efx->reset_work); 1782 queue_work(efx->reset_workqueue, &efx->reset_work);
1766} 1783}
1767 1784
1768/************************************************************************** 1785/**************************************************************************
@@ -1907,14 +1924,28 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
1907 goto fail1; 1924 goto fail1;
1908 } 1925 }
1909 1926
1927 efx->reset_workqueue = create_singlethread_workqueue("sfc_reset");
1928 if (!efx->reset_workqueue) {
1929 rc = -ENOMEM;
1930 goto fail2;
1931 }
1932
1910 return 0; 1933 return 0;
1911 1934
1935 fail2:
1936 destroy_workqueue(efx->workqueue);
1937 efx->workqueue = NULL;
1938
1912 fail1: 1939 fail1:
1913 return rc; 1940 return rc;
1914} 1941}
1915 1942
1916static void efx_fini_struct(struct efx_nic *efx) 1943static void efx_fini_struct(struct efx_nic *efx)
1917{ 1944{
1945 if (efx->reset_workqueue) {
1946 destroy_workqueue(efx->reset_workqueue);
1947 efx->reset_workqueue = NULL;
1948 }
1918 if (efx->workqueue) { 1949 if (efx->workqueue) {
1919 destroy_workqueue(efx->workqueue); 1950 destroy_workqueue(efx->workqueue);
1920 efx->workqueue = NULL; 1951 efx->workqueue = NULL;
@@ -1977,7 +2008,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
1977 * scheduled from this point because efx_stop_all() has been 2008 * scheduled from this point because efx_stop_all() has been
1978 * called, we are no longer registered with driverlink, and 2009 * called, we are no longer registered with driverlink, and
1979 * the net_device's have been removed. */ 2010 * the net_device's have been removed. */
1980 flush_workqueue(efx->workqueue); 2011 flush_workqueue(efx->reset_workqueue);
1981 2012
1982 efx_pci_remove_main(efx); 2013 efx_pci_remove_main(efx);
1983 2014
@@ -2098,7 +2129,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
2098 * scheduled since efx_stop_all() has been called, and we 2129 * scheduled since efx_stop_all() has been called, and we
2099 * have not and never have been registered with either 2130 * have not and never have been registered with either
2100 * the rtnetlink or driverlink layers. */ 2131 * the rtnetlink or driverlink layers. */
2101 cancel_work_sync(&efx->reset_work); 2132 flush_workqueue(efx->reset_workqueue);
2102 2133
2103 /* Retry if a recoverably reset event has been scheduled */ 2134 /* Retry if a recoverably reset event has been scheduled */
2104 if ((efx->reset_pending != RESET_TYPE_INVISIBLE) && 2135 if ((efx->reset_pending != RESET_TYPE_INVISIBLE) &&