mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
efbcb1b20a
commit
9a97e7053a
|
@ -395,8 +395,9 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
|
static int qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
|
||||||
{
|
{
|
||||||
|
int err = 0;
|
||||||
u32 offset, mask_reg;
|
u32 offset, mask_reg;
|
||||||
const struct qlcnic_legacy_intr_set *legacy_intrp;
|
const struct qlcnic_legacy_intr_set *legacy_intrp;
|
||||||
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
struct qlcnic_hardware_context *ahw = adapter->ahw;
|
||||||
|
@ -409,8 +410,10 @@ static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
|
||||||
offset);
|
offset);
|
||||||
dev_info(&pdev->dev, "using msi interrupts\n");
|
dev_info(&pdev->dev, "using msi interrupts\n");
|
||||||
adapter->msix_entries[0].vector = pdev->irq;
|
adapter->msix_entries[0].vector = pdev->irq;
|
||||||
return;
|
return err;
|
||||||
}
|
}
|
||||||
|
if (qlcnic_use_msi || qlcnic_use_msi_x)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
legacy_intrp = &legacy_intr[adapter->ahw->pci_func];
|
legacy_intrp = &legacy_intr[adapter->ahw->pci_func];
|
||||||
adapter->ahw->int_vec_bit = legacy_intrp->int_vec_bit;
|
adapter->ahw->int_vec_bit = legacy_intrp->int_vec_bit;
|
||||||
|
@ -422,11 +425,12 @@ static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
|
||||||
adapter->crb_int_state_reg = qlcnic_get_ioaddr(ahw, ISR_INT_STATE_REG);
|
adapter->crb_int_state_reg = qlcnic_get_ioaddr(ahw, ISR_INT_STATE_REG);
|
||||||
dev_info(&pdev->dev, "using legacy interrupts\n");
|
dev_info(&pdev->dev, "using legacy interrupts\n");
|
||||||
adapter->msix_entries[0].vector = pdev->irq;
|
adapter->msix_entries[0].vector = pdev->irq;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr)
|
int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr)
|
||||||
{
|
{
|
||||||
int num_msix, err;
|
int num_msix, err = 0;
|
||||||
|
|
||||||
if (!num_intr)
|
if (!num_intr)
|
||||||
num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS;
|
num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS;
|
||||||
|
@ -441,8 +445,11 @@ int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr)
|
||||||
if (err == -ENOMEM || !err)
|
if (err == -ENOMEM || !err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
qlcnic_enable_msi_legacy(adapter);
|
err = qlcnic_enable_msi_legacy(adapter);
|
||||||
return 0;
|
if (!err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qlcnic_teardown_intr(struct qlcnic_adapter *adapter)
|
void qlcnic_teardown_intr(struct qlcnic_adapter *adapter)
|
||||||
|
@ -1843,8 +1850,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
board_name, adapter->ahw->revision_id);
|
board_name, adapter->ahw->revision_id);
|
||||||
}
|
}
|
||||||
err = qlcnic_setup_intr(adapter, 0);
|
err = qlcnic_setup_intr(adapter, 0);
|
||||||
if (err)
|
if (err) {
|
||||||
|
dev_err(&pdev->dev, "Failed to setup interrupt\n");
|
||||||
goto err_out_disable_msi;
|
goto err_out_disable_msi;
|
||||||
|
}
|
||||||
|
|
||||||
if (qlcnic_83xx_check(adapter)) {
|
if (qlcnic_83xx_check(adapter)) {
|
||||||
err = qlcnic_83xx_setup_mbx_intr(adapter);
|
err = qlcnic_83xx_setup_mbx_intr(adapter);
|
||||||
|
@ -2976,6 +2985,12 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
|
||||||
adapter->msix_entries = NULL;
|
adapter->msix_entries = NULL;
|
||||||
err = qlcnic_setup_intr(adapter, 0);
|
err = qlcnic_setup_intr(adapter, 0);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
kfree(adapter->msix_entries);
|
||||||
|
netdev_err(netdev, "failed to setup interrupt\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (qlcnic_83xx_check(adapter)) {
|
if (qlcnic_83xx_check(adapter)) {
|
||||||
err = qlcnic_83xx_setup_mbx_intr(adapter);
|
err = qlcnic_83xx_setup_mbx_intr(adapter);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -3131,9 +3146,11 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data, size_t len)
|
||||||
qlcnic_detach(adapter);
|
qlcnic_detach(adapter);
|
||||||
qlcnic_teardown_intr(adapter);
|
qlcnic_teardown_intr(adapter);
|
||||||
err = qlcnic_setup_intr(adapter, data);
|
err = qlcnic_setup_intr(adapter, data);
|
||||||
if (err)
|
if (err) {
|
||||||
dev_err(&adapter->pdev->dev,
|
kfree(adapter->msix_entries);
|
||||||
"failed setting max_rss; rss disabled\n");
|
netdev_err(netdev, "failed to setup interrupt\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (qlcnic_83xx_check(adapter)) {
|
if (qlcnic_83xx_check(adapter)) {
|
||||||
err = qlcnic_83xx_setup_mbx_intr(adapter);
|
err = qlcnic_83xx_setup_mbx_intr(adapter);
|
||||||
|
|
Loading…
Reference in New Issue