diff options
author | Manish Chopra <manish.chopra@qlogic.com> | 2013-05-30 05:51:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-05-30 19:52:37 -0400 |
commit | b37eb210c076b0465fcb8d14694fcce3f267ac63 (patch) | |
tree | 084e013056cbf6d51b35b4e9ec2d350ff52515d3 /drivers/net | |
parent | a120e864676548454f8d061e7d8a2e68c908a794 (diff) |
netxen_nic: Avoid mixed mode interrupts
o Adapters do not support co-existence of INTx Interrupt with
MSI-X or MSI among multiple functions. Prevent attaching
of a function during normal load, if adapter gets into mixed
mode of interrupts
Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 50 |
2 files changed, 46 insertions, 7 deletions
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h index 28e076960bcb..32c790659f9c 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h | |||
@@ -734,6 +734,9 @@ enum { | |||
734 | #define NIC_CRB_BASE_2 (NETXEN_CAM_RAM(0x700)) | 734 | #define NIC_CRB_BASE_2 (NETXEN_CAM_RAM(0x700)) |
735 | #define NETXEN_NIC_REG(X) (NIC_CRB_BASE+(X)) | 735 | #define NETXEN_NIC_REG(X) (NIC_CRB_BASE+(X)) |
736 | #define NETXEN_NIC_REG_2(X) (NIC_CRB_BASE_2+(X)) | 736 | #define NETXEN_NIC_REG_2(X) (NIC_CRB_BASE_2+(X)) |
737 | #define NETXEN_INTR_MODE_REG NETXEN_NIC_REG(0x44) | ||
738 | #define NETXEN_MSI_MODE 0x1 | ||
739 | #define NETXEN_INTX_MODE 0x2 | ||
737 | 740 | ||
738 | #define NX_CDRP_CRB_OFFSET (NETXEN_NIC_REG(0x18)) | 741 | #define NX_CDRP_CRB_OFFSET (NETXEN_NIC_REG(0x18)) |
739 | #define NX_ARG1_CRB_OFFSET (NETXEN_NIC_REG(0x1c)) | 742 | #define NX_ARG1_CRB_OFFSET (NETXEN_NIC_REG(0x1c)) |
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 927ae9f801fb..20c7b3c12b56 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | |||
@@ -592,6 +592,22 @@ static const struct net_device_ops netxen_netdev_ops = { | |||
592 | #endif | 592 | #endif |
593 | }; | 593 | }; |
594 | 594 | ||
595 | static inline bool netxen_function_zero(struct pci_dev *pdev) | ||
596 | { | ||
597 | return (PCI_FUNC(pdev->devfn) == 0) ? true : false; | ||
598 | } | ||
599 | |||
600 | static inline void netxen_set_interrupt_mode(struct netxen_adapter *adapter, | ||
601 | u32 mode) | ||
602 | { | ||
603 | NXWR32(adapter, NETXEN_INTR_MODE_REG, mode); | ||
604 | } | ||
605 | |||
606 | static inline u32 netxen_get_interrupt_mode(struct netxen_adapter *adapter) | ||
607 | { | ||
608 | return NXRD32(adapter, NETXEN_INTR_MODE_REG); | ||
609 | } | ||
610 | |||
595 | static void | 611 | static void |
596 | netxen_initialize_interrupt_registers(struct netxen_adapter *adapter) | 612 | netxen_initialize_interrupt_registers(struct netxen_adapter *adapter) |
597 | { | 613 | { |
@@ -654,10 +670,11 @@ static int netxen_setup_msi_interrupts(struct netxen_adapter *adapter, | |||
654 | return 0; | 670 | return 0; |
655 | } | 671 | } |
656 | 672 | ||
673 | dev_err(&pdev->dev, "Failed to acquire MSI-X/MSI interrupt vector\n"); | ||
657 | return -EIO; | 674 | return -EIO; |
658 | } | 675 | } |
659 | 676 | ||
660 | static void netxen_setup_intr(struct netxen_adapter *adapter) | 677 | static int netxen_setup_intr(struct netxen_adapter *adapter) |
661 | { | 678 | { |
662 | struct pci_dev *pdev = adapter->pdev; | 679 | struct pci_dev *pdev = adapter->pdev; |
663 | int num_msix; | 680 | int num_msix; |
@@ -674,11 +691,24 @@ static void netxen_setup_intr(struct netxen_adapter *adapter) | |||
674 | netxen_initialize_interrupt_registers(adapter); | 691 | netxen_initialize_interrupt_registers(adapter); |
675 | netxen_set_msix_bit(pdev, 0); | 692 | netxen_set_msix_bit(pdev, 0); |
676 | 693 | ||
677 | if (!netxen_setup_msi_interrupts(adapter, num_msix)) | 694 | if (netxen_function_zero(pdev)) { |
678 | return; | 695 | if (!netxen_setup_msi_interrupts(adapter, num_msix)) |
696 | netxen_set_interrupt_mode(adapter, NETXEN_MSI_MODE); | ||
697 | else | ||
698 | netxen_set_interrupt_mode(adapter, NETXEN_INTX_MODE); | ||
699 | } else { | ||
700 | if (netxen_get_interrupt_mode(adapter) == NETXEN_MSI_MODE && | ||
701 | netxen_setup_msi_interrupts(adapter, num_msix)) { | ||
702 | dev_err(&pdev->dev, "Co-existence of MSI-X/MSI and INTx interrupts is not supported\n"); | ||
703 | return -EIO; | ||
704 | } | ||
705 | } | ||
679 | 706 | ||
680 | adapter->msix_entries[0].vector = pdev->irq; | 707 | if (!NETXEN_IS_MSI_FAMILY(adapter)) { |
681 | dev_info(&pdev->dev, "using legacy interrupts\n"); | 708 | adapter->msix_entries[0].vector = pdev->irq; |
709 | dev_info(&pdev->dev, "using legacy interrupts\n"); | ||
710 | } | ||
711 | return 0; | ||
682 | } | 712 | } |
683 | 713 | ||
684 | static void | 714 | static void |
@@ -1525,7 +1555,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1525 | 1555 | ||
1526 | netxen_nic_clear_stats(adapter); | 1556 | netxen_nic_clear_stats(adapter); |
1527 | 1557 | ||
1528 | netxen_setup_intr(adapter); | 1558 | err = netxen_setup_intr(adapter); |
1559 | |||
1560 | if (err) { | ||
1561 | dev_err(&adapter->pdev->dev, | ||
1562 | "Failed to setup interrupts, error = %d\n", err); | ||
1563 | goto err_out_disable_msi; | ||
1564 | } | ||
1529 | 1565 | ||
1530 | err = netxen_setup_netdev(adapter, netdev); | 1566 | err = netxen_setup_netdev(adapter, netdev); |
1531 | if (err) | 1567 | if (err) |
@@ -1613,7 +1649,7 @@ static void netxen_nic_remove(struct pci_dev *pdev) | |||
1613 | clear_bit(__NX_RESETTING, &adapter->state); | 1649 | clear_bit(__NX_RESETTING, &adapter->state); |
1614 | 1650 | ||
1615 | netxen_teardown_intr(adapter); | 1651 | netxen_teardown_intr(adapter); |
1616 | 1652 | netxen_set_interrupt_mode(adapter, 0); | |
1617 | netxen_remove_diag_entries(adapter); | 1653 | netxen_remove_diag_entries(adapter); |
1618 | 1654 | ||
1619 | netxen_cleanup_pci_map(adapter); | 1655 | netxen_cleanup_pci_map(adapter); |