diff options
author | Sony Chacko <sony.chacko@qlogic.com> | 2012-12-31 22:20:21 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-02 05:43:26 -0500 |
commit | 13159183ec7afe03ed48d3b083b255278f429b5a (patch) | |
tree | d3401157a11b2f96f8630c4c70663bd51591b051 /drivers/net | |
parent | 4be41e92f7c613d6c08686374ad0fdeaaa2a7280 (diff) |
qlcnic: 83xx base driver
Enable base 83xx adapter driver.
Common driver interface routines like probe,
interface up/down routines, irq and resource
allocation routines are modified to add support for 83xx
adapter.
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Sritej Velaga <sritej.velaga@qlogic.com>
Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 503 |
3 files changed, 330 insertions, 175 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 31cf1b1cdf6c..dd9be4f008aa 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -1377,6 +1377,7 @@ void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter); | |||
1377 | int qlcnic_dump_fw(struct qlcnic_adapter *); | 1377 | int qlcnic_dump_fw(struct qlcnic_adapter *); |
1378 | 1378 | ||
1379 | /* Functions from qlcnic_init.c */ | 1379 | /* Functions from qlcnic_init.c */ |
1380 | void qlcnic_schedule_work(struct qlcnic_adapter *, work_func_t, int); | ||
1380 | int qlcnic_load_firmware(struct qlcnic_adapter *adapter); | 1381 | int qlcnic_load_firmware(struct qlcnic_adapter *adapter); |
1381 | int qlcnic_need_fw_reset(struct qlcnic_adapter *adapter); | 1382 | int qlcnic_need_fw_reset(struct qlcnic_adapter *adapter); |
1382 | void qlcnic_request_firmware(struct qlcnic_adapter *adapter); | 1383 | void qlcnic_request_firmware(struct qlcnic_adapter *adapter); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index e2cfc86f925a..51775e4e3fd9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | |||
@@ -209,7 +209,6 @@ int qlcnic_83xx_napi_add(struct qlcnic_adapter *, struct net_device *); | |||
209 | void qlcnic_83xx_napi_del(struct qlcnic_adapter *); | 209 | void qlcnic_83xx_napi_del(struct qlcnic_adapter *); |
210 | void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); | 210 | void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); |
211 | void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); | 211 | void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); |
212 | |||
213 | void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); | 212 | void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); |
214 | int qlcnic_ind_rd(struct qlcnic_adapter *, u32); | 213 | int qlcnic_ind_rd(struct qlcnic_adapter *, u32); |
215 | void qlcnic_83xx_get_stats(struct qlcnic_adapter *, | 214 | void qlcnic_83xx_get_stats(struct qlcnic_adapter *, |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index ae289abfeb2f..2e69ff8d4021 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -2,10 +2,15 @@ | |||
2 | * QLogic qlcnic NIC Driver | 2 | * QLogic qlcnic NIC Driver |
3 | * Copyright (c) 2009-2010 QLogic Corporation | 3 | * Copyright (c) 2009-2010 QLogic Corporation |
4 | * | 4 | * |
5 | * PCI searching functions pci_get_domain_bus_and_slot & pci_channel_offline | ||
6 | * Copyright (C) 1993 -- 1997 Drew Eckhardt, Frederic Potter, | ||
7 | * David Mosberger-Tang | ||
8 | * Copyright (C) 1997 -- 2000 Martin Mares <mj@ucw.cz> | ||
9 | * Copyright (C) 2003 -- 2004 Greg Kroah-Hartman <greg@kroah.com>. | ||
10 | * | ||
5 | * See LICENSE.qlcnic for copyright and licensing details. | 11 | * See LICENSE.qlcnic for copyright and licensing details. |
6 | */ | 12 | */ |
7 | 13 | ||
8 | #include <linux/slab.h> | ||
9 | #include <linux/vmalloc.h> | 14 | #include <linux/vmalloc.h> |
10 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
11 | 16 | ||
@@ -14,10 +19,10 @@ | |||
14 | 19 | ||
15 | #include <linux/swab.h> | 20 | #include <linux/swab.h> |
16 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
22 | #include <linux/if_vlan.h> | ||
17 | #include <net/ip.h> | 23 | #include <net/ip.h> |
18 | #include <linux/ipv6.h> | 24 | #include <linux/ipv6.h> |
19 | #include <linux/inetdevice.h> | 25 | #include <linux/inetdevice.h> |
20 | #include <linux/sysfs.h> | ||
21 | #include <linux/aer.h> | 26 | #include <linux/aer.h> |
22 | #include <linux/log2.h> | 27 | #include <linux/log2.h> |
23 | 28 | ||
@@ -30,7 +35,6 @@ char qlcnic_driver_name[] = "qlcnic"; | |||
30 | static const char qlcnic_driver_string[] = "QLogic 1/10 GbE " | 35 | static const char qlcnic_driver_string[] = "QLogic 1/10 GbE " |
31 | "Converged/Intelligent Ethernet Driver v" QLCNIC_LINUX_VERSIONID; | 36 | "Converged/Intelligent Ethernet Driver v" QLCNIC_LINUX_VERSIONID; |
32 | 37 | ||
33 | static struct workqueue_struct *qlcnic_wq; | ||
34 | static int qlcnic_mac_learn; | 38 | static int qlcnic_mac_learn; |
35 | module_param(qlcnic_mac_learn, int, 0444); | 39 | module_param(qlcnic_mac_learn, int, 0444); |
36 | MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=disabled, 1=enabled)"); | 40 | MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=disabled, 1=enabled)"); |
@@ -63,9 +67,6 @@ static void qlcnic_tx_timeout(struct net_device *netdev); | |||
63 | static void qlcnic_attach_work(struct work_struct *work); | 67 | static void qlcnic_attach_work(struct work_struct *work); |
64 | static void qlcnic_fwinit_work(struct work_struct *work); | 68 | static void qlcnic_fwinit_work(struct work_struct *work); |
65 | static void qlcnic_fw_poll_work(struct work_struct *work); | 69 | static void qlcnic_fw_poll_work(struct work_struct *work); |
66 | static void qlcnic_schedule_work(struct qlcnic_adapter *adapter, | ||
67 | work_func_t func, int delay); | ||
68 | static void qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter); | ||
69 | #ifdef CONFIG_NET_POLL_CONTROLLER | 70 | #ifdef CONFIG_NET_POLL_CONTROLLER |
70 | static void qlcnic_poll_controller(struct net_device *netdev); | 71 | static void qlcnic_poll_controller(struct net_device *netdev); |
71 | #endif | 72 | #endif |
@@ -78,6 +79,7 @@ static irqreturn_t qlcnic_tmp_intr(int irq, void *data); | |||
78 | static irqreturn_t qlcnic_intr(int irq, void *data); | 79 | static irqreturn_t qlcnic_intr(int irq, void *data); |
79 | static irqreturn_t qlcnic_msi_intr(int irq, void *data); | 80 | static irqreturn_t qlcnic_msi_intr(int irq, void *data); |
80 | static irqreturn_t qlcnic_msix_intr(int irq, void *data); | 81 | static irqreturn_t qlcnic_msix_intr(int irq, void *data); |
82 | static irqreturn_t qlcnic_msix_tx_intr(int irq, void *data); | ||
81 | 83 | ||
82 | static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); | 84 | static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); |
83 | static void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long); | 85 | static void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long); |
@@ -94,15 +96,24 @@ static int qlcnic_vlan_rx_del(struct net_device *, u16); | |||
94 | #define QLCNIC_IS_TSO_CAPABLE(adapter) \ | 96 | #define QLCNIC_IS_TSO_CAPABLE(adapter) \ |
95 | ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) | 97 | ((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) |
96 | 98 | ||
99 | static u32 qlcnic_vlan_tx_check(struct qlcnic_adapter *adapter) | ||
100 | { | ||
101 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
102 | |||
103 | if (adapter->pdev->device == PCI_DEVICE_ID_QLOGIC_QLE824X) | ||
104 | return ahw->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX; | ||
105 | else | ||
106 | return 1; | ||
107 | } | ||
108 | |||
97 | /* PCI Device ID Table */ | 109 | /* PCI Device ID Table */ |
98 | #define ENTRY(device) \ | 110 | #define ENTRY(device) \ |
99 | {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ | 111 | {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ |
100 | .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} | 112 | .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} |
101 | 113 | ||
102 | #define PCI_DEVICE_ID_QLOGIC_QLE824X 0x8020 | ||
103 | |||
104 | static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = { | 114 | static DEFINE_PCI_DEVICE_TABLE(qlcnic_pci_tbl) = { |
105 | ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X), | 115 | ENTRY(PCI_DEVICE_ID_QLOGIC_QLE824X), |
116 | ENTRY(PCI_DEVICE_ID_QLOGIC_QLE834X), | ||
106 | {0,} | 117 | {0,} |
107 | }; | 118 | }; |
108 | 119 | ||
@@ -191,30 +202,6 @@ void qlcnic_free_sds_rings(struct qlcnic_recv_context *recv_ctx) | |||
191 | recv_ctx->sds_rings = NULL; | 202 | recv_ctx->sds_rings = NULL; |
192 | } | 203 | } |
193 | 204 | ||
194 | static void qlcnic_set_msix_bit(struct pci_dev *pdev, int enable) | ||
195 | { | ||
196 | u32 control; | ||
197 | int pos; | ||
198 | |||
199 | pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); | ||
200 | if (pos) { | ||
201 | pci_read_config_dword(pdev, pos, &control); | ||
202 | if (enable) | ||
203 | control |= PCI_MSIX_FLAGS_ENABLE; | ||
204 | else | ||
205 | control = 0; | ||
206 | pci_write_config_dword(pdev, pos, control); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | static void qlcnic_init_msix_entries(struct qlcnic_adapter *adapter, int count) | ||
211 | { | ||
212 | int i; | ||
213 | |||
214 | for (i = 0; i < count; i++) | ||
215 | adapter->msix_entries[i].entry = i; | ||
216 | } | ||
217 | |||
218 | static int | 205 | static int |
219 | qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) | 206 | qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) |
220 | { | 207 | { |
@@ -247,7 +234,7 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) | |||
247 | return -EOPNOTSUPP; | 234 | return -EOPNOTSUPP; |
248 | 235 | ||
249 | if (!is_valid_ether_addr(addr->sa_data)) | 236 | if (!is_valid_ether_addr(addr->sa_data)) |
250 | return -EADDRNOTAVAIL; | 237 | return -EINVAL; |
251 | 238 | ||
252 | if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { | 239 | if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { |
253 | netif_device_detach(netdev); | 240 | netif_device_detach(netdev); |
@@ -351,31 +338,66 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = { | |||
351 | int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) | 338 | int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) |
352 | { | 339 | { |
353 | struct pci_dev *pdev = adapter->pdev; | 340 | struct pci_dev *pdev = adapter->pdev; |
354 | int err = -1; | 341 | int err = -1, i; |
342 | int max_tx_rings; | ||
343 | |||
344 | if (!adapter->msix_entries) { | ||
345 | adapter->msix_entries = kcalloc(num_msix, | ||
346 | sizeof(struct msix_entry), | ||
347 | GFP_KERNEL); | ||
348 | if (!adapter->msix_entries) { | ||
349 | dev_err(&pdev->dev, "failed allocating msix_entries\n"); | ||
350 | return -ENOMEM; | ||
351 | } | ||
352 | } | ||
355 | 353 | ||
356 | adapter->max_sds_rings = 1; | 354 | adapter->max_sds_rings = 1; |
357 | adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED); | 355 | adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED); |
358 | qlcnic_set_msix_bit(pdev, 0); | ||
359 | 356 | ||
360 | if (adapter->ahw->msix_supported) { | 357 | if (adapter->ahw->msix_supported) { |
361 | enable_msix: | 358 | enable_msix: |
362 | qlcnic_init_msix_entries(adapter, num_msix); | 359 | for (i = 0; i < num_msix; i++) |
360 | adapter->msix_entries[i].entry = i; | ||
363 | err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); | 361 | err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); |
364 | if (err == 0) { | 362 | if (err == 0) { |
365 | adapter->flags |= QLCNIC_MSIX_ENABLED; | 363 | adapter->flags |= QLCNIC_MSIX_ENABLED; |
366 | qlcnic_set_msix_bit(pdev, 1); | 364 | if (qlcnic_83xx_check(adapter)) { |
367 | 365 | adapter->ahw->num_msix = num_msix; | |
368 | adapter->max_sds_rings = num_msix; | 366 | /* subtract mail box and tx ring vectors */ |
369 | 367 | max_tx_rings = adapter->max_drv_tx_rings; | |
368 | adapter->max_sds_rings = num_msix - | ||
369 | max_tx_rings - 1; | ||
370 | } else { | ||
371 | adapter->max_sds_rings = num_msix; | ||
372 | } | ||
370 | dev_info(&pdev->dev, "using msi-x interrupts\n"); | 373 | dev_info(&pdev->dev, "using msi-x interrupts\n"); |
371 | return err; | 374 | return err; |
372 | } | 375 | } else if (err > 0) { |
373 | if (err > 0) { | 376 | dev_info(&pdev->dev, |
374 | num_msix = rounddown_pow_of_two(err); | 377 | "Unable to allocate %d MSI-X interrupt vectors\n", |
375 | if (num_msix) | 378 | num_msix); |
379 | if (qlcnic_83xx_check(adapter)) { | ||
380 | if (err < QLC_83XX_MINIMUM_VECTOR) | ||
381 | return err; | ||
382 | err -= (adapter->max_drv_tx_rings + 1); | ||
383 | num_msix = rounddown_pow_of_two(err); | ||
384 | num_msix += (adapter->max_drv_tx_rings + 1); | ||
385 | } else { | ||
386 | num_msix = rounddown_pow_of_two(err); | ||
387 | } | ||
388 | |||
389 | if (num_msix) { | ||
390 | dev_info(&pdev->dev, | ||
391 | "Trying %d MSI-X interrupt vectors\n", | ||
392 | num_msix); | ||
376 | goto enable_msix; | 393 | goto enable_msix; |
394 | } | ||
395 | } else { | ||
396 | dev_info(&pdev->dev, "Failed to get %d vectors\n", | ||
397 | num_msix); | ||
377 | } | 398 | } |
378 | } | 399 | } |
400 | |||
379 | return err; | 401 | return err; |
380 | } | 402 | } |
381 | 403 | ||
@@ -428,6 +450,7 @@ int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr) | |||
428 | qlcnic_enable_msi_legacy(adapter); | 450 | qlcnic_enable_msi_legacy(adapter); |
429 | return 0; | 451 | return 0; |
430 | } | 452 | } |
453 | |||
431 | static void | 454 | static void |
432 | qlcnic_teardown_intr(struct qlcnic_adapter *adapter) | 455 | qlcnic_teardown_intr(struct qlcnic_adapter *adapter) |
433 | { | 456 | { |
@@ -435,6 +458,14 @@ qlcnic_teardown_intr(struct qlcnic_adapter *adapter) | |||
435 | pci_disable_msix(adapter->pdev); | 458 | pci_disable_msix(adapter->pdev); |
436 | if (adapter->flags & QLCNIC_MSI_ENABLED) | 459 | if (adapter->flags & QLCNIC_MSI_ENABLED) |
437 | pci_disable_msi(adapter->pdev); | 460 | pci_disable_msi(adapter->pdev); |
461 | |||
462 | kfree(adapter->msix_entries); | ||
463 | adapter->msix_entries = NULL; | ||
464 | |||
465 | if (adapter->ahw->intr_tbl) { | ||
466 | vfree(adapter->ahw->intr_tbl); | ||
467 | adapter->ahw->intr_tbl = NULL; | ||
468 | } | ||
438 | } | 469 | } |
439 | 470 | ||
440 | static void | 471 | static void |
@@ -524,8 +555,11 @@ static int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) | |||
524 | j++; | 555 | j++; |
525 | } | 556 | } |
526 | 557 | ||
527 | for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) | 558 | for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) { |
528 | adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE; | 559 | adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE; |
560 | if (qlcnic_83xx_check(adapter)) | ||
561 | qlcnic_enable_eswitch(adapter, i, 1); | ||
562 | } | ||
529 | 563 | ||
530 | kfree(pci_info); | 564 | kfree(pci_info); |
531 | return 0; | 565 | return 0; |
@@ -574,29 +608,20 @@ err_lock: | |||
574 | return ret; | 608 | return ret; |
575 | } | 609 | } |
576 | 610 | ||
577 | static void | 611 | static void qlcnic_check_vf(struct qlcnic_adapter *adapter, |
578 | qlcnic_check_vf(struct qlcnic_adapter *adapter) | 612 | const struct pci_device_id *ent) |
579 | { | 613 | { |
580 | void __iomem *msix_base_addr; | ||
581 | void __iomem *priv_op; | ||
582 | u32 func; | ||
583 | u32 msix_base; | ||
584 | u32 op_mode, priv_level; | 614 | u32 op_mode, priv_level; |
585 | 615 | ||
586 | /* Determine FW API version */ | 616 | /* Determine FW API version */ |
587 | adapter->ahw->fw_hal_version = readl(adapter->ahw->pci_base0 + | 617 | adapter->ahw->fw_hal_version = QLC_SHARED_REG_RD32(adapter, |
588 | QLCNIC_FW_API); | 618 | QLCNIC_FW_API); |
589 | 619 | ||
590 | /* Find PCI function number */ | 620 | /* Find PCI function number */ |
591 | pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func); | 621 | qlcnic_get_func_no(adapter); |
592 | msix_base_addr = adapter->ahw->pci_base0 + QLCNIC_MSIX_BASE; | ||
593 | msix_base = readl(msix_base_addr); | ||
594 | func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE; | ||
595 | adapter->ahw->pci_func = func; | ||
596 | 622 | ||
597 | /* Determine function privilege level */ | 623 | /* Determine function privilege level */ |
598 | priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE; | 624 | op_mode = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); |
599 | op_mode = readl(priv_op); | ||
600 | if (op_mode == QLC_DEV_DRV_DEFAULT) | 625 | if (op_mode == QLC_DEV_DRV_DEFAULT) |
601 | priv_level = QLCNIC_MGMT_FUNC; | 626 | priv_level = QLCNIC_MGMT_FUNC; |
602 | else | 627 | else |
@@ -613,12 +638,16 @@ qlcnic_check_vf(struct qlcnic_adapter *adapter) | |||
613 | } | 638 | } |
614 | 639 | ||
615 | #define QLCNIC_82XX_BAR0_LENGTH 0x00200000UL | 640 | #define QLCNIC_82XX_BAR0_LENGTH 0x00200000UL |
641 | #define QLCNIC_83XX_BAR0_LENGTH 0x4000 | ||
616 | static void qlcnic_get_bar_length(u32 dev_id, ulong *bar) | 642 | static void qlcnic_get_bar_length(u32 dev_id, ulong *bar) |
617 | { | 643 | { |
618 | switch (dev_id) { | 644 | switch (dev_id) { |
619 | case PCI_DEVICE_ID_QLOGIC_QLE824X: | 645 | case PCI_DEVICE_ID_QLOGIC_QLE824X: |
620 | *bar = QLCNIC_82XX_BAR0_LENGTH; | 646 | *bar = QLCNIC_82XX_BAR0_LENGTH; |
621 | break; | 647 | break; |
648 | case PCI_DEVICE_ID_QLOGIC_QLE834X: | ||
649 | *bar = QLCNIC_83XX_BAR0_LENGTH; | ||
650 | break; | ||
622 | default: | 651 | default: |
623 | *bar = 0; | 652 | *bar = 0; |
624 | } | 653 | } |
@@ -713,8 +742,9 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) | |||
713 | } | 742 | } |
714 | } | 743 | } |
715 | 744 | ||
716 | dev_info(&pdev->dev, "firmware v%d.%d.%d\n", | 745 | dev_info(&pdev->dev, "Driver v%s, firmware v%d.%d.%d\n", |
717 | fw_major, fw_minor, fw_build); | 746 | QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build); |
747 | |||
718 | if (adapter->ahw->port_type == QLCNIC_XGBE) { | 748 | if (adapter->ahw->port_type == QLCNIC_XGBE) { |
719 | if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { | 749 | if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { |
720 | adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF; | 750 | adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF; |
@@ -760,6 +790,10 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter) | |||
760 | adapter->ahw->max_mac_filters = nic_info.max_mac_filters; | 790 | adapter->ahw->max_mac_filters = nic_info.max_mac_filters; |
761 | adapter->ahw->max_mtu = nic_info.max_mtu; | 791 | adapter->ahw->max_mtu = nic_info.max_mtu; |
762 | 792 | ||
793 | /* Disable NPAR for 83XX */ | ||
794 | if (qlcnic_83xx_check(adapter)) | ||
795 | return err; | ||
796 | |||
763 | if (adapter->ahw->capabilities & BIT_6) | 797 | if (adapter->ahw->capabilities & BIT_6) |
764 | adapter->flags |= QLCNIC_ESWITCH_ENABLED; | 798 | adapter->flags |= QLCNIC_ESWITCH_ENABLED; |
765 | else | 799 | else |
@@ -839,14 +873,17 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, | |||
839 | struct qlcnic_esw_func_cfg *esw_cfg) | 873 | struct qlcnic_esw_func_cfg *esw_cfg) |
840 | { | 874 | { |
841 | struct net_device *netdev = adapter->netdev; | 875 | struct net_device *netdev = adapter->netdev; |
842 | netdev_features_t features, vlan_features; | 876 | unsigned long features, vlan_features; |
877 | |||
878 | if (qlcnic_83xx_check(adapter)) | ||
879 | return; | ||
843 | 880 | ||
844 | features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | | 881 | features = (NETIF_F_SG | NETIF_F_IP_CSUM | |
845 | NETIF_F_IPV6_CSUM | NETIF_F_GRO); | 882 | NETIF_F_IPV6_CSUM | NETIF_F_GRO); |
846 | vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM | | 883 | vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM | |
847 | NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_FILTER); | 884 | NETIF_F_IPV6_CSUM); |
848 | 885 | ||
849 | if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) { | 886 | if (QLCNIC_IS_TSO_CAPABLE(adapter)) { |
850 | features |= (NETIF_F_TSO | NETIF_F_TSO6); | 887 | features |= (NETIF_F_TSO | NETIF_F_TSO6); |
851 | vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); | 888 | vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); |
852 | } | 889 | } |
@@ -856,12 +893,14 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, | |||
856 | 893 | ||
857 | if (esw_cfg->offload_flags & BIT_0) { | 894 | if (esw_cfg->offload_flags & BIT_0) { |
858 | netdev->features |= features; | 895 | netdev->features |= features; |
896 | adapter->rx_csum = 1; | ||
859 | if (!(esw_cfg->offload_flags & BIT_1)) | 897 | if (!(esw_cfg->offload_flags & BIT_1)) |
860 | netdev->features &= ~NETIF_F_TSO; | 898 | netdev->features &= ~NETIF_F_TSO; |
861 | if (!(esw_cfg->offload_flags & BIT_2)) | 899 | if (!(esw_cfg->offload_flags & BIT_2)) |
862 | netdev->features &= ~NETIF_F_TSO6; | 900 | netdev->features &= ~NETIF_F_TSO6; |
863 | } else { | 901 | } else { |
864 | netdev->features &= ~features; | 902 | netdev->features &= ~features; |
903 | adapter->rx_csum = 0; | ||
865 | } | 904 | } |
866 | 905 | ||
867 | netdev->vlan_features = (features & vlan_features); | 906 | netdev->vlan_features = (features & vlan_features); |
@@ -870,7 +909,6 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, | |||
870 | static int | 909 | static int |
871 | qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) | 910 | qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) |
872 | { | 911 | { |
873 | void __iomem *priv_op; | ||
874 | u32 op_mode, priv_level; | 912 | u32 op_mode, priv_level; |
875 | int err = 0; | 913 | int err = 0; |
876 | 914 | ||
@@ -881,8 +919,7 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) | |||
881 | if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED) | 919 | if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED) |
882 | return 0; | 920 | return 0; |
883 | 921 | ||
884 | priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE; | 922 | op_mode = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE); |
885 | op_mode = readl(priv_op); | ||
886 | priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); | 923 | priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func); |
887 | 924 | ||
888 | if (op_mode == QLC_DEV_DRV_DEFAULT) | 925 | if (op_mode == QLC_DEV_DRV_DEFAULT) |
@@ -947,6 +984,7 @@ static int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) | |||
947 | return 0; | 984 | return 0; |
948 | } | 985 | } |
949 | 986 | ||
987 | |||
950 | static int | 988 | static int |
951 | qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, | 989 | qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, |
952 | struct qlcnic_npar_info *npar, int pci_func) | 990 | struct qlcnic_npar_info *npar, int pci_func) |
@@ -986,8 +1024,7 @@ static int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) | |||
986 | npar = &adapter->npars[i]; | 1024 | npar = &adapter->npars[i]; |
987 | pci_func = npar->pci_func; | 1025 | pci_func = npar->pci_func; |
988 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); | 1026 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); |
989 | err = qlcnic_get_nic_info(adapter, | 1027 | err = qlcnic_get_nic_info(adapter, &nic_info, pci_func); |
990 | &nic_info, pci_func); | ||
991 | if (err) | 1028 | if (err) |
992 | return err; | 1029 | return err; |
993 | nic_info.min_tx_bw = npar->min_bw; | 1030 | nic_info.min_tx_bw = npar->min_bw; |
@@ -1052,6 +1089,8 @@ qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter) | |||
1052 | 1089 | ||
1053 | qlcnic_dev_set_npar_ready(adapter); | 1090 | qlcnic_dev_set_npar_ready(adapter); |
1054 | 1091 | ||
1092 | if (qlcnic_83xx_check(adapter)) | ||
1093 | qlcnic_83xx_register_nic_idc_func(adapter, 1); | ||
1055 | return err; | 1094 | return err; |
1056 | } | 1095 | } |
1057 | 1096 | ||
@@ -1126,6 +1165,7 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter) | |||
1126 | { | 1165 | { |
1127 | irq_handler_t handler; | 1166 | irq_handler_t handler; |
1128 | struct qlcnic_host_sds_ring *sds_ring; | 1167 | struct qlcnic_host_sds_ring *sds_ring; |
1168 | struct qlcnic_host_tx_ring *tx_ring; | ||
1129 | int err, ring; | 1169 | int err, ring; |
1130 | 1170 | ||
1131 | unsigned long flags = 0; | 1171 | unsigned long flags = 0; |
@@ -1133,7 +1173,8 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter) | |||
1133 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; | 1173 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; |
1134 | 1174 | ||
1135 | if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { | 1175 | if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { |
1136 | handler = qlcnic_tmp_intr; | 1176 | if (qlcnic_82xx_check(adapter)) |
1177 | handler = qlcnic_tmp_intr; | ||
1137 | if (!QLCNIC_IS_MSI_FAMILY(adapter)) | 1178 | if (!QLCNIC_IS_MSI_FAMILY(adapter)) |
1138 | flags |= IRQF_SHARED; | 1179 | flags |= IRQF_SHARED; |
1139 | 1180 | ||
@@ -1149,15 +1190,32 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter) | |||
1149 | } | 1190 | } |
1150 | adapter->irq = netdev->irq; | 1191 | adapter->irq = netdev->irq; |
1151 | 1192 | ||
1152 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 1193 | if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST) { |
1153 | sds_ring = &recv_ctx->sds_rings[ring]; | 1194 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
1154 | sprintf(sds_ring->name, "%s[%d]", netdev->name, ring); | 1195 | sds_ring = &recv_ctx->sds_rings[ring]; |
1155 | err = request_irq(sds_ring->irq, handler, | 1196 | snprintf(sds_ring->name, sizeof(int) + IFNAMSIZ, |
1156 | flags, sds_ring->name, sds_ring); | 1197 | "%s[%d]", netdev->name, ring); |
1157 | if (err) | 1198 | err = request_irq(sds_ring->irq, handler, flags, |
1158 | return err; | 1199 | sds_ring->name, sds_ring); |
1200 | if (err) | ||
1201 | return err; | ||
1202 | } | ||
1203 | if (qlcnic_83xx_check(adapter) && | ||
1204 | (adapter->flags & QLCNIC_MSIX_ENABLED)) { | ||
1205 | handler = qlcnic_msix_tx_intr; | ||
1206 | for (ring = 0; ring < adapter->max_drv_tx_rings; | ||
1207 | ring++) { | ||
1208 | tx_ring = &adapter->tx_ring[ring]; | ||
1209 | snprintf(tx_ring->name, sizeof(int) + IFNAMSIZ, | ||
1210 | "%s[%d]", netdev->name, | ||
1211 | adapter->max_sds_rings + ring); | ||
1212 | err = request_irq(tx_ring->irq, handler, flags, | ||
1213 | tx_ring->name, tx_ring); | ||
1214 | if (err) | ||
1215 | return err; | ||
1216 | } | ||
1217 | } | ||
1159 | } | 1218 | } |
1160 | |||
1161 | return 0; | 1219 | return 0; |
1162 | } | 1220 | } |
1163 | 1221 | ||
@@ -1166,12 +1224,23 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter) | |||
1166 | { | 1224 | { |
1167 | int ring; | 1225 | int ring; |
1168 | struct qlcnic_host_sds_ring *sds_ring; | 1226 | struct qlcnic_host_sds_ring *sds_ring; |
1227 | struct qlcnic_host_tx_ring *tx_ring; | ||
1169 | 1228 | ||
1170 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; | 1229 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; |
1171 | 1230 | ||
1172 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 1231 | if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST) { |
1173 | sds_ring = &recv_ctx->sds_rings[ring]; | 1232 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
1174 | free_irq(sds_ring->irq, sds_ring); | 1233 | sds_ring = &recv_ctx->sds_rings[ring]; |
1234 | free_irq(sds_ring->irq, sds_ring); | ||
1235 | } | ||
1236 | if (qlcnic_83xx_check(adapter)) { | ||
1237 | for (ring = 0; ring < adapter->max_drv_tx_rings; | ||
1238 | ring++) { | ||
1239 | tx_ring = &adapter->tx_ring[ring]; | ||
1240 | if (tx_ring->irq) | ||
1241 | free_irq(tx_ring->irq, tx_ring); | ||
1242 | } | ||
1243 | } | ||
1175 | } | 1244 | } |
1176 | } | 1245 | } |
1177 | 1246 | ||
@@ -1229,8 +1298,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
1229 | 1298 | ||
1230 | /* Usage: During resume and firmware recovery module.*/ | 1299 | /* Usage: During resume and firmware recovery module.*/ |
1231 | 1300 | ||
1232 | static int | 1301 | static int qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) |
1233 | qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) | ||
1234 | { | 1302 | { |
1235 | int err = 0; | 1303 | int err = 0; |
1236 | 1304 | ||
@@ -1358,7 +1426,10 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings) | |||
1358 | if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { | 1426 | if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { |
1359 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 1427 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
1360 | sds_ring = &adapter->recv_ctx->sds_rings[ring]; | 1428 | sds_ring = &adapter->recv_ctx->sds_rings[ring]; |
1361 | qlcnic_disable_int(sds_ring); | 1429 | if (qlcnic_83xx_check(adapter)) |
1430 | writel(1, sds_ring->crb_intr_mask); | ||
1431 | else | ||
1432 | qlcnic_disable_int(sds_ring); | ||
1362 | } | 1433 | } |
1363 | } | 1434 | } |
1364 | 1435 | ||
@@ -1484,6 +1555,7 @@ qlcnic_reset_hw_context(struct qlcnic_adapter *adapter) | |||
1484 | netif_device_attach(netdev); | 1555 | netif_device_attach(netdev); |
1485 | 1556 | ||
1486 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | 1557 | clear_bit(__QLCNIC_RESETTING, &adapter->state); |
1558 | dev_err(&adapter->pdev->dev, "%s:\n", __func__); | ||
1487 | return 0; | 1559 | return 0; |
1488 | } | 1560 | } |
1489 | 1561 | ||
@@ -1527,33 +1599,38 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev, | |||
1527 | int err; | 1599 | int err; |
1528 | struct pci_dev *pdev = adapter->pdev; | 1600 | struct pci_dev *pdev = adapter->pdev; |
1529 | 1601 | ||
1602 | adapter->rx_csum = 1; | ||
1530 | adapter->ahw->mc_enabled = 0; | 1603 | adapter->ahw->mc_enabled = 0; |
1531 | adapter->ahw->max_mc_count = 38; | 1604 | adapter->ahw->max_mc_count = QLCNIC_MAX_MC_COUNT; |
1532 | 1605 | ||
1533 | netdev->netdev_ops = &qlcnic_netdev_ops; | 1606 | netdev->netdev_ops = &qlcnic_netdev_ops; |
1534 | netdev->watchdog_timeo = 5*HZ; | 1607 | netdev->watchdog_timeo = QLCNIC_WATCHDOG_TIMEOUTVALUE * HZ; |
1535 | 1608 | ||
1536 | qlcnic_change_mtu(netdev, netdev->mtu); | 1609 | qlcnic_change_mtu(netdev, netdev->mtu); |
1537 | 1610 | ||
1538 | SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); | 1611 | SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); |
1539 | 1612 | ||
1540 | netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | | 1613 | netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | |
1541 | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM; | 1614 | NETIF_F_IPV6_CSUM | NETIF_F_GRO | |
1615 | NETIF_F_HW_VLAN_RX); | ||
1616 | netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | | ||
1617 | NETIF_F_IPV6_CSUM); | ||
1542 | 1618 | ||
1543 | if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO) | 1619 | if (QLCNIC_IS_TSO_CAPABLE(adapter)) { |
1544 | netdev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6; | 1620 | netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6); |
1545 | if (pci_using_dac == 1) | 1621 | netdev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); |
1546 | netdev->hw_features |= NETIF_F_HIGHDMA; | 1622 | } |
1547 | 1623 | ||
1548 | netdev->vlan_features = netdev->hw_features; | 1624 | if (pci_using_dac) { |
1625 | netdev->features |= NETIF_F_HIGHDMA; | ||
1626 | netdev->vlan_features |= NETIF_F_HIGHDMA; | ||
1627 | } | ||
1549 | 1628 | ||
1550 | if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX) | 1629 | if (qlcnic_vlan_tx_check(adapter)) |
1551 | netdev->hw_features |= NETIF_F_HW_VLAN_TX; | 1630 | netdev->features |= (NETIF_F_HW_VLAN_TX); |
1552 | if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) | ||
1553 | netdev->hw_features |= NETIF_F_LRO; | ||
1554 | 1631 | ||
1555 | netdev->features |= netdev->hw_features | | 1632 | if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) |
1556 | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; | 1633 | netdev->features |= NETIF_F_LRO; |
1557 | 1634 | ||
1558 | netdev->irq = adapter->msix_entries[0].vector; | 1635 | netdev->irq = adapter->msix_entries[0].vector; |
1559 | 1636 | ||
@@ -1582,19 +1659,6 @@ static int qlcnic_set_dma_mask(struct pci_dev *pdev, int *pci_using_dac) | |||
1582 | return 0; | 1659 | return 0; |
1583 | } | 1660 | } |
1584 | 1661 | ||
1585 | static int | ||
1586 | qlcnic_alloc_msix_entries(struct qlcnic_adapter *adapter, u16 count) | ||
1587 | { | ||
1588 | adapter->msix_entries = kcalloc(count, sizeof(struct msix_entry), | ||
1589 | GFP_KERNEL); | ||
1590 | |||
1591 | if (adapter->msix_entries) | ||
1592 | return 0; | ||
1593 | |||
1594 | dev_err(&adapter->pdev->dev, "failed allocating msix_entries\n"); | ||
1595 | return -ENOMEM; | ||
1596 | } | ||
1597 | |||
1598 | void qlcnic_free_tx_rings(struct qlcnic_adapter *adapter) | 1662 | void qlcnic_free_tx_rings(struct qlcnic_adapter *adapter) |
1599 | { | 1663 | { |
1600 | int ring; | 1664 | int ring; |
@@ -1691,6 +1755,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1691 | if (ent->device == PCI_DEVICE_ID_QLOGIC_QLE824X) { | 1755 | if (ent->device == PCI_DEVICE_ID_QLOGIC_QLE824X) { |
1692 | ahw->hw_ops = &qlcnic_hw_ops; | 1756 | ahw->hw_ops = &qlcnic_hw_ops; |
1693 | ahw->reg_tbl = (u32 *)qlcnic_reg_tbl; | 1757 | ahw->reg_tbl = (u32 *)qlcnic_reg_tbl; |
1758 | } else if (ent->device == PCI_DEVICE_ID_QLOGIC_QLE834X) { | ||
1759 | qlcnic_83xx_register_map(ahw); | ||
1760 | } else { | ||
1761 | goto err_out_free_hw_res; | ||
1694 | } | 1762 | } |
1695 | 1763 | ||
1696 | err = qlcnic_setup_pci_map(pdev, ahw); | 1764 | err = qlcnic_setup_pci_map(pdev, ahw); |
@@ -1708,6 +1776,13 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1708 | adapter = netdev_priv(netdev); | 1776 | adapter = netdev_priv(netdev); |
1709 | adapter->netdev = netdev; | 1777 | adapter->netdev = netdev; |
1710 | adapter->pdev = pdev; | 1778 | adapter->pdev = pdev; |
1779 | adapter->ahw = ahw; | ||
1780 | |||
1781 | adapter->qlcnic_wq = create_singlethread_workqueue("qlcnic"); | ||
1782 | if (adapter->qlcnic_wq == NULL) { | ||
1783 | dev_err(&pdev->dev, "Failed to create workqueue\n"); | ||
1784 | goto err_out_free_netdev; | ||
1785 | } | ||
1711 | 1786 | ||
1712 | err = qlcnic_alloc_adapter_resources(adapter); | 1787 | err = qlcnic_alloc_adapter_resources(adapter); |
1713 | if (err) | 1788 | if (err) |
@@ -1725,7 +1800,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1725 | INIT_LIST_HEAD(&adapter->mac_list); | 1800 | INIT_LIST_HEAD(&adapter->mac_list); |
1726 | 1801 | ||
1727 | if (qlcnic_82xx_check(adapter)) { | 1802 | if (qlcnic_82xx_check(adapter)) { |
1728 | qlcnic_check_vf(adapter); | 1803 | qlcnic_check_vf(adapter, ent); |
1729 | adapter->portnum = adapter->ahw->pci_func; | 1804 | adapter->portnum = adapter->ahw->pci_func; |
1730 | err = qlcnic_start_firmware(adapter); | 1805 | err = qlcnic_start_firmware(adapter); |
1731 | if (err) { | 1806 | if (err) { |
@@ -1738,6 +1813,13 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1738 | goto err_out_free_hw; | 1813 | goto err_out_free_hw; |
1739 | 1814 | ||
1740 | adapter->flags |= QLCNIC_NEED_FLR; | 1815 | adapter->flags |= QLCNIC_NEED_FLR; |
1816 | } else if (qlcnic_83xx_check(adapter)) { | ||
1817 | qlcnic_83xx_check_vf(adapter, ent); | ||
1818 | adapter->portnum = adapter->ahw->pci_func; | ||
1819 | } else { | ||
1820 | dev_err(&pdev->dev, | ||
1821 | "%s: failed. Please Reboot\n", __func__); | ||
1822 | goto err_out_free_hw; | ||
1741 | } | 1823 | } |
1742 | 1824 | ||
1743 | if (qlcnic_read_mac_addr(adapter)) | 1825 | if (qlcnic_read_mac_addr(adapter)) |
@@ -1745,18 +1827,20 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1745 | 1827 | ||
1746 | if (adapter->portnum == 0) { | 1828 | if (adapter->portnum == 0) { |
1747 | qlcnic_get_board_name(adapter, board_name); | 1829 | qlcnic_get_board_name(adapter, board_name); |
1830 | |||
1748 | pr_info("%s: %s Board Chip rev 0x%x\n", | 1831 | pr_info("%s: %s Board Chip rev 0x%x\n", |
1749 | module_name(THIS_MODULE), | 1832 | module_name(THIS_MODULE), |
1750 | board_name, adapter->ahw->revision_id); | 1833 | board_name, adapter->ahw->revision_id); |
1751 | } | 1834 | } |
1752 | err = qlcnic_alloc_msix_entries(adapter, adapter->ahw->max_rx_ques); | ||
1753 | if (err) | ||
1754 | goto err_out_disable_msi; | ||
1755 | |||
1756 | err = qlcnic_setup_intr(adapter, 0); | 1835 | err = qlcnic_setup_intr(adapter, 0); |
1757 | if (err) | 1836 | if (err) |
1758 | goto err_out_disable_msi; | 1837 | goto err_out_disable_msi; |
1759 | 1838 | ||
1839 | if (qlcnic_83xx_check(adapter)) { | ||
1840 | err = qlcnic_83xx_setup_mbx_intr(adapter); | ||
1841 | if (err) | ||
1842 | goto err_out_disable_msi; | ||
1843 | } | ||
1760 | 1844 | ||
1761 | err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); | 1845 | err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); |
1762 | if (err) | 1846 | if (err) |
@@ -1790,6 +1874,11 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1790 | return 0; | 1874 | return 0; |
1791 | 1875 | ||
1792 | err_out_disable_mbx_intr: | 1876 | err_out_disable_mbx_intr: |
1877 | if (qlcnic_83xx_check(adapter)) { | ||
1878 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | ||
1879 | qlcnic_83xx_config_intrpt(adapter, 0); | ||
1880 | qlcnic_83xx_free_mbx_intr(adapter); | ||
1881 | } | ||
1793 | 1882 | ||
1794 | err_out_disable_msi: | 1883 | err_out_disable_msi: |
1795 | qlcnic_teardown_intr(adapter); | 1884 | qlcnic_teardown_intr(adapter); |
@@ -1817,10 +1906,11 @@ err_out_disable_pdev: | |||
1817 | return err; | 1906 | return err; |
1818 | } | 1907 | } |
1819 | 1908 | ||
1820 | static void qlcnic_remove(struct pci_dev *pdev) | 1909 | static void __devexit qlcnic_remove(struct pci_dev *pdev) |
1821 | { | 1910 | { |
1822 | struct qlcnic_adapter *adapter; | 1911 | struct qlcnic_adapter *adapter; |
1823 | struct net_device *netdev; | 1912 | struct net_device *netdev; |
1913 | struct qlcnic_hardware_context *ahw; | ||
1824 | 1914 | ||
1825 | adapter = pci_get_drvdata(pdev); | 1915 | adapter = pci_get_drvdata(pdev); |
1826 | if (adapter == NULL) | 1916 | if (adapter == NULL) |
@@ -1828,10 +1918,17 @@ static void qlcnic_remove(struct pci_dev *pdev) | |||
1828 | 1918 | ||
1829 | netdev = adapter->netdev; | 1919 | netdev = adapter->netdev; |
1830 | 1920 | ||
1831 | qlcnic_cancel_fw_work(adapter); | 1921 | qlcnic_cancel_idc_work(adapter); |
1922 | ahw = adapter->ahw; | ||
1832 | 1923 | ||
1833 | unregister_netdev(netdev); | 1924 | unregister_netdev(netdev); |
1834 | 1925 | ||
1926 | if (qlcnic_83xx_check(adapter)) { | ||
1927 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | ||
1928 | qlcnic_83xx_config_intrpt(adapter, 0); | ||
1929 | qlcnic_83xx_free_mbx_intr(adapter); | ||
1930 | } | ||
1931 | |||
1835 | qlcnic_detach(adapter); | 1932 | qlcnic_detach(adapter); |
1836 | 1933 | ||
1837 | if (adapter->npars != NULL) | 1934 | if (adapter->npars != NULL) |
@@ -1847,9 +1944,8 @@ static void qlcnic_remove(struct pci_dev *pdev) | |||
1847 | qlcnic_free_lb_filters_mem(adapter); | 1944 | qlcnic_free_lb_filters_mem(adapter); |
1848 | 1945 | ||
1849 | qlcnic_teardown_intr(adapter); | 1946 | qlcnic_teardown_intr(adapter); |
1850 | kfree(adapter->msix_entries); | ||
1851 | 1947 | ||
1852 | qlcnic_remove_diag_entries(adapter); | 1948 | qlcnic_remove_sysfs(adapter); |
1853 | 1949 | ||
1854 | qlcnic_cleanup_pci_map(adapter); | 1950 | qlcnic_cleanup_pci_map(adapter); |
1855 | 1951 | ||
@@ -1860,7 +1956,12 @@ static void qlcnic_remove(struct pci_dev *pdev) | |||
1860 | pci_disable_device(pdev); | 1956 | pci_disable_device(pdev); |
1861 | pci_set_drvdata(pdev, NULL); | 1957 | pci_set_drvdata(pdev, NULL); |
1862 | 1958 | ||
1959 | if (adapter->qlcnic_wq) { | ||
1960 | destroy_workqueue(adapter->qlcnic_wq); | ||
1961 | adapter->qlcnic_wq = NULL; | ||
1962 | } | ||
1863 | qlcnic_free_adapter_resources(adapter); | 1963 | qlcnic_free_adapter_resources(adapter); |
1964 | kfree(ahw); | ||
1864 | free_netdev(netdev); | 1965 | free_netdev(netdev); |
1865 | } | 1966 | } |
1866 | static int __qlcnic_shutdown(struct pci_dev *pdev) | 1967 | static int __qlcnic_shutdown(struct pci_dev *pdev) |
@@ -1871,7 +1972,7 @@ static int __qlcnic_shutdown(struct pci_dev *pdev) | |||
1871 | 1972 | ||
1872 | netif_device_detach(netdev); | 1973 | netif_device_detach(netdev); |
1873 | 1974 | ||
1874 | qlcnic_cancel_fw_work(adapter); | 1975 | qlcnic_cancel_idc_work(adapter); |
1875 | 1976 | ||
1876 | if (netif_running(netdev)) | 1977 | if (netif_running(netdev)) |
1877 | qlcnic_down(adapter, netdev); | 1978 | qlcnic_down(adapter, netdev); |
@@ -1884,7 +1985,6 @@ static int __qlcnic_shutdown(struct pci_dev *pdev) | |||
1884 | retval = pci_save_state(pdev); | 1985 | retval = pci_save_state(pdev); |
1885 | if (retval) | 1986 | if (retval) |
1886 | return retval; | 1987 | return retval; |
1887 | |||
1888 | if (qlcnic_82xx_check(adapter)) { | 1988 | if (qlcnic_82xx_check(adapter)) { |
1889 | if (qlcnic_wol_supported(adapter)) { | 1989 | if (qlcnic_wol_supported(adapter)) { |
1890 | pci_enable_wake(pdev, PCI_D3cold, 1); | 1990 | pci_enable_wake(pdev, PCI_D3cold, 1); |
@@ -1932,7 +2032,7 @@ qlcnic_resume(struct pci_dev *pdev) | |||
1932 | pci_set_master(pdev); | 2032 | pci_set_master(pdev); |
1933 | pci_restore_state(pdev); | 2033 | pci_restore_state(pdev); |
1934 | 2034 | ||
1935 | err = adapter->nic_ops->start_firmware(adapter); | 2035 | err = qlcnic_start_firmware(adapter); |
1936 | if (err) { | 2036 | if (err) { |
1937 | dev_err(&pdev->dev, "failed to start firmware\n"); | 2037 | dev_err(&pdev->dev, "failed to start firmware\n"); |
1938 | return err; | 2038 | return err; |
@@ -1990,6 +2090,11 @@ static int qlcnic_close(struct net_device *netdev) | |||
1990 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 2090 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1991 | 2091 | ||
1992 | __qlcnic_down(adapter, netdev); | 2092 | __qlcnic_down(adapter, netdev); |
2093 | if (qlcnic_83xx_check(adapter)) { | ||
2094 | qlcnic_83xx_register_nic_idc_func(adapter, 0); | ||
2095 | cancel_delayed_work_sync(&adapter->idc_aen_work); | ||
2096 | } | ||
2097 | |||
1993 | return 0; | 2098 | return 0; |
1994 | } | 2099 | } |
1995 | 2100 | ||
@@ -1997,21 +2102,37 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) | |||
1997 | { | 2102 | { |
1998 | void *head; | 2103 | void *head; |
1999 | int i; | 2104 | int i; |
2105 | struct net_device *netdev = adapter->netdev; | ||
2106 | u32 filter_size = 0; | ||
2107 | u16 act_pci_func = 0; | ||
2000 | 2108 | ||
2001 | if (adapter->fhash.fmax && adapter->fhash.fhead) | 2109 | if (adapter->fhash.fmax && adapter->fhash.fhead) |
2002 | return; | 2110 | return; |
2003 | 2111 | ||
2112 | act_pci_func = adapter->ahw->act_pci_func; | ||
2004 | spin_lock_init(&adapter->mac_learn_lock); | 2113 | spin_lock_init(&adapter->mac_learn_lock); |
2005 | 2114 | ||
2006 | head = kcalloc(QLCNIC_LB_MAX_FILTERS, sizeof(struct hlist_head), | 2115 | if (qlcnic_82xx_check(adapter)) { |
2007 | GFP_KERNEL); | 2116 | filter_size = QLCNIC_LB_MAX_FILTERS; |
2117 | adapter->fhash.fbucket_size = QLCNIC_LB_BUCKET_SIZE; | ||
2118 | } else { | ||
2119 | filter_size = QLC_83XX_LB_MAX_FILTERS; | ||
2120 | adapter->fhash.fbucket_size = QLC_83XX_LB_BUCKET_SIZE; | ||
2121 | } | ||
2122 | |||
2123 | head = kcalloc(adapter->fhash.fbucket_size, | ||
2124 | sizeof(struct hlist_head), GFP_KERNEL); | ||
2125 | |||
2008 | if (!head) | 2126 | if (!head) |
2009 | return; | 2127 | return; |
2010 | 2128 | ||
2011 | adapter->fhash.fmax = QLCNIC_LB_MAX_FILTERS; | 2129 | adapter->fhash.fmax = (filter_size / act_pci_func); |
2012 | adapter->fhash.fhead = head; | 2130 | adapter->fhash.fhead = head; |
2013 | 2131 | ||
2014 | for (i = 0; i < adapter->fhash.fmax; i++) | 2132 | netdev_info(netdev, "active nic func = %d, mac filter size=%d\n", |
2133 | act_pci_func, adapter->fhash.fmax); | ||
2134 | |||
2135 | for (i = 0; i < adapter->fhash.fbucket_size; i++) | ||
2015 | INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); | 2136 | INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); |
2016 | } | 2137 | } |
2017 | 2138 | ||
@@ -2030,6 +2151,9 @@ static int qlcnic_check_temp(struct qlcnic_adapter *adapter) | |||
2030 | u32 temp_state, temp_val, temp = 0; | 2151 | u32 temp_state, temp_val, temp = 0; |
2031 | int rv = 0; | 2152 | int rv = 0; |
2032 | 2153 | ||
2154 | if (qlcnic_83xx_check(adapter)) | ||
2155 | temp = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP); | ||
2156 | |||
2033 | if (qlcnic_82xx_check(adapter)) | 2157 | if (qlcnic_82xx_check(adapter)) |
2034 | temp = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP); | 2158 | temp = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP); |
2035 | 2159 | ||
@@ -2167,6 +2291,14 @@ static irqreturn_t qlcnic_msix_intr(int irq, void *data) | |||
2167 | return IRQ_HANDLED; | 2291 | return IRQ_HANDLED; |
2168 | } | 2292 | } |
2169 | 2293 | ||
2294 | static irqreturn_t qlcnic_msix_tx_intr(int irq, void *data) | ||
2295 | { | ||
2296 | struct qlcnic_host_tx_ring *tx_ring = data; | ||
2297 | |||
2298 | napi_schedule(&tx_ring->napi); | ||
2299 | return IRQ_HANDLED; | ||
2300 | } | ||
2301 | |||
2170 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2302 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2171 | static void qlcnic_poll_controller(struct net_device *netdev) | 2303 | static void qlcnic_poll_controller(struct net_device *netdev) |
2172 | { | 2304 | { |
@@ -2592,25 +2724,22 @@ void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *adapter, u32 key) | |||
2592 | dev_info(&adapter->pdev->dev, "Pause control frames disabled" | 2724 | dev_info(&adapter->pdev->dev, "Pause control frames disabled" |
2593 | " on all ports\n"); | 2725 | " on all ports\n"); |
2594 | adapter->need_fw_reset = 1; | 2726 | adapter->need_fw_reset = 1; |
2727 | |||
2595 | if (qlcnic_api_lock(adapter)) | 2728 | if (qlcnic_api_lock(adapter)) |
2596 | return; | 2729 | return; |
2597 | 2730 | ||
2598 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | 2731 | state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); |
2599 | if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD)) { | ||
2600 | netdev_err(adapter->netdev, | ||
2601 | "Device is in FAILED state, Please Reboot\n"); | ||
2602 | qlcnic_api_unlock(adapter); | ||
2603 | return; | ||
2604 | } | ||
2605 | 2732 | ||
2606 | if (state == QLCNIC_DEV_READY) { | 2733 | if (state == QLCNIC_DEV_READY) { |
2607 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET); | 2734 | QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_STATE, |
2735 | QLCNIC_DEV_NEED_RESET); | ||
2608 | adapter->flags |= QLCNIC_FW_RESET_OWNER; | 2736 | adapter->flags |= QLCNIC_FW_RESET_OWNER; |
2609 | QLCDB(adapter, DRV, "NEED_RESET state set\n"); | 2737 | QLCDB(adapter, DRV, "NEED_RESET state set\n"); |
2610 | qlcnic_idc_debug_info(adapter, 0); | 2738 | qlcnic_idc_debug_info(adapter, 0); |
2611 | } | 2739 | } |
2612 | 2740 | ||
2613 | QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER); | 2741 | QLC_SHARED_REG_WR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, |
2742 | QLCNIC_DEV_NPAR_NON_OPER); | ||
2614 | qlcnic_api_unlock(adapter); | 2743 | qlcnic_api_unlock(adapter); |
2615 | } | 2744 | } |
2616 | 2745 | ||
@@ -2628,28 +2757,15 @@ qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) | |||
2628 | qlcnic_api_unlock(adapter); | 2757 | qlcnic_api_unlock(adapter); |
2629 | } | 2758 | } |
2630 | 2759 | ||
2631 | static void | 2760 | void qlcnic_schedule_work(struct qlcnic_adapter *adapter, |
2632 | qlcnic_schedule_work(struct qlcnic_adapter *adapter, | 2761 | work_func_t func, int delay) |
2633 | work_func_t func, int delay) | ||
2634 | { | 2762 | { |
2635 | if (test_bit(__QLCNIC_AER, &adapter->state)) | 2763 | if (test_bit(__QLCNIC_AER, &adapter->state)) |
2636 | return; | 2764 | return; |
2637 | 2765 | ||
2638 | INIT_DELAYED_WORK(&adapter->fw_work, func); | 2766 | INIT_DELAYED_WORK(&adapter->fw_work, func); |
2639 | queue_delayed_work(qlcnic_wq, &adapter->fw_work, | 2767 | queue_delayed_work(adapter->qlcnic_wq, &adapter->fw_work, |
2640 | round_jiffies_relative(delay)); | 2768 | round_jiffies_relative(delay)); |
2641 | } | ||
2642 | |||
2643 | static void | ||
2644 | qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter) | ||
2645 | { | ||
2646 | while (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) | ||
2647 | msleep(10); | ||
2648 | |||
2649 | if (!adapter->fw_work.work.func) | ||
2650 | return; | ||
2651 | |||
2652 | cancel_delayed_work_sync(&adapter->fw_work); | ||
2653 | } | 2769 | } |
2654 | 2770 | ||
2655 | static void | 2771 | static void |
@@ -2788,6 +2904,19 @@ reschedule: | |||
2788 | qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); | 2904 | qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); |
2789 | } | 2905 | } |
2790 | 2906 | ||
2907 | struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, | ||
2908 | unsigned int devfn) | ||
2909 | { | ||
2910 | struct pci_dev *dev = NULL; | ||
2911 | |||
2912 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | ||
2913 | if (pci_domain_nr(dev->bus) == domain && | ||
2914 | (dev->bus->number == bus && dev->devfn == devfn)) | ||
2915 | return dev; | ||
2916 | } | ||
2917 | return NULL; | ||
2918 | } | ||
2919 | |||
2791 | static int qlcnic_is_first_func(struct pci_dev *pdev) | 2920 | static int qlcnic_is_first_func(struct pci_dev *pdev) |
2792 | { | 2921 | { |
2793 | struct pci_dev *oth_pdev; | 2922 | struct pci_dev *oth_pdev; |
@@ -2839,12 +2968,25 @@ static int qlcnic_attach_func(struct pci_dev *pdev) | |||
2839 | } | 2968 | } |
2840 | qlcnic_api_unlock(adapter); | 2969 | qlcnic_api_unlock(adapter); |
2841 | 2970 | ||
2842 | err = adapter->nic_ops->start_firmware(adapter); | 2971 | err = qlcnic_start_firmware(adapter); |
2843 | if (err) | 2972 | if (err) |
2844 | return err; | 2973 | return err; |
2845 | 2974 | ||
2846 | qlcnic_clr_drv_state(adapter); | 2975 | qlcnic_clr_drv_state(adapter); |
2847 | qlcnic_setup_intr(adapter, 0); | 2976 | kfree(adapter->msix_entries); |
2977 | adapter->msix_entries = NULL; | ||
2978 | err = qlcnic_setup_intr(adapter, 0); | ||
2979 | |||
2980 | if (qlcnic_83xx_check(adapter)) { | ||
2981 | err = qlcnic_83xx_setup_mbx_intr(adapter); | ||
2982 | if (err) { | ||
2983 | dev_err(&adapter->pdev->dev, | ||
2984 | "failed to setup mbx interrupt\n"); | ||
2985 | qlcnic_clr_all_drv_state(adapter, 1); | ||
2986 | clear_bit(__QLCNIC_AER, &adapter->state); | ||
2987 | goto done; | ||
2988 | } | ||
2989 | } | ||
2848 | 2990 | ||
2849 | if (netif_running(netdev)) { | 2991 | if (netif_running(netdev)) { |
2850 | err = qlcnic_attach(adapter); | 2992 | err = qlcnic_attach(adapter); |
@@ -2886,6 +3028,12 @@ static pci_ers_result_t qlcnic_io_error_detected(struct pci_dev *pdev, | |||
2886 | if (netif_running(netdev)) | 3028 | if (netif_running(netdev)) |
2887 | qlcnic_down(adapter, netdev); | 3029 | qlcnic_down(adapter, netdev); |
2888 | 3030 | ||
3031 | if (qlcnic_83xx_check(adapter)) { | ||
3032 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | ||
3033 | qlcnic_83xx_config_intrpt(adapter, 0); | ||
3034 | qlcnic_83xx_free_mbx_intr(adapter); | ||
3035 | } | ||
3036 | |||
2889 | qlcnic_detach(adapter); | 3037 | qlcnic_detach(adapter); |
2890 | qlcnic_teardown_intr(adapter); | 3038 | qlcnic_teardown_intr(adapter); |
2891 | 3039 | ||
@@ -2962,21 +3110,34 @@ int qlcnic_validate_max_rss(struct net_device *netdev, u8 max_hw, u8 val) | |||
2962 | 3110 | ||
2963 | int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data) | 3111 | int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data) |
2964 | { | 3112 | { |
3113 | int err; | ||
2965 | struct net_device *netdev = adapter->netdev; | 3114 | struct net_device *netdev = adapter->netdev; |
2966 | int err = 0; | ||
2967 | |||
2968 | if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) | ||
2969 | return -EBUSY; | ||
2970 | 3115 | ||
3116 | rtnl_lock(); | ||
2971 | netif_device_detach(netdev); | 3117 | netif_device_detach(netdev); |
2972 | if (netif_running(netdev)) | 3118 | if (netif_running(netdev)) |
2973 | __qlcnic_down(adapter, netdev); | 3119 | __qlcnic_down(adapter, netdev); |
3120 | |||
3121 | if (qlcnic_83xx_check(adapter)) { | ||
3122 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | ||
3123 | qlcnic_83xx_config_intrpt(adapter, 0); | ||
3124 | qlcnic_83xx_free_mbx_intr(adapter); | ||
3125 | } | ||
3126 | |||
2974 | qlcnic_detach(adapter); | 3127 | qlcnic_detach(adapter); |
2975 | qlcnic_teardown_intr(adapter); | 3128 | qlcnic_teardown_intr(adapter); |
3129 | err = adapter->ahw->hw_ops->setup_intr(adapter, data); | ||
3130 | if (err) | ||
3131 | dev_err(&adapter->pdev->dev, | ||
3132 | "failed setting max_rss; rss disabled\n"); | ||
2976 | 3133 | ||
2977 | if (qlcnic_enable_msix(adapter, data)) { | 3134 | if (qlcnic_83xx_check(adapter)) { |
2978 | netdev_info(netdev, "failed setting max_rss; rss disabled\n"); | 3135 | err = qlcnic_83xx_setup_mbx_intr(adapter); |
2979 | qlcnic_enable_msi_legacy(adapter); | 3136 | if (err) { |
3137 | dev_err(&adapter->pdev->dev, | ||
3138 | "failed to setup mbx interrupt\n"); | ||
3139 | goto done; | ||
3140 | } | ||
2980 | } | 3141 | } |
2981 | 3142 | ||
2982 | if (netif_running(netdev)) { | 3143 | if (netif_running(netdev)) { |
@@ -2991,6 +3152,7 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data) | |||
2991 | done: | 3152 | done: |
2992 | netif_device_attach(netdev); | 3153 | netif_device_attach(netdev); |
2993 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | 3154 | clear_bit(__QLCNIC_RESETTING, &adapter->state); |
3155 | rtnl_unlock(); | ||
2994 | return err; | 3156 | return err; |
2995 | } | 3157 | } |
2996 | 3158 | ||
@@ -3108,9 +3270,11 @@ recheck: | |||
3108 | switch (event) { | 3270 | switch (event) { |
3109 | case NETDEV_UP: | 3271 | case NETDEV_UP: |
3110 | qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_UP); | 3272 | qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_UP); |
3273 | |||
3111 | break; | 3274 | break; |
3112 | case NETDEV_DOWN: | 3275 | case NETDEV_DOWN: |
3113 | qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_DOWN); | 3276 | qlcnic_config_ipaddr(adapter, ifa->ifa_address, QLCNIC_IP_DOWN); |
3277 | |||
3114 | break; | 3278 | break; |
3115 | default: | 3279 | default: |
3116 | break; | 3280 | break; |
@@ -3158,12 +3322,6 @@ static int __init qlcnic_init_module(void) | |||
3158 | 3322 | ||
3159 | printk(KERN_INFO "%s\n", qlcnic_driver_string); | 3323 | printk(KERN_INFO "%s\n", qlcnic_driver_string); |
3160 | 3324 | ||
3161 | qlcnic_wq = create_singlethread_workqueue("qlcnic"); | ||
3162 | if (qlcnic_wq == NULL) { | ||
3163 | printk(KERN_ERR "qlcnic: cannot create workqueue\n"); | ||
3164 | return -ENOMEM; | ||
3165 | } | ||
3166 | |||
3167 | #ifdef CONFIG_INET | 3325 | #ifdef CONFIG_INET |
3168 | register_netdevice_notifier(&qlcnic_netdev_cb); | 3326 | register_netdevice_notifier(&qlcnic_netdev_cb); |
3169 | register_inetaddr_notifier(&qlcnic_inetaddr_cb); | 3327 | register_inetaddr_notifier(&qlcnic_inetaddr_cb); |
@@ -3175,7 +3333,6 @@ static int __init qlcnic_init_module(void) | |||
3175 | unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); | 3333 | unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); |
3176 | unregister_netdevice_notifier(&qlcnic_netdev_cb); | 3334 | unregister_netdevice_notifier(&qlcnic_netdev_cb); |
3177 | #endif | 3335 | #endif |
3178 | destroy_workqueue(qlcnic_wq); | ||
3179 | } | 3336 | } |
3180 | 3337 | ||
3181 | return ret; | 3338 | return ret; |
@@ -3185,14 +3342,12 @@ module_init(qlcnic_init_module); | |||
3185 | 3342 | ||
3186 | static void __exit qlcnic_exit_module(void) | 3343 | static void __exit qlcnic_exit_module(void) |
3187 | { | 3344 | { |
3188 | |||
3189 | pci_unregister_driver(&qlcnic_driver); | 3345 | pci_unregister_driver(&qlcnic_driver); |
3190 | 3346 | ||
3191 | #ifdef CONFIG_INET | 3347 | #ifdef CONFIG_INET |
3192 | unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); | 3348 | unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); |
3193 | unregister_netdevice_notifier(&qlcnic_netdev_cb); | 3349 | unregister_netdevice_notifier(&qlcnic_netdev_cb); |
3194 | #endif | 3350 | #endif |
3195 | destroy_workqueue(qlcnic_wq); | ||
3196 | } | 3351 | } |
3197 | 3352 | ||
3198 | module_exit(qlcnic_exit_module); | 3353 | module_exit(qlcnic_exit_module); |