diff options
author | Manish chopra <manish.chopra@qlogic.com> | 2013-01-25 05:20:37 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-27 01:00:08 -0500 |
commit | 9a97e7053a056679e33a4e23c98c5fbb6799e92a (patch) | |
tree | 17632ecc1b7250bc6773aff74b51741740c0a8c2 /drivers/net/ethernet/qlogic | |
parent | efbcb1b20a08a8dd6faefbc04a63330703bc6b5e (diff) |
qlcnic: avoid mixed mode interrupts for some adapter types
o Some adapter types do not support co-existence of Legacy Interrupt with
MSI-x or MSI among multiple functions. For those adapters, prevent attaching
to a function during normal load, if MSI-x or MSI vectors are not available.
o Using module parameters use_msi=0 and use_msi_x=0, driver can be loaded in
legacy mode for all functions in the adapter.
Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index e460401667df..5cbf8c64e0f3 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -395,8 +395,9 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) | |||
395 | return err; | 395 | return err; |
396 | } | 396 | } |
397 | 397 | ||
398 | static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) | 398 | static int qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) |
399 | { | 399 | { |
400 | int err = 0; | ||
400 | u32 offset, mask_reg; | 401 | u32 offset, mask_reg; |
401 | const struct qlcnic_legacy_intr_set *legacy_intrp; | 402 | const struct qlcnic_legacy_intr_set *legacy_intrp; |
402 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 403 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
@@ -409,8 +410,10 @@ static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) | |||
409 | offset); | 410 | offset); |
410 | dev_info(&pdev->dev, "using msi interrupts\n"); | 411 | dev_info(&pdev->dev, "using msi interrupts\n"); |
411 | adapter->msix_entries[0].vector = pdev->irq; | 412 | adapter->msix_entries[0].vector = pdev->irq; |
412 | return; | 413 | return err; |
413 | } | 414 | } |
415 | if (qlcnic_use_msi || qlcnic_use_msi_x) | ||
416 | return -EOPNOTSUPP; | ||
414 | 417 | ||
415 | legacy_intrp = &legacy_intr[adapter->ahw->pci_func]; | 418 | legacy_intrp = &legacy_intr[adapter->ahw->pci_func]; |
416 | adapter->ahw->int_vec_bit = legacy_intrp->int_vec_bit; | 419 | adapter->ahw->int_vec_bit = legacy_intrp->int_vec_bit; |
@@ -422,11 +425,12 @@ static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) | |||
422 | adapter->crb_int_state_reg = qlcnic_get_ioaddr(ahw, ISR_INT_STATE_REG); | 425 | adapter->crb_int_state_reg = qlcnic_get_ioaddr(ahw, ISR_INT_STATE_REG); |
423 | dev_info(&pdev->dev, "using legacy interrupts\n"); | 426 | dev_info(&pdev->dev, "using legacy interrupts\n"); |
424 | adapter->msix_entries[0].vector = pdev->irq; | 427 | adapter->msix_entries[0].vector = pdev->irq; |
428 | return err; | ||
425 | } | 429 | } |
426 | 430 | ||
427 | int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr) | 431 | int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr) |
428 | { | 432 | { |
429 | int num_msix, err; | 433 | int num_msix, err = 0; |
430 | 434 | ||
431 | if (!num_intr) | 435 | if (!num_intr) |
432 | num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS; | 436 | num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS; |
@@ -441,8 +445,11 @@ int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr) | |||
441 | if (err == -ENOMEM || !err) | 445 | if (err == -ENOMEM || !err) |
442 | return err; | 446 | return err; |
443 | 447 | ||
444 | qlcnic_enable_msi_legacy(adapter); | 448 | err = qlcnic_enable_msi_legacy(adapter); |
445 | return 0; | 449 | if (!err) |
450 | return err; | ||
451 | |||
452 | return -EIO; | ||
446 | } | 453 | } |
447 | 454 | ||
448 | void qlcnic_teardown_intr(struct qlcnic_adapter *adapter) | 455 | void qlcnic_teardown_intr(struct qlcnic_adapter *adapter) |
@@ -1843,8 +1850,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1843 | board_name, adapter->ahw->revision_id); | 1850 | board_name, adapter->ahw->revision_id); |
1844 | } | 1851 | } |
1845 | err = qlcnic_setup_intr(adapter, 0); | 1852 | err = qlcnic_setup_intr(adapter, 0); |
1846 | if (err) | 1853 | if (err) { |
1854 | dev_err(&pdev->dev, "Failed to setup interrupt\n"); | ||
1847 | goto err_out_disable_msi; | 1855 | goto err_out_disable_msi; |
1856 | } | ||
1848 | 1857 | ||
1849 | if (qlcnic_83xx_check(adapter)) { | 1858 | if (qlcnic_83xx_check(adapter)) { |
1850 | err = qlcnic_83xx_setup_mbx_intr(adapter); | 1859 | err = qlcnic_83xx_setup_mbx_intr(adapter); |
@@ -2976,6 +2985,12 @@ static int qlcnic_attach_func(struct pci_dev *pdev) | |||
2976 | adapter->msix_entries = NULL; | 2985 | adapter->msix_entries = NULL; |
2977 | err = qlcnic_setup_intr(adapter, 0); | 2986 | err = qlcnic_setup_intr(adapter, 0); |
2978 | 2987 | ||
2988 | if (err) { | ||
2989 | kfree(adapter->msix_entries); | ||
2990 | netdev_err(netdev, "failed to setup interrupt\n"); | ||
2991 | return err; | ||
2992 | } | ||
2993 | |||
2979 | if (qlcnic_83xx_check(adapter)) { | 2994 | if (qlcnic_83xx_check(adapter)) { |
2980 | err = qlcnic_83xx_setup_mbx_intr(adapter); | 2995 | err = qlcnic_83xx_setup_mbx_intr(adapter); |
2981 | if (err) { | 2996 | if (err) { |
@@ -3131,9 +3146,11 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data, size_t len) | |||
3131 | qlcnic_detach(adapter); | 3146 | qlcnic_detach(adapter); |
3132 | qlcnic_teardown_intr(adapter); | 3147 | qlcnic_teardown_intr(adapter); |
3133 | err = qlcnic_setup_intr(adapter, data); | 3148 | err = qlcnic_setup_intr(adapter, data); |
3134 | if (err) | 3149 | if (err) { |
3135 | dev_err(&adapter->pdev->dev, | 3150 | kfree(adapter->msix_entries); |
3136 | "failed setting max_rss; rss disabled\n"); | 3151 | netdev_err(netdev, "failed to setup interrupt\n"); |
3152 | return err; | ||
3153 | } | ||
3137 | 3154 | ||
3138 | if (qlcnic_83xx_check(adapter)) { | 3155 | if (qlcnic_83xx_check(adapter)) { |
3139 | err = qlcnic_83xx_setup_mbx_intr(adapter); | 3156 | err = qlcnic_83xx_setup_mbx_intr(adapter); |