aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic
diff options
context:
space:
mode:
authorManish chopra <manish.chopra@qlogic.com>2013-01-25 05:20:37 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-27 01:00:08 -0500
commit9a97e7053a056679e33a4e23c98c5fbb6799e92a (patch)
tree17632ecc1b7250bc6773aff74b51741740c0a8c2 /drivers/net/ethernet/qlogic
parentefbcb1b20a08a8dd6faefbc04a63330703bc6b5e (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.c35
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
398static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) 398static 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
427int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr) 431int 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
448void qlcnic_teardown_intr(struct qlcnic_adapter *adapter) 455void 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);